v2: `if x := `; fix `for key, val in`; CastExpr

pull/3866/head
Alexander Medvednikov 2020-02-27 18:02:40 +01:00
parent 3bde876097
commit 4f0d505c65
3 changed files with 53 additions and 14 deletions

View File

@ -11,11 +11,11 @@ import (
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr |
CastExpr | EnumVal | Assoc | SizeOf | None | MapInit
CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | OrExpr
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt |
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt |
LineComment | MultiLineComment | AssertStmt | UnsafeStmt
pub type Type = StructType | ArrayType
@ -351,10 +351,11 @@ pub:
pub struct ForInStmt {
pub:
var string
cond Expr
stmts []Stmt
pos token.Position
key_var string
val_var string
cond Expr
stmts []Stmt
pos token.Position
}
pub struct ForCStmt {
@ -481,6 +482,12 @@ pub:
expr Expr
}
pub struct OrExpr {
pub:
var_name string
expr Expr
}
pub struct Assoc {
pub:
name string

View File

@ -159,7 +159,11 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
f.writeln('}\n')
}
ast.ForInStmt {
f.write('for $it.var in ')
f.write('for $it.key_var')
if it.val_var != '' {
f.write(', $it.val_var')
}
f.write(' in ')
f.expr(it.cond)
f.writeln(' {')
f.stmts(it.stmts)
@ -282,6 +286,11 @@ fn (f mut Fmt) expr(node ast.Expr) {
ast.BoolLiteral {
f.write(it.val.str())
}
ast.CastExpr {
f.write(f.table.type_to_str(it.typ) + '(')
f.expr(it.expr)
f.write(')')
}
ast.CallExpr {
f.write('${it.name}(')
for i, expr in it.args {
@ -387,6 +396,10 @@ fn (f mut Fmt) expr(node ast.Expr) {
ast.None {
f.write('none')
}
ast.OrExpr {
f.write(it.var_name + ' := ')
f.expr(it.expr)
}
ast.PostfixExpr {
f.expr(it.expr)
f.write(it.op.str())
@ -424,7 +437,9 @@ fn (f mut Fmt) expr(node ast.Expr) {
f.write('}')
}
}
else {}
else {
println('fmt expr: unhandled node ') // + typeof(node))
}
}
}

View File

@ -1035,9 +1035,10 @@ fn (p mut Parser) for_statement() ast.Stmt {
// `for i in vals`, `for i in start .. end`
else if p.peek_tok.kind in [.key_in, .comma] {
var_name := p.check_name()
mut val_name := ''
if p.tok.kind == .comma {
p.check(.comma)
val_name := p.check_name()
val_name = p.check_name()
// p.table.register_var(table.Var{
// name: val_name
// typ: table.int_type
@ -1092,7 +1093,8 @@ fn (p mut Parser) for_statement() ast.Stmt {
stmts: stmts
pos: p.tok.position()
cond: cond
var: var_name
key_var: var_name
val_var: val_name
}
}
// `for cond {`
@ -1115,10 +1117,22 @@ fn (p mut Parser) if_expr() ast.Expr {
pos := p.tok.position()
// `if x := opt() {`
mut cond := ast.Expr{}
mut is_or := false
if p.peek_tok.kind == .decl_assign {
p.next()
is_or = true
p.open_scope()
var_name := p.check_name()
// p.table.register_var(
p.check(.decl_assign)
p.expr(0)
expr,typ := p.expr(0)
p.scope.register_var(ast.VarDecl{
name: var_name
typ: typ
})
cond = ast.OrExpr{
var_name: var_name
expr: expr
}
}
else {
cond,_ = p.expr(0)
@ -1138,6 +1152,9 @@ fn (p mut Parser) if_expr() ast.Expr {
else_stmts = p.parse_block()
}
}
if is_or {
p.close_scope()
}
// mut typ := table.void_type
// mut left := ast.Expr{}
// If the last statement is an expression, return its type