1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast: ParExpr, OrExpr, IfGuardExpr; ForInStmt fix; remove all cap vars

This commit is contained in:
Alexander Medvednikov 2020-02-28 15:36:41 +01:00
parent 6a198df3af
commit ccf4f61521
5 changed files with 76 additions and 44 deletions

1
.github/FUNDING.yml vendored
View File

@ -1,3 +1,4 @@
# These are supported funding model platforms # These are supported funding model platforms
patreon: vlang patreon: vlang
github: [medvednikov]

View File

@ -2014,21 +2014,21 @@ fn (p mut Parser) var_expr(v Var) string {
mut typ := v.typ mut typ := v.typ
// Function pointer? // Function pointer?
if p.base_type(typ).starts_with('fn ') && p.tok == .lpar { if p.base_type(typ).starts_with('fn ') && p.tok == .lpar {
T := p.table.find_type(p.base_type(typ)) tt := p.table.find_type(p.base_type(typ))
p.gen('(') p.gen('(')
p.fn_call_args(mut T.func, []) p.fn_call_args(mut tt.func, [])
p.gen(')') p.gen(')')
typ = T.func.typ typ = tt.func.typ
} }
// users[0].name // users[0].name
if p.tok == .lsbr { if p.tok == .lsbr {
typ = p.index_expr(typ, fn_ph) typ = p.index_expr(typ, fn_ph)
if p.base_type(typ).starts_with('fn ') && p.tok == .lpar { if p.base_type(typ).starts_with('fn ') && p.tok == .lpar {
T := p.table.find_type(p.base_type(typ)) tt := p.table.find_type(p.base_type(typ))
p.gen('(') p.gen('(')
p.fn_call_args(mut T.func, []) p.fn_call_args(mut tt.func, [])
p.gen(')') p.gen(')')
typ = T.func.typ typ = tt.func.typ
} }
} }
// a.b.c().d chain // a.b.c().d chain
@ -2364,10 +2364,10 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
// [2.. // [2..
if p.tok != .dotdot { if p.tok != .dotdot {
index_pos := p.cgen.cur_line.len index_pos := p.cgen.cur_line.len
T := p.table.find_type(p.expression()) tt := p.table.find_type(p.expression())
// Allows only i8-64 and byte-64 to be used when accessing an array // Allows only i8-64 and byte-64 to be used when accessing an array
if T.parent != 'int' && T.parent != 'u32' { if tt.parent != 'int' && tt.parent != 'u32' {
p.check_types(T.name, 'int') p.check_types(tt.name, 'int')
} }
if p.cgen.cur_line[index_pos..].replace(' ', '').int() < 0 { if p.cgen.cur_line[index_pos..].replace(' ', '').int() < 0 {
p.error('cannot access negative array index') p.error('cannot access negative array index')
@ -2402,10 +2402,10 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
} }
} }
else { else {
T := p.table.find_type(p.expression()) tt := p.table.find_type(p.expression())
// TODO: Get the key type of the map instead of only string. // TODO: Get the key type of the map instead of only string.
if is_map && T.parent != 'string' { if is_map && tt.parent != 'string' {
p.check_types(T.name, 'string') p.check_types(tt.name, 'string')
} }
} }
p.check(.rsbr) p.check(.rsbr)
@ -3065,14 +3065,14 @@ fn (p mut Parser) js_decode() string {
cjson_tmp := p.get_tmp() cjson_tmp := p.get_tmp()
mut decl := '$typ $tmp; ' mut decl := '$typ $tmp; '
// Init the struct // Init the struct
T := p.table.find_type(typ) tt := p.table.find_type(typ)
for field in T.fields { for field in tt.fields {
def_val := type_default(field.typ) def_val := type_default(field.typ)
if def_val != '' { if def_val != '' {
decl += '${tmp}.$field.name = OPTION_CAST($field.typ) $def_val;\n' decl += '${tmp}.$field.name = OPTION_CAST($field.typ) $def_val;\n'
} }
} }
p.gen_json_for_type(T) p.gen_json_for_type(tt)
decl += 'cJSON* $cjson_tmp = json__json_parse($expr);' decl += 'cJSON* $cjson_tmp = json__json_parse($expr);'
p.cgen.insert_before(decl) p.cgen.insert_before(decl)
// p.gen('jsdecode_$typ(json_parse($expr), &$tmp);') // p.gen('jsdecode_$typ(json_parse($expr), &$tmp);')
@ -3085,8 +3085,8 @@ fn (p mut Parser) js_decode() string {
else if op == 'encode' { else if op == 'encode' {
p.check(.lpar) p.check(.lpar)
typ,expr := p.tmp_expr() typ,expr := p.tmp_expr()
T := p.table.find_type(typ) tt := p.table.find_type(typ)
p.gen_json_for_type(T) p.gen_json_for_type(tt)
p.check(.rpar) p.check(.rpar)
p.gen('json__json_print(json__jsencode_${typ}($expr))') p.gen('json__json_print(json__jsencode_${typ}($expr))')
return 'string' return 'string'

View File

@ -11,7 +11,7 @@ import (
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr |
CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | OrExpr | ParExpr CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
@ -159,11 +159,12 @@ mut:
pub struct MethodCallExpr { pub struct MethodCallExpr {
pub: pub:
// tok token.Token // tok token.Token
pos token.Position pos token.Position
expr Expr expr Expr
name string name string
args []Expr args []Expr
muts []bool muts []bool
or_block OrExpr
} }
pub struct Return { pub struct Return {
@ -355,11 +356,13 @@ pub:
pub struct ForInStmt { pub struct ForInStmt {
pub: pub:
key_var string key_var string
val_var string val_var string
cond Expr cond Expr
stmts []Stmt is_range bool
pos token.Position high Expr // `10` in `for i in 0..10 {`
stmts []Stmt
pos token.Position
} }
pub struct ForCStmt { pub struct ForCStmt {
@ -492,12 +495,21 @@ pub:
expr Expr expr Expr
} }
pub struct OrExpr { // `if [x := opt()] {`
pub struct IfGuardExpr {
pub: pub:
var_name string var_name string
expr Expr expr Expr
} }
// `or { ... }`
pub struct OrExpr {
pub:
stmts []Stmt
// var_name string
// expr Expr
}
pub struct Assoc { pub struct Assoc {
pub: pub:
name string name string

View File

@ -168,6 +168,10 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
} }
f.write(' in ') f.write(' in ')
f.expr(it.cond) f.expr(it.cond)
if it.is_range {
f.write(' .. ')
f.expr(it.high)
}
f.writeln(' {') f.writeln(' {')
f.stmts(it.stmts) f.stmts(it.stmts)
f.writeln('}') f.writeln('}')
@ -421,19 +425,24 @@ fn (f mut Fmt) expr(node ast.Expr) {
} }
} }
f.write(')') f.write(')')
if it.or_block.stmts.len > 0 {
f.writeln(' or {')
f.stmts(it.or_block.stmts)
f.write('}')
}
} }
ast.None { ast.None {
f.write('none') f.write('none')
} }
ast.OrExpr { ast.IfGuardExpr {
f.write(it.var_name + ' := ') f.write(it.var_name + ' := ')
f.expr(it.expr) f.expr(it.expr)
} }
ast.ParExpr{ ast.ParExpr {
f.write('(') f.write('(')
f.expr(it.expr) f.expr(it.expr)
f.write(')') f.write(')')
} }
ast.PostfixExpr { ast.PostfixExpr {
f.expr(it.expr) f.expr(it.expr)
f.write(it.op.str()) f.write(it.op.str())

View File

@ -57,7 +57,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt {
pref: &pref.Preferences{} pref: &pref.Preferences{}
scope: scope scope: scope
// scope: &ast.Scope{start_pos: 0, parent: 0} // scope: &ast.Scope{start_pos: 0, parent: 0}
} }
p.init_parse_fns() p.init_parse_fns()
p.read_first_token() p.read_first_token()
@ -329,7 +329,7 @@ pub fn (p mut Parser) stmt() ast.Stmt {
return ast.ExprStmt{ return ast.ExprStmt{
expr: expr expr: expr
// typ: typ // typ: typ
} }
} }
} }
@ -621,7 +621,7 @@ pub fn (p mut Parser) name_expr() ast.Expr {
p.expr_mod = '' p.expr_mod = ''
return ast.EnumVal{ return ast.EnumVal{
enum_name: enum_name // lp.prepend_mod(enum_name) enum_name: enum_name // lp.prepend_mod(enum_name)
val: val val: val
pos: p.tok.position() pos: p.tok.position()
} }
@ -887,9 +887,10 @@ fn (p mut Parser) dot_expr(left ast.Expr, left_type table.Type) ast.Expr {
if p.tok.kind == .lpar { if p.tok.kind == .lpar {
p.next() p.next()
args,muts := p.call_args() args,muts := p.call_args()
mut or_stmts := []ast.Stmt
if p.tok.kind == .key_orelse { if p.tok.kind == .key_orelse {
p.next() p.next()
p.parse_block() or_stmts = p.parse_block()
} }
mcall_expr := ast.MethodCallExpr{ mcall_expr := ast.MethodCallExpr{
expr: left expr: left
@ -897,6 +898,9 @@ fn (p mut Parser) dot_expr(left ast.Expr, left_type table.Type) ast.Expr {
args: args args: args
muts: muts muts: muts
pos: p.tok.position() pos: p.tok.position()
or_block: ast.OrExpr{
stmts: or_stmts
}
} }
mut node := ast.Expr{} mut node := ast.Expr{}
node = mcall_expr node = mcall_expr
@ -1064,9 +1068,13 @@ fn (p mut Parser) for_statement() ast.Stmt {
} }
// 0 .. 10 // 0 .. 10
// start := p.tok.lit.int() // start := p.tok.lit.int()
// TODO use RangeExpr
mut high_expr := ast.Expr{}
mut is_range := false
if p.tok.kind == .dotdot { if p.tok.kind == .dotdot {
is_range = true
p.check(.dotdot) p.check(.dotdot)
p.expr(0) high_expr,_ = p.expr(0)
} }
// p.table.register_var(table.Var{ // p.table.register_var(table.Var{
// name: var_name // name: var_name
@ -1085,6 +1093,8 @@ fn (p mut Parser) for_statement() ast.Stmt {
cond: cond cond: cond
key_var: var_name key_var: var_name
val_var: val_name val_var: val_name
high: high_expr
is_range: is_range
} }
} }
// `for cond {` // `for cond {`
@ -1119,7 +1129,7 @@ fn (p mut Parser) if_expr() ast.Expr {
name: var_name name: var_name
typ: typ typ: typ
}) })
cond = ast.OrExpr{ cond = ast.IfGuardExpr{
var_name: var_name var_name: var_name
expr: expr expr: expr
} }
@ -1168,11 +1178,11 @@ fn (p mut Parser) if_expr() ast.Expr {
stmts: stmts stmts: stmts
else_stmts: else_stmts else_stmts: else_stmts
// typ: typ // typ: typ
pos: pos pos: pos
has_else: has_else has_else: has_else
// left: left // left: left
} }
return node return node
} }
@ -1588,12 +1598,12 @@ fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt {
return ast.VarDecl{ return ast.VarDecl{
name: ident.name name: ident.name
// name2: name2 // name2: name2
expr: expr // p.expr(token.lowest_prec) expr: expr // p.expr(token.lowest_prec)
is_mut: info0.is_mut is_mut: info0.is_mut
// typ: typ // typ: typ
pos: p.tok.position() pos: p.tok.position()
} }
// return p.var_decl(ident[0], exprs[0]) // return p.var_decl(ident[0], exprs[0])
@ -1731,7 +1741,7 @@ fn (p mut Parser) match_expr() ast.Expr {
blocks: blocks blocks: blocks
match_exprs: match_exprs match_exprs: match_exprs
// typ: typ // typ: typ
cond: cond cond: cond
} }
return node return node