v2: match expr; enum val; string formatting
							parent
							
								
									d51c159160
								
							
						
					
					
						commit
						26cfaa150e
					
				|  | @ -10,7 +10,8 @@ import ( | |||
| 
 | ||||
| pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | | ||||
| FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | | ||||
| AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr | ||||
| AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | | ||||
| CastExpr  | EnumVal | ||||
| 
 | ||||
| pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | | ||||
| ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | | ||||
|  | @ -366,6 +367,12 @@ pub: | |||
| 	name string | ||||
| } | ||||
| 
 | ||||
| pub struct EnumVal{ | ||||
| pub: | ||||
| 	name string | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| pub struct AssignExpr { | ||||
| pub: | ||||
| 	op   token.Kind | ||||
|  |  | |||
|  | @ -92,6 +92,13 @@ multi_return_int_string multi_return() { | |||
| 
 | ||||
| void variadic(variadic_int a) { | ||||
| 	int x = path_sep; | ||||
| 	int y = if (true) { | ||||
| 1; | ||||
| } | ||||
| else { | ||||
| 0; | ||||
| } | ||||
| ; | ||||
| } | ||||
| 
 | ||||
| void ensure_cap(int required, int cap) { | ||||
|  | @ -105,12 +112,12 @@ void println(string s) { | |||
| 
 | ||||
| void matches() { | ||||
| 	int a = 100; | ||||
| 	int tmp1 = a; | ||||
| 	if tmp1 == 10{ | ||||
| 	int tmp2 = a; | ||||
| 	if tmp2 == 10{ | ||||
| 		println(tos3("10")); | ||||
| 
 | ||||
| 	} | ||||
| 	if tmp1 == 20{ | ||||
| 	if tmp2 == 20{ | ||||
| 		int k = a + 1; | ||||
| 
 | ||||
| 	} | ||||
|  |  | |||
|  | @ -98,6 +98,7 @@ fn multi_return() (int,string) { | |||
| 
 | ||||
| fn variadic(a ...int) { | ||||
| 	x := path_sep | ||||
| 	y := if true { 1 } else { 0 } // TODO cgen
 | ||||
| } | ||||
| 
 | ||||
| fn ensure_cap(required int, cap int) { | ||||
|  | @ -118,6 +119,13 @@ fn matches() { | |||
| 			k := a + 1 | ||||
| 		} | ||||
| 	} | ||||
| 	/* | ||||
| 	n := match a { | ||||
| 		1 { 10 } | ||||
| 		2 { 20 } | ||||
| 		else { 30 } | ||||
| 	} | ||||
| 	*/ | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ pub fn (p mut Parser) call_expr() (ast.CallExpr,table.Type) { | |||
| 		name: fn_name | ||||
| 		args: args | ||||
| 		// tok: tok
 | ||||
| 		 | ||||
| 		pos: tok.position() | ||||
| 	} | ||||
| 	if p.tok.kind == .key_orelse { | ||||
|  | @ -121,7 +122,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | |||
| 				typ: arg_type | ||||
| 			} | ||||
| 			args << arg | ||||
| 			//p.table.register_var(arg)
 | ||||
| 			// p.table.register_var(arg)
 | ||||
| 			ast_args << ast.Arg{ | ||||
| 				name: arg_name | ||||
| 				typ: arg_type | ||||
|  | @ -156,7 +157,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | |||
| 					name: arg_name | ||||
| 					typ: typ | ||||
| 				} | ||||
| 				//if typ.typ.kind == .variadic && p.tok.kind == .comma {
 | ||||
| 				// if typ.typ.kind == .variadic && p.tok.kind == .comma {
 | ||||
| 				if is_variadic && p.tok.kind == .comma { | ||||
| 					p.error('cannot use ...(variadic) with non-final parameter $arg_name') | ||||
| 				} | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ mut: | |||
| 	mod               string | ||||
| 	unresolved        []ast.Expr | ||||
| 	unresolved_offset int | ||||
| 	expected_type     table.Type | ||||
| } | ||||
| 
 | ||||
| // for tests
 | ||||
|  | @ -471,7 +472,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) { | |||
| 	if p.peek_tok.kind == .lpar { | ||||
| 		name := p.tok.lit | ||||
| 		// type cast. TODO: finish
 | ||||
| 		//if name in table.builtin_type_names {
 | ||||
| 		// if name in table.builtin_type_names {
 | ||||
| 		if name in p.table.type_idxs { | ||||
| 			to_typ := p.parse_type() | ||||
| 			p.check(.lpar) | ||||
|  | @ -487,7 +488,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) { | |||
| 				typ: to_typ | ||||
| 				expr: expr | ||||
| 			} | ||||
| 			return node, to_typ | ||||
| 			return node,to_typ | ||||
| 		} | ||||
| 		// fn call
 | ||||
| 		else { | ||||
|  | @ -540,6 +541,10 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) { | |||
| 		.str { | ||||
| 			node,typ = p.string_expr() | ||||
| 		} | ||||
| 		.dot { | ||||
| 			// .enum_val
 | ||||
| 			node,typ = p.enum_val() | ||||
| 		} | ||||
| 		.chartoken { | ||||
| 			typ = table.byte_type | ||||
| 			node = ast.CharLiteral{ | ||||
|  | @ -562,7 +567,7 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) { | |||
| 			p.next() | ||||
| 		} | ||||
| 		.key_match { | ||||
| 			return p.match_expr() | ||||
| 			node,typ = p.match_expr() | ||||
| 		} | ||||
| 		.number { | ||||
| 			node,typ = p.parse_number_literal() | ||||
|  | @ -747,7 +752,16 @@ fn (p &Parser) is_addative() bool { | |||
| 	return p.tok.kind in [.plus, .minus] && p.peek_tok.kind in [.number, .name] | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| // `.green`
 | ||||
| fn (p mut Parser) enum_val() (ast.Expr,table.Type) { | ||||
| 	p.check(.dot) | ||||
| 	name := p.check_name() | ||||
| 	mut node := ast.Expr{} | ||||
| 	node = ast.EnumVal{ | ||||
| 		name: name | ||||
| 	} | ||||
| 	return node,table.bool_type | ||||
| } | ||||
| 
 | ||||
| fn (p mut Parser) for_statement() ast.Stmt { | ||||
| 	p.check(.key_for) | ||||
|  | @ -815,7 +829,8 @@ fn (p mut Parser) for_statement() ast.Stmt { | |||
| 		} | ||||
| 		p.check(.key_in) | ||||
| 		mut elem_type := table.void_type | ||||
| 		/*arr_expr*/_,arr_typ := p.expr(0) | ||||
| 		// arr_expr
 | ||||
| 		_,arr_typ := p.expr(0) | ||||
| 		// array / map
 | ||||
| 		arr_typ_sym := p.table.get_type_symbol(arr_typ) | ||||
| 		match arr_typ_sym.info { | ||||
|  | @ -826,10 +841,11 @@ fn (p mut Parser) for_statement() ast.Stmt { | |||
| 				elem_type = it.value_type | ||||
| 			} | ||||
| 			else { | ||||
| 				//elem_type_sym := p.table.get_type_symbol(elem_type)
 | ||||
| 				//p.error('cannot loop over type: $elem_type_sym.name')
 | ||||
| 				println(1) | ||||
| 				// elem_type_sym := p.table.get_type_symbol(elem_type)
 | ||||
| 				// p.error('cannot loop over type: $elem_type_sym.name')
 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 		// 0 .. 10
 | ||||
| 		// start := p.tok.lit.int()
 | ||||
| 		if p.tok.kind == .dotdot { | ||||
|  | @ -922,7 +938,7 @@ fn (p mut Parser) string_expr() (ast.Expr,table.Type) { | |||
| 		} | ||||
| 		p.check(.str_dollar) | ||||
| 		p.expr(0) | ||||
| 		if p.tok.kind == .semicolon { | ||||
| 		if p.tok.kind == .colon { | ||||
| 			p.next() | ||||
| 		} | ||||
| 	} | ||||
|  | @ -945,6 +961,7 @@ fn (p mut Parser) array_init() (ast.Expr,table.Type) { | |||
| 		// []
 | ||||
| 		else { | ||||
| 			// TODO ?
 | ||||
| 			println(0) | ||||
| 		} | ||||
| 	} | ||||
| 	else { | ||||
|  | @ -966,18 +983,15 @@ fn (p mut Parser) array_init() (ast.Expr,table.Type) { | |||
| 			is_fixed = true | ||||
| 			val_type = p.parse_type() | ||||
| 			match exprs[0] { | ||||
| 				ast.IntegerLiteral { fixed_size = it.val } | ||||
| 				ast.IntegerLiteral { | ||||
| 					fixed_size = it.val | ||||
| 				} | ||||
| 				else {} | ||||
| 			} | ||||
| 	} | ||||
| 			p.warn('fixed size array') | ||||
| 		} | ||||
| 	} | ||||
| 	idx := if is_fixed { | ||||
| 		p.table.find_or_register_array_fixed(val_type, fixed_size, 1) | ||||
| 	} | ||||
| 	else { | ||||
| 		p.table.find_or_register_array(val_type, 1) | ||||
| 	} | ||||
| 	idx := if is_fixed { p.table.find_or_register_array_fixed(val_type, fixed_size, 1) } else { p.table.find_or_register_array(val_type, 1) } | ||||
| 	array_type := table.new_type(idx) | ||||
| 	node = ast.ArrayInit{ | ||||
| 		typ: array_type | ||||
|  | @ -1252,19 +1266,19 @@ fn (p mut Parser) global_decl() ast.GlobalDecl { | |||
| 	p.table.register_global(name, typ) | ||||
| 	// p.genln(p.table.cgen_name_type_pair(name, typ))
 | ||||
| 	/* | ||||
| 				mut g := p.table.cgen_name_type_pair(name, typ) | ||||
| 				if p.tok == .assign { | ||||
| 					p.next() | ||||
| 					g += ' = ' | ||||
| 					_,expr := p.tmp_expr() | ||||
| 					g += expr | ||||
| 				} | ||||
| 				// p.genln('; // global')
 | ||||
| 				g += '; // global' | ||||
| 				if !p.cgen.nogen { | ||||
| 					p.cgen.consts << g | ||||
| 				} | ||||
| 				*/ | ||||
| 		mut g := p.table.cgen_name_type_pair(name, typ) | ||||
| 		if p.tok == .assign { | ||||
| 			p.next() | ||||
| 			g += ' = ' | ||||
| 			_,expr := p.tmp_expr() | ||||
| 			g += expr | ||||
| 		} | ||||
| 		// p.genln('; // global')
 | ||||
| 		g += '; // global' | ||||
| 		if !p.cgen.nogen { | ||||
| 			p.cgen.consts << g | ||||
| 		} | ||||
| 		*/ | ||||
| 
 | ||||
| 	return ast.GlobalDecl{ | ||||
| 		name: name | ||||
|  | @ -1277,13 +1291,15 @@ fn (p mut Parser) match_expr() (ast.Expr,table.Type) { | |||
| 	p.check(.lcbr) | ||||
| 	mut blocks := []ast.StmtBlock | ||||
| 	mut match_exprs := []ast.Expr | ||||
| 	mut return_type := table.void_type | ||||
| 	for { | ||||
| 		// p.tok.kind != .rcbr {
 | ||||
| 		match_expr,_ := p.expr(0) | ||||
| 		match_exprs << match_expr | ||||
| 		p.warn('match block') | ||||
| 		stmts := p.parse_block() | ||||
| 		blocks << ast.StmtBlock{ | ||||
| 			stmts: p.parse_block() | ||||
| 			stmts: stmts | ||||
| 		} | ||||
| 		if p.tok.kind == .key_else { | ||||
| 			p.next() | ||||
|  | @ -1291,6 +1307,17 @@ fn (p mut Parser) match_expr() (ast.Expr,table.Type) { | |||
| 				stmts: p.parse_block() | ||||
| 			} | ||||
| 		} | ||||
| 		// If the last statement is an expression, return its type
 | ||||
| 		if stmts.len > 0 { | ||||
| 			match stmts[stmts.len - 1] { | ||||
| 				ast.ExprStmt { | ||||
| 					type_sym := p.table.get_type_symbol(it.typ) | ||||
| 					p.warn('match expr ret $type_sym.name') | ||||
| 					return_type = it.typ | ||||
| 				} | ||||
| 				else {} | ||||
| 	} | ||||
| 		} | ||||
| 		if p.tok.kind == .rcbr { | ||||
| 			break | ||||
| 		} | ||||
|  | @ -1303,7 +1330,7 @@ fn (p mut Parser) match_expr() (ast.Expr,table.Type) { | |||
| 		typ: typ | ||||
| 		cond: cond | ||||
| 	} | ||||
| 	return node,table.void_type | ||||
| 	return node,return_type | ||||
| } | ||||
| 
 | ||||
| fn (p mut Parser) add_unresolved(key string, expr ast.Expr) table.Type { | ||||
|  |  | |||
|  | @ -168,6 +168,7 @@ pub fn (p mut Table) clear_vars() { | |||
| 		// ///}
 | ||||
| 		p.local_vars = [] | ||||
| 	} | ||||
| 	p.tmp_cnt = 0 | ||||
| } | ||||
| 
 | ||||
| pub fn (t &Table) find_fn(name string) ?Fn { | ||||
|  | @ -224,7 +225,6 @@ pub fn (t &TypeSymbol) find_method(name string) ?Fn { | |||
| 	return none | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| pub fn (s &TypeSymbol) has_field(name string) bool { | ||||
| 	s.find_field(name) or { | ||||
| 		return false | ||||
|  | @ -235,7 +235,7 @@ pub fn (s &TypeSymbol) has_field(name string) bool { | |||
| pub fn (s &TypeSymbol) find_field(name string) ?Field { | ||||
| 	match s.info { | ||||
| 		Struct { | ||||
| 		    for field in it.fields { | ||||
| 			for field in it.fields { | ||||
| 				if field.name == name { | ||||
| 					return field | ||||
| 				} | ||||
|  | @ -302,7 +302,8 @@ pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol { | |||
| 			kind: .unresolved | ||||
| 			name: 'unresolved-$unresolved_idx' | ||||
| 		} | ||||
| 	} else if idx > 0 { | ||||
| 	} | ||||
| 	else if idx > 0 { | ||||
| 		return &t.types[idx] | ||||
| 	} | ||||
| 	// this should never happen
 | ||||
|  | @ -319,8 +320,12 @@ pub fn (t mut Table) register_builtin_type_symbol(typ TypeSymbol) int { | |||
| 		if existing_idx >= string_type_idx { | ||||
| 			if existing_idx == string_type_idx { | ||||
| 				existing_type := &t.types[existing_idx] | ||||
| 				t.types[existing_idx] = { typ | kind: existing_type.kind } | ||||
| 			} else { | ||||
| 				t.types[existing_idx] = { | ||||
| 					typ | | ||||
| 					kind:existing_type.kind | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
| 				t.types[existing_idx] = typ | ||||
| 			} | ||||
| 		} | ||||
|  | @ -473,8 +478,7 @@ pub fn (t &Table) check(got, expected Type) bool { | |||
| 	if exp_type_sym.kind == .voidptr { | ||||
| 		return true | ||||
| 	} | ||||
| 	if got_type_sym.kind in [.voidptr, .byteptr, .charptr, .int] && | ||||
| 		exp_type_sym.kind in [.voidptr, .byteptr, .charptr] { | ||||
| 	if got_type_sym.kind in [.voidptr, .byteptr, .charptr, .int] && exp_type_sym.kind in [.voidptr, .byteptr, .charptr] { | ||||
| 		return true | ||||
| 	} | ||||
| 	if got_type_sym.is_int() && exp_type_sym.is_int() { | ||||
|  | @ -489,7 +493,7 @@ pub fn (t &Table) check(got, expected Type) bool { | |||
| 	// if expected.name == 'array' {
 | ||||
| 	// return true
 | ||||
| 	// }
 | ||||
| 	if got_idx != exp_idx /*&& got.typ.name != expected.typ.name*/ { | ||||
| 	if got_idx != exp_idx/*&& got.typ.name != expected.typ.name*/ { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue