cgen: cast to sum type
							parent
							
								
									66adf7a6b9
								
							
						
					
					
						commit
						c947e6ebe6
					
				|  | @ -189,6 +189,8 @@ pub struct Return { | |||
| pub: | ||||
| 	pos   token.Position | ||||
| 	exprs []Expr | ||||
| mut: | ||||
| 	types []table.Type | ||||
| } | ||||
| 
 | ||||
| /* | ||||
|  | @ -416,10 +418,13 @@ pub: | |||
| 
 | ||||
| pub struct AssignStmt { | ||||
| pub: | ||||
| 	left  []Ident | ||||
| 	right []Expr | ||||
| 	op    token.Kind | ||||
| 	pos   token.Position | ||||
| 	left        []Ident | ||||
| 	right       []Expr | ||||
| 	op          token.Kind | ||||
| 	pos         token.Position | ||||
| mut: | ||||
| 	left_types  []table.Type | ||||
| 	right_types []table.Type | ||||
| } | ||||
| 
 | ||||
| pub struct AsCast { | ||||
|  | @ -490,12 +495,13 @@ pub: | |||
| 
 | ||||
| pub struct AssignExpr { | ||||
| pub: | ||||
| 	op        token.Kind | ||||
| 	pos       token.Position | ||||
| 	left      Expr | ||||
| 	val       Expr | ||||
| 	op         token.Kind | ||||
| 	pos        token.Position | ||||
| 	left       Expr | ||||
| 	val        Expr | ||||
| mut: | ||||
| 	left_type table.Type | ||||
| 	left_type  table.Type | ||||
| 	right_type table.Type | ||||
| } | ||||
| 
 | ||||
| pub struct GotoLabel { | ||||
|  |  | |||
|  | @ -169,6 +169,7 @@ fn (c mut Checker) assign_expr(assign_expr mut ast.AssignExpr) { | |||
| 	// t := c.table.get_type_symbol(left_type)
 | ||||
| 	// println('setting exp type to $c.expected_type $t.name')
 | ||||
| 	right_type := c.expr(assign_expr.val) | ||||
| 	assign_expr.right_type = right_type | ||||
| 	if !c.table.check(right_type, left_type) { | ||||
| 		left_type_sym := c.table.get_type_symbol(left_type) | ||||
| 		right_type_sym := c.table.get_type_symbol(right_type) | ||||
|  | @ -352,7 +353,7 @@ pub fn (c mut Checker) selector_expr(selector_expr mut ast.SelectorExpr) table.T | |||
| } | ||||
| 
 | ||||
| // TODO: non deferred
 | ||||
| pub fn (c mut Checker) return_stmt(return_stmt ast.Return) { | ||||
| pub fn (c mut Checker) return_stmt(return_stmt mut ast.Return) { | ||||
| 	c.expected_type = c.fn_return_type | ||||
| 	if return_stmt.exprs.len == 0 { | ||||
| 		return | ||||
|  | @ -370,6 +371,7 @@ pub fn (c mut Checker) return_stmt(return_stmt ast.Return) { | |||
| 		typ := c.expr(expr) | ||||
| 		got_types << typ | ||||
| 	} | ||||
| 	return_stmt.types = got_types | ||||
| 	// allow `none` & `error (Option)` return types for function that returns optional
 | ||||
| 	if exp_is_optional && table.type_idx(got_types[0]) in [table.none_type_idx, c.table.type_idxs['Option']] { | ||||
| 		return | ||||
|  | @ -406,12 +408,14 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) { | |||
| 			assign_stmt.left[i] = ident | ||||
| 			if assign_stmt.op == .assign { | ||||
| 				var_type := c.expr(ident) | ||||
| 				assign_stmt.left_types << var_type | ||||
| 				if !c.table.check(val_type, var_type) { | ||||
| 					val_type_sym := c.table.get_type_symbol(val_type) | ||||
| 					var_type_sym := c.table.get_type_symbol(var_type) | ||||
| 					c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`', assign_stmt.pos) | ||||
| 				} | ||||
| 			} | ||||
| 			assign_stmt.right_types << val_type | ||||
| 			scope.override_var(ast.Var{ | ||||
| 				name: ident.name | ||||
| 				typ: mr_info.types[i] | ||||
|  | @ -426,16 +430,18 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) { | |||
| 		mut scope := c.file.scope.innermost(assign_stmt.pos.pos) | ||||
| 		for i, _ in assign_stmt.left { | ||||
| 			mut ident := assign_stmt.left[i] | ||||
| 			mut ident_var_info := ident.var_info() | ||||
| 			val_type := c.expr(assign_stmt.right[i]) | ||||
| 			if assign_stmt.op == .assign { | ||||
| 				var_type := c.expr(ident) | ||||
| 				assign_stmt.left_types << var_type | ||||
| 				if !c.table.check(val_type, var_type) { | ||||
| 					val_type_sym := c.table.get_type_symbol(val_type) | ||||
| 					var_type_sym := c.table.get_type_symbol(var_type) | ||||
| 					c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`', assign_stmt.pos) | ||||
| 				} | ||||
| 			} | ||||
| 			mut ident_var_info := ident.var_info() | ||||
| 			assign_stmt.right_types << val_type | ||||
| 			ident_var_info.typ = val_type | ||||
| 			ident.info = ident_var_info | ||||
| 			assign_stmt.left[i] = ident | ||||
|  | @ -556,7 +562,7 @@ fn (c mut Checker) stmt(node ast.Stmt) { | |||
| 		// ast.HashStmt {}
 | ||||
| 		ast.Import {} | ||||
| 		ast.Return { | ||||
| 			c.return_stmt(it) | ||||
| 			c.return_stmt(mut it) | ||||
| 		} | ||||
| 		// ast.StructDecl {}
 | ||||
| 		ast.UnsafeStmt { | ||||
|  |  | |||
|  | @ -326,6 +326,29 @@ fn (g mut Gen) stmt(node ast.Stmt) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g &Gen) is_sum_cast(got_type table.Type, exp_type table.Type) bool { | ||||
| 	if exp_type != table.void_type && exp_type != 0  && got_type != 0{ | ||||
| 		exp_sym := g.table.get_type_symbol(exp_type) | ||||
| 		// got_sym := g.table.get_type_symbol(got_type)
 | ||||
| 		if exp_sym.kind == .sum_type { | ||||
| 			sum_info := exp_sym.info as table.SumType | ||||
| 			if got_type in sum_info.variants { | ||||
| 				return true | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) sum_cast(got_type table.Type, exp_type table.Type, expr ast.Expr) { | ||||
| 	got_styp := g.typ(got_type) | ||||
| 	exp_styp := g.typ(exp_type) | ||||
| 	got_idx := table.type_idx(got_type) | ||||
| 	g.write('/* SUM TYPE CAST */ ($exp_styp) {.obj = memdup(&(${got_styp}[]) {') | ||||
| 	g.expr(expr) | ||||
| 	g.writeln('}, sizeof($got_styp)), .typ = $got_idx};') | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { | ||||
| 	// multi return
 | ||||
| 	// g.write('/*assign*/')
 | ||||
|  | @ -394,13 +417,20 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { | |||
| 					} | ||||
| 					else {} | ||||
| 	} | ||||
| 				mut is_sum_cast := false | ||||
| 				if assign_stmt.op == .decl_assign { | ||||
| 					g.write('$styp ') | ||||
| 				} else { | ||||
| 					is_sum_cast = g.is_sum_cast(assign_stmt.right_types[i], assign_stmt.left_types[i]) | ||||
| 				} | ||||
| 				g.expr(ident) | ||||
| 				if !is_fixed_array_init { | ||||
| 					g.write(' = ') | ||||
| 					g.expr(val) | ||||
| 					if is_sum_cast { | ||||
| 						g.sum_cast(ident_var_info.typ, assign_stmt.left_types[i], val) | ||||
| 					} else { | ||||
| 						g.expr(val) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			g.writeln(';') | ||||
|  | @ -549,7 +579,11 @@ fn (g mut Gen) expr(node ast.Expr) { | |||
| 				g.write(', ') | ||||
| 			} | ||||
| 			g.is_assign_expr = false | ||||
| 			g.expr(it.val) | ||||
| 			if g.is_sum_cast(it.left_type, it.right_type) { | ||||
| 				g.sum_cast(it.left_type, it.right_type, it.val) | ||||
| 			} else { | ||||
| 				g.expr(it.val) | ||||
| 			} | ||||
| 			if g.is_array_set { | ||||
| 				g.write(' })') | ||||
| 				g.is_array_set = false | ||||
|  | @ -1135,6 +1169,8 @@ fn (g mut Gen) return_statement(it ast.Return) { | |||
| 	g.write('return') | ||||
| 	// multiple returns
 | ||||
| 	if it.exprs.len > 1 { | ||||
| 		typ_sym := g.table.get_type_symbol(g.fn_decl.return_type) | ||||
| 		mr_info := typ_sym.info as table.MultiReturn | ||||
| 		styp := g.typ(g.fn_decl.return_type) | ||||
| 		g.write(' ($styp){') | ||||
| 		for i, expr in it.exprs { | ||||
|  | @ -1171,7 +1207,12 @@ fn (g mut Gen) return_statement(it ast.Return) { | |||
| 			} | ||||
| 			// g.write('/*OPTIONAL*/')
 | ||||
| 		} | ||||
| 		g.expr(it.exprs[0]) | ||||
| 		if g.is_sum_cast(it.types[0], g.fn_decl.return_type) { | ||||
| 			g.sum_cast(it.types[0], g.fn_decl.return_type, it.exprs[0]) | ||||
| 		} | ||||
| 		else { | ||||
| 			g.expr(it.exprs[0]) | ||||
| 		} | ||||
| 	} | ||||
| 	g.writeln(';') | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue