v: fix/gen multi return/assign + merge VarDecl & AssignStmt
parent
876b73f92c
commit
f7a93a69f6
|
@ -16,7 +16,7 @@ AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr |
|
||||||
CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr |
|
CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr |
|
||||||
ConcatExpr | Type | AsCast
|
ConcatExpr | Type | AsCast
|
||||||
|
|
||||||
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
|
pub type Stmt = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
|
||||||
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
|
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
|
||||||
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt |
|
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt |
|
||||||
LineComment | MultiLineComment | AssertStmt | UnsafeStmt
|
LineComment | MultiLineComment | AssertStmt | UnsafeStmt
|
||||||
|
@ -164,6 +164,7 @@ mut:
|
||||||
is_c bool
|
is_c bool
|
||||||
muts []bool
|
muts []bool
|
||||||
or_block OrExpr
|
or_block OrExpr
|
||||||
|
typ table.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MethodCallExpr {
|
pub struct MethodCallExpr {
|
||||||
|
@ -201,10 +202,9 @@ pub struct Stmt {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
pub struct VarDecl {
|
pub struct Var {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
name2 string // TODO
|
|
||||||
expr Expr
|
expr Expr
|
||||||
is_mut bool
|
is_mut bool
|
||||||
mut:
|
mut:
|
||||||
|
|
|
@ -10,7 +10,7 @@ mut:
|
||||||
start_pos int
|
start_pos int
|
||||||
end_pos int
|
end_pos int
|
||||||
// vars map[string]table.Var
|
// vars map[string]table.Var
|
||||||
vars map[string]VarDecl
|
vars map[string]Var
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_scope(parent &Scope, start_pos int) &Scope {
|
pub fn new_scope(parent &Scope, start_pos int) &Scope {
|
||||||
|
@ -20,7 +20,7 @@ pub fn new_scope(parent &Scope, start_pos int) &Scope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (s &Scope) find_scope_and_var(name string) ?(&Scope,VarDecl) {
|
pub fn (s &Scope) find_scope_and_var(name string) ?(&Scope,Var) {
|
||||||
if name in s.vars {
|
if name in s.vars {
|
||||||
return s,s.vars[name]
|
return s,s.vars[name]
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ pub fn (s &Scope) find_scope_and_var(name string) ?(&Scope,VarDecl) {
|
||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (s &Scope) find_var(name string) ?VarDecl {
|
pub fn (s &Scope) find_var(name string) ?Var {
|
||||||
if name in s.vars {
|
if name in s.vars {
|
||||||
return s.vars[name]
|
return s.vars[name]
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ pub fn (s &Scope) known_var(name string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (s mut Scope) register_var(var VarDecl) {
|
pub fn (s mut Scope) register_var(var Var) {
|
||||||
if x := s.find_var(var.name) {
|
if x := s.find_var(var.name) {
|
||||||
// println('existing var: $var.name')
|
// println('existing var: $var.name')
|
||||||
return
|
return
|
||||||
|
@ -59,7 +59,7 @@ pub fn (s mut Scope) register_var(var VarDecl) {
|
||||||
s.vars[var.name] = var
|
s.vars[var.name] = var
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (s mut Scope) override_var(var VarDecl) {
|
pub fn (s mut Scope) override_var(var Var) {
|
||||||
s.vars[var.name] = var
|
s.vars[var.name] = var
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,26 @@ pub fn (x Expr) str() string {
|
||||||
|
|
||||||
pub fn (node Stmt) str() string {
|
pub fn (node Stmt) str() string {
|
||||||
match node {
|
match node {
|
||||||
VarDecl {
|
AssignStmt {
|
||||||
return it.name + ' = ' + it.expr.str()
|
mut out := ''
|
||||||
|
for i,ident in it.left {
|
||||||
|
var_info := ident.var_info()
|
||||||
|
if var_info.is_mut {
|
||||||
|
out += 'mut '
|
||||||
|
}
|
||||||
|
out += ident.name
|
||||||
|
if i < it.left.len-1 {
|
||||||
|
out += ','
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out += ' $it.op.str() '
|
||||||
|
for i,val in it.right {
|
||||||
|
out += val.str()
|
||||||
|
if i < it.right.len-1 {
|
||||||
|
out += ','
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
ExprStmt {
|
ExprStmt {
|
||||||
return it.expr.str()
|
return it.expr.str()
|
||||||
|
|
|
@ -206,6 +206,7 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
|
||||||
if !found {
|
if !found {
|
||||||
c.error('unknown fn: $fn_name', call_expr.pos)
|
c.error('unknown fn: $fn_name', call_expr.pos)
|
||||||
}
|
}
|
||||||
|
call_expr.typ = f.return_type
|
||||||
if f.is_c || call_expr.is_c {
|
if f.is_c || call_expr.is_c {
|
||||||
for expr in call_expr.args {
|
for expr in call_expr.args {
|
||||||
c.expr(expr)
|
c.expr(expr)
|
||||||
|
@ -259,12 +260,13 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr)
|
||||||
mut scope := c.file.scope.innermost(method_call_expr.pos.pos) or {
|
mut scope := c.file.scope.innermost(method_call_expr.pos.pos) or {
|
||||||
c.file.scope
|
c.file.scope
|
||||||
}
|
}
|
||||||
scope.override_var(ast.VarDecl{
|
scope.override_var(ast.Var{
|
||||||
name: 'it'
|
name: 'it'
|
||||||
typ: array_info.elem_type
|
typ: array_info.elem_type
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if method := typ_sym.find_method(name) {
|
if method := typ_sym.find_method(name) {
|
||||||
|
method_call_expr.typ = method.return_type
|
||||||
for i, arg_expr in method_call_expr.args {
|
for i, arg_expr in method_call_expr.args {
|
||||||
c.expected_type = method.args[i].typ
|
c.expected_type = method.args[i].typ
|
||||||
c.expr(arg_expr)
|
c.expr(arg_expr)
|
||||||
|
@ -370,27 +372,70 @@ pub fn (c mut Checker) return_stmt(return_stmt ast.Return) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c mut Checker) assign_stmt(assign_stmt ast.AssignStmt) {
|
pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) {
|
||||||
// multi return
|
// multi return
|
||||||
if assign_stmt.left.len > assign_stmt.right.len {
|
if assign_stmt.left.len > assign_stmt.right.len {
|
||||||
right := c.expr(assign_stmt.right[0])
|
right := c.expr(assign_stmt.right[0])
|
||||||
right_sym := c.table.get_type_symbol(right)
|
right_sym := c.table.get_type_symbol(right)
|
||||||
info := right_sym.mr_info()
|
mr_info := right_sym.mr_info()
|
||||||
if right_sym.kind != .multi_return {
|
if right_sym.kind != .multi_return {
|
||||||
c.error('wrong number of vars', assign_stmt.pos)
|
c.error('wrong number of vars', assign_stmt.pos)
|
||||||
}
|
}
|
||||||
mut scope := c.file.scope.innermost(assign_stmt.pos.pos) or {
|
mut scope := c.file.scope.innermost(assign_stmt.pos.pos) or {
|
||||||
c.file.scope
|
c.file.scope
|
||||||
}
|
}
|
||||||
for i, ident in assign_stmt.left {
|
for i, _ in assign_stmt.left {
|
||||||
// TODO: check types
|
mut ident := assign_stmt.left[i]
|
||||||
scope.override_var(ast.VarDecl{
|
mut var_info := ident.var_info()
|
||||||
|
val_type := mr_info.types[i]
|
||||||
|
var_info.typ = val_type
|
||||||
|
ident.info = var_info
|
||||||
|
assign_stmt.left[i] = ident
|
||||||
|
if assign_stmt.op == .assign {
|
||||||
|
if !c.table.check(val_type, var_info.typ) {
|
||||||
|
val_type_sym := c.table.get_type_symbol(val_type)
|
||||||
|
var_type_sym := c.table.get_type_symbol(var_info.typ)
|
||||||
|
c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`', assign_stmt.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scope.override_var(ast.Var{
|
||||||
name: ident.name
|
name: ident.name
|
||||||
typ: info.types[i]
|
typ: mr_info.types[i]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// `a := 1` | `a,b := 1,2`
|
||||||
|
else {
|
||||||
|
if assign_stmt.left.len != assign_stmt.right.len {
|
||||||
|
c.error('wrong number of vars', assign_stmt.pos)
|
||||||
|
}
|
||||||
|
for i, _ in assign_stmt.left {
|
||||||
|
mut ident := assign_stmt.left[i]
|
||||||
|
val := assign_stmt.right[i]
|
||||||
|
val_type := c.expr(val)
|
||||||
|
if assign_stmt.op == .assign {
|
||||||
|
var_info := ident.var_info()
|
||||||
|
if !c.table.check(val_type, var_info.typ) {
|
||||||
|
val_type_sym := c.table.get_type_symbol(val_type)
|
||||||
|
var_type_sym := c.table.get_type_symbol(var_info.typ)
|
||||||
|
c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`', assign_stmt.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if assign_stmt.op == .decl_assign {
|
||||||
|
mut var_info := ident.var_info()
|
||||||
|
var_info.typ = val_type
|
||||||
|
ident.info = var_info
|
||||||
|
assign_stmt.left[i] = ident
|
||||||
|
}
|
||||||
|
mut scope := c.file.scope.innermost(assign_stmt.pos.pos) or {
|
||||||
|
c.file.scope
|
||||||
|
}
|
||||||
|
scope.override_var(ast.Var{
|
||||||
|
name: ident.name
|
||||||
|
typ: val_type
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: multiple assign
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
|
pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
|
||||||
|
@ -448,7 +493,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
// c.expected_type = table.void_type
|
// c.expected_type = table.void_type
|
||||||
match mut node {
|
match mut node {
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
c.assign_stmt(it)
|
c.assign_stmt(mut it)
|
||||||
}
|
}
|
||||||
// ast.Attr {}
|
// ast.Attr {}
|
||||||
// ast.CompIf {}
|
// ast.CompIf {}
|
||||||
|
@ -507,10 +552,6 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
c.stmt(stmt)
|
c.stmt(stmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.VarDecl {
|
|
||||||
typ := c.expr(it.expr)
|
|
||||||
it.typ = typ
|
|
||||||
}
|
|
||||||
else {}
|
else {}
|
||||||
// println('checker.stmt(): unhandled node')
|
// println('checker.stmt(): unhandled node')
|
||||||
// println('checker.stmt(): unhandled node (${typeof(node)})')
|
// println('checker.stmt(): unhandled node (${typeof(node)})')
|
||||||
|
@ -646,7 +687,7 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
|
||||||
}
|
}
|
||||||
mut found := true
|
mut found := true
|
||||||
mut var_scope := &ast.Scope(0)
|
mut var_scope := &ast.Scope(0)
|
||||||
mut var := ast.VarDecl{}
|
mut var := ast.Var{}
|
||||||
var_scope,var = start_scope.find_scope_and_var(ident.name) or {
|
var_scope,var = start_scope.find_scope_and_var(ident.name) or {
|
||||||
found = false
|
found = false
|
||||||
c.error('not found: $ident.name - POS: $ident.pos.pos', ident.pos)
|
c.error('not found: $ident.name - POS: $ident.pos.pos', ident.pos)
|
||||||
|
|
|
@ -66,11 +66,14 @@ fn (e mut Eval) stmt(node ast.Stmt) string {
|
||||||
// ast.StructDecl {
|
// ast.StructDecl {
|
||||||
// println('s decl')
|
// println('s decl')
|
||||||
// }
|
// }
|
||||||
ast.VarDecl {
|
ast.AssignStmt {
|
||||||
e.vars[it.name] = Var{
|
// TODO; replaced VarDecl
|
||||||
value: e.expr(it.expr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// ast.VarDecl {
|
||||||
|
// e.vars[it.name] = Var{
|
||||||
|
// value: e.expr(it.expr)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
return '>>'
|
return '>>'
|
||||||
|
|
|
@ -100,18 +100,22 @@ fn (f mut Fmt) stmts(stmts []ast.Stmt) {
|
||||||
fn (f mut Fmt) stmt(node ast.Stmt) {
|
fn (f mut Fmt) stmt(node ast.Stmt) {
|
||||||
match node {
|
match node {
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
for i, left in it.left {
|
for i,ident in it.left {
|
||||||
if left.var_info().is_mut {
|
var_info := ident.var_info()
|
||||||
|
if var_info.is_mut {
|
||||||
f.write('mut ')
|
f.write('mut ')
|
||||||
}
|
}
|
||||||
f.expr(left)
|
f.write(ident.name)
|
||||||
if i < it.left.len - 1 {
|
if i < it.left.len-1 {
|
||||||
f.write(', ')
|
f.write(', ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.write(' $it.op.str() ')
|
f.write(' $it.op.str() ')
|
||||||
for right in it.right {
|
for i,val in it.right {
|
||||||
f.expr(right)
|
f.expr(val)
|
||||||
|
if i < it.right.len-1 {
|
||||||
|
f.write(', ')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
f.writeln('')
|
f.writeln('')
|
||||||
}
|
}
|
||||||
|
@ -231,20 +235,6 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
|
||||||
f.stmts(it.stmts)
|
f.stmts(it.stmts)
|
||||||
f.writeln('}')
|
f.writeln('}')
|
||||||
}
|
}
|
||||||
ast.VarDecl {
|
|
||||||
// type_sym := f.table.get_type_symbol(it.typ)
|
|
||||||
if it.is_mut {
|
|
||||||
f.write('mut ')
|
|
||||||
}
|
|
||||||
if it.name2 == '' {
|
|
||||||
f.write('$it.name := ')
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
f.write('/*2*/$it.name, $it.name2 := ')
|
|
||||||
}
|
|
||||||
f.expr(it.expr)
|
|
||||||
f.writeln('')
|
|
||||||
}
|
|
||||||
ast.Import {
|
ast.Import {
|
||||||
// already handled in f.imports
|
// already handled in f.imports
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,22 +135,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
// g.writeln('//// stmt start')
|
// g.writeln('//// stmt start')
|
||||||
match node {
|
match node {
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
// ident0 := it.left[0]
|
g.gen_assign_stmt(it)
|
||||||
// info0 := ident0.var_info()
|
|
||||||
// for i, ident in it.left {
|
|
||||||
// info := ident.var_info()
|
|
||||||
// if info0.typ.typ.kind == .multi_return {
|
|
||||||
// if i == 0 {
|
|
||||||
// g.write('$info.typ.typ.name $ident.name = ')
|
|
||||||
// g.expr(it.right[0])
|
|
||||||
// } else {
|
|
||||||
// arg_no := i-1
|
|
||||||
// g.write('$info.typ.typ.name $ident.name = $ident0.name->arg[$arg_no]')
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// g.writeln(';')
|
|
||||||
// }
|
|
||||||
g.write('') // /*assign*/')
|
|
||||||
}
|
}
|
||||||
ast.AssertStmt {
|
ast.AssertStmt {
|
||||||
g.write('// assert')
|
g.write('// assert')
|
||||||
|
@ -283,18 +268,51 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
ast.UnsafeStmt {
|
ast.UnsafeStmt {
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
}
|
}
|
||||||
ast.VarDecl {
|
|
||||||
styp := g.typ(it.typ)
|
|
||||||
g.write('$styp $it.name = ')
|
|
||||||
g.expr(it.expr)
|
|
||||||
g.writeln(';')
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
verror('cgen.stmt(): unhandled node ' + typeof(node))
|
verror('cgen.stmt(): unhandled node ' + typeof(node))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
|
// multi return
|
||||||
|
if assign_stmt.left.len > assign_stmt.right.len {
|
||||||
|
mut return_type := table.void_type
|
||||||
|
match assign_stmt.right[0] {
|
||||||
|
ast.CallExpr {
|
||||||
|
return_type = it.typ
|
||||||
|
}
|
||||||
|
ast.MethodCallExpr {
|
||||||
|
return_type = it.typ
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
panic('expected call')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mr_typ_sym := g.table.get_type_symbol(return_type)
|
||||||
|
mr_var_name := 'mr_$assign_stmt.pos.pos'
|
||||||
|
g.write('$mr_typ_sym.name $mr_var_name = ')
|
||||||
|
g.expr(assign_stmt.right[0])
|
||||||
|
g.writeln(';')
|
||||||
|
for i, ident in assign_stmt.left {
|
||||||
|
ident_var_info := ident.var_info()
|
||||||
|
var_type_sym := g.table.get_type_symbol(ident_var_info.typ)
|
||||||
|
g.writeln('$var_type_sym.name $ident.name = $mr_var_name->arg[$i];')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// `a := 1` | `a,b := 1,2`
|
||||||
|
else {
|
||||||
|
for i, ident in assign_stmt.left {
|
||||||
|
val := assign_stmt.right[i]
|
||||||
|
ident_var_info := ident.var_info()
|
||||||
|
var_type_sym := g.table.get_type_symbol(ident_var_info.typ)
|
||||||
|
g.write('$var_type_sym.name $ident.name = ')
|
||||||
|
g.expr(val)
|
||||||
|
g.writeln(';')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||||
if it.is_c || it.name == 'malloc' || it.no_body {
|
if it.is_c || it.name == 'malloc' || it.no_body {
|
||||||
return
|
return
|
||||||
|
|
|
@ -57,13 +57,21 @@ fn (g mut JsGen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
}
|
}
|
||||||
ast.AssignStmt {}
|
ast.AssignStmt {
|
||||||
ast.VarDecl {
|
if it.left.len > it.right.len {
|
||||||
type_sym := g.table.get_type_symbol(it.typ)
|
// TODO: multi return
|
||||||
g.write('var /* $type_sym.name */ $it.name = ')
|
}
|
||||||
g.expr(it.expr)
|
else {
|
||||||
|
for i,ident in it.left {
|
||||||
|
var_info := ident.var_info()
|
||||||
|
var_type_sym := g.table.get_type_symbol(var_info.typ)
|
||||||
|
val := it.right[i]
|
||||||
|
g.write('var /* $var_type_sym.name */ $ident.name = ')
|
||||||
|
g.expr(val)
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ast.ForStmt {
|
ast.ForStmt {
|
||||||
g.write('while (')
|
g.write('while (')
|
||||||
g.expr(it.cond)
|
g.expr(it.cond)
|
||||||
|
|
|
@ -54,6 +54,9 @@ int main() {
|
||||||
string foo_a = af_idx_el.a;
|
string foo_a = af_idx_el.a;
|
||||||
map_string_string m1 = new_map(1, sizeof(string));
|
map_string_string m1 = new_map(1, sizeof(string));
|
||||||
map_string_int m2 = new_map_init(2, sizeof(int), (string[2]){tos3("v"), tos3("lang"), }, (int[2]){1, 2, });
|
map_string_int m2 = new_map_init(2, sizeof(int), (string[2]){tos3("v"), tos3("lang"), }, (int[2]){1, 2, });
|
||||||
|
multi_return_int_string mr_548 = mr_test();
|
||||||
|
int mr1 = mr_548->arg[0];
|
||||||
|
string mr2 = mr_548->arg[1];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@ fn main() {
|
||||||
mut f := [testa(),2,3,4]
|
mut f := [testa(),2,3,4]
|
||||||
mut g := [testb(1),'hello']
|
mut g := [testb(1),'hello']
|
||||||
|
|
||||||
mr1, mr2 := mr_test()
|
|
||||||
|
|
||||||
//mut arr_foo := []Foo
|
//mut arr_foo := []Foo
|
||||||
arr_foo := [a]
|
arr_foo := [a]
|
||||||
//arr_foo << a // TODO
|
//arr_foo << a // TODO
|
||||||
|
@ -41,6 +39,8 @@ fn main() {
|
||||||
|
|
||||||
mut m1 := map[string]string
|
mut m1 := map[string]string
|
||||||
mut m2 := {'v': 1, 'lang': 2}
|
mut m2 := {'v': 1, 'lang': 2}
|
||||||
|
|
||||||
|
mr1, mr2 := mr_test()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mr_test() (int, string) {
|
fn mr_test() (int, string) {
|
||||||
|
|
|
@ -332,7 +332,6 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.Return {}
|
ast.Return {}
|
||||||
ast.AssignStmt {}
|
ast.AssignStmt {}
|
||||||
ast.VarDecl {}
|
|
||||||
ast.ForStmt {}
|
ast.ForStmt {}
|
||||||
ast.StructDecl {}
|
ast.StructDecl {}
|
||||||
ast.ExprStmt {
|
ast.ExprStmt {
|
||||||
|
|
|
@ -88,7 +88,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||||
// name: rec_name
|
// name: rec_name
|
||||||
// typ: rec_type
|
// typ: rec_type
|
||||||
// })
|
// })
|
||||||
p.scope.register_var(ast.VarDecl{
|
p.scope.register_var(ast.Var{
|
||||||
name: rec_name
|
name: rec_name
|
||||||
typ: rec_type
|
typ: rec_type
|
||||||
})
|
})
|
||||||
|
@ -115,7 +115,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||||
typ: ast_arg.typ
|
typ: ast_arg.typ
|
||||||
}
|
}
|
||||||
args << var
|
args << var
|
||||||
p.scope.register_var(ast.VarDecl{
|
p.scope.register_var(ast.Var{
|
||||||
name: ast_arg.name
|
name: ast_arg.name
|
||||||
typ: ast_arg.typ
|
typ: ast_arg.typ
|
||||||
})
|
})
|
||||||
|
|
|
@ -296,7 +296,7 @@ pub fn (p mut Parser) stmt() ast.Stmt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_mut {
|
.key_mut {
|
||||||
return p.var_decl_and_assign_stmt()
|
return p.assign_stmt()
|
||||||
}
|
}
|
||||||
.key_for {
|
.key_for {
|
||||||
return p.for_statement()
|
return p.for_statement()
|
||||||
|
@ -341,7 +341,7 @@ pub fn (p mut Parser) stmt() ast.Stmt {
|
||||||
else {
|
else {
|
||||||
// `x := ...`
|
// `x := ...`
|
||||||
if p.tok.kind == .name && p.peek_tok.kind in [.decl_assign, .comma] {
|
if p.tok.kind == .name && p.peek_tok.kind in [.decl_assign, .comma] {
|
||||||
return p.var_decl_and_assign_stmt()
|
return p.assign_stmt()
|
||||||
}
|
}
|
||||||
// `label:`
|
// `label:`
|
||||||
else if p.tok.kind == .name && p.peek_tok.kind == .colon {
|
else if p.tok.kind == .name && p.peek_tok.kind == .colon {
|
||||||
|
@ -870,7 +870,7 @@ fn (p mut Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) filter() {
|
fn (p mut Parser) filter() {
|
||||||
p.scope.register_var(ast.VarDecl{
|
p.scope.register_var(ast.Var{
|
||||||
name: 'it'
|
name: 'it'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -990,7 +990,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
||||||
// mut inc := ast.Stmt{}
|
// mut inc := ast.Stmt{}
|
||||||
mut inc := ast.Expr{}
|
mut inc := ast.Expr{}
|
||||||
if p.peek_tok.kind in [.assign, .decl_assign] {
|
if p.peek_tok.kind in [.assign, .decl_assign] {
|
||||||
init = p.var_decl_and_assign_stmt()
|
init = p.assign_stmt()
|
||||||
}
|
}
|
||||||
else if p.tok.kind != .semicolon {}
|
else if p.tok.kind != .semicolon {}
|
||||||
// allow `for ;; i++ {`
|
// allow `for ;; i++ {`
|
||||||
|
@ -1029,7 +1029,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
||||||
if p.tok.kind == .comma {
|
if p.tok.kind == .comma {
|
||||||
p.check(.comma)
|
p.check(.comma)
|
||||||
val_name = p.check_name()
|
val_name = p.check_name()
|
||||||
p.scope.register_var(ast.VarDecl{
|
p.scope.register_var(ast.Var{
|
||||||
name: val_name
|
name: val_name
|
||||||
typ: table.int_type
|
typ: table.int_type
|
||||||
})
|
})
|
||||||
|
@ -1048,7 +1048,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
||||||
high_expr = p.expr(0)
|
high_expr = p.expr(0)
|
||||||
}
|
}
|
||||||
// TODO: update var type in checker
|
// TODO: update var type in checker
|
||||||
p.scope.register_var(ast.VarDecl{
|
p.scope.register_var(ast.Var{
|
||||||
name: var_name
|
name: var_name
|
||||||
// expr: cond
|
// expr: cond
|
||||||
|
|
||||||
|
@ -1093,7 +1093,7 @@ fn (p mut Parser) if_expr() ast.Expr {
|
||||||
var_name := p.check_name()
|
var_name := p.check_name()
|
||||||
p.check(.decl_assign)
|
p.check(.decl_assign)
|
||||||
expr := p.expr(0)
|
expr := p.expr(0)
|
||||||
p.scope.register_var(ast.VarDecl{
|
p.scope.register_var(ast.Var{
|
||||||
name: var_name
|
name: var_name
|
||||||
expr: expr
|
expr: expr
|
||||||
})
|
})
|
||||||
|
@ -1508,50 +1508,22 @@ fn (p mut Parser) parse_assign_rhs() []ast.Expr {
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt {
|
fn (p mut Parser) assign_stmt() ast.Stmt {
|
||||||
idents := p.parse_assign_lhs()
|
idents := p.parse_assign_lhs()
|
||||||
op := p.tok.kind
|
op := p.tok.kind
|
||||||
p.next() // :=, =
|
p.next() // :=, =
|
||||||
exprs := p.parse_assign_rhs()
|
exprs := p.parse_assign_rhs()
|
||||||
is_decl := op == .decl_assign
|
is_decl := op == .decl_assign
|
||||||
// VarDecl
|
for ident in idents {
|
||||||
if idents.len == 1 {
|
|
||||||
ident := idents[0]
|
|
||||||
expr := exprs[0]
|
|
||||||
info0 := ident.var_info()
|
|
||||||
known_var := p.scope.known_var(ident.name)
|
known_var := p.scope.known_var(ident.name)
|
||||||
if !is_decl && !known_var {
|
if !is_decl && !known_var {
|
||||||
p.error('unknown variable `$ident.name`')
|
p.error('unknown variable `$ident.name`')
|
||||||
}
|
}
|
||||||
if is_decl && ident.kind != .blank_ident {
|
|
||||||
if known_var {
|
|
||||||
p.error('redefinition of `$ident.name`')
|
|
||||||
}
|
|
||||||
p.scope.register_var(ast.VarDecl{
|
|
||||||
name: ident.name
|
|
||||||
expr: expr
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return ast.VarDecl{
|
|
||||||
name: ident.name
|
|
||||||
// name2: name2
|
|
||||||
|
|
||||||
expr: expr // p.expr(token.lowest_prec)
|
|
||||||
|
|
||||||
is_mut: info0.is_mut
|
|
||||||
// typ: typ
|
|
||||||
|
|
||||||
pos: p.tok.position()
|
|
||||||
}
|
|
||||||
// return p.var_decl(ident[0], exprs[0])
|
|
||||||
}
|
|
||||||
// AssignStmt
|
|
||||||
for ident in idents {
|
|
||||||
if is_decl && ident.kind != .blank_ident {
|
if is_decl && ident.kind != .blank_ident {
|
||||||
if p.scope.known_var(ident.name) {
|
if p.scope.known_var(ident.name) {
|
||||||
p.error('redefinition of `$ident.name`')
|
p.error('redefinition of `$ident.name`')
|
||||||
}
|
}
|
||||||
p.scope.register_var(ast.VarDecl{
|
p.scope.register_var(ast.Var{
|
||||||
name: ident.name
|
name: ident.name
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1564,8 +1536,6 @@ fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn (p mut Parser) assign_stmt() ast.AssignStmt {}
|
|
||||||
// fn (p mut Parser) var_decl() ast.VarDecl {}
|
|
||||||
fn (p mut Parser) hash() ast.HashStmt {
|
fn (p mut Parser) hash() ast.HashStmt {
|
||||||
val := p.tok.lit
|
val := p.tok.lit
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -1633,7 +1603,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
|
||||||
exprs << ast.Type{
|
exprs << ast.Type{
|
||||||
typ: typ
|
typ: typ
|
||||||
}
|
}
|
||||||
p.scope.register_var(ast.VarDecl{
|
p.scope.register_var(ast.Var{
|
||||||
name: 'it'
|
name: 'it'
|
||||||
typ: typ
|
typ: typ
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue