v.gen.js: improve reference support (#10793)
							parent
							
								
									19642a1182
								
							
						
					
					
						commit
						9c710b2a34
					
				|  | @ -655,13 +655,18 @@ fn (mut g JsGen) expr(node ast.Expr) { | ||||||
| 			if node.op in [.amp, .mul] { | 			if node.op in [.amp, .mul] { | ||||||
| 				// C pointers/references: ignore them
 | 				// C pointers/references: ignore them
 | ||||||
| 				if node.op == .amp { | 				if node.op == .amp { | ||||||
| 					g.write('{ value: ') | 					type_sym := g.table.get_type_symbol(node.right_type) | ||||||
| 					g.expr(node.right) | 					if !type_sym.is_primitive() && !node.right_type.is_pointer() { | ||||||
| 					g.write(' } ') | 						g.write('{ val: ') | ||||||
|  | 						g.expr(node.right) | ||||||
|  | 						g.write(' } ') | ||||||
|  | 					} else { | ||||||
|  | 						g.expr(node.right) | ||||||
|  | 					} | ||||||
| 				} else { | 				} else { | ||||||
| 					g.write('(') | 					g.write('(') | ||||||
| 					g.expr(node.right) | 					g.expr(node.right) | ||||||
| 					g.write(').value') | 					g.write(').val') | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				g.write(node.op.str()) | 				g.write(node.op.str()) | ||||||
|  | @ -808,13 +813,18 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			g.expr(left) | 			g.expr(left) | ||||||
|  | 			mut is_ptr := false | ||||||
| 			if stmt.op == .assign && stmt.left_types[i].is_ptr() { | 			if stmt.op == .assign && stmt.left_types[i].is_ptr() { | ||||||
| 				g.write('.value') | 				is_ptr = true | ||||||
|  | 				g.write('.val') | ||||||
| 			} | 			} | ||||||
| 			if g.inside_map_set && op == .assign { | 			if g.inside_map_set && op == .assign { | ||||||
| 				g.inside_map_set = false | 				g.inside_map_set = false | ||||||
| 				g.write(', ') | 				g.write(', ') | ||||||
| 				g.expr(val) | 				g.expr(val) | ||||||
|  | 				if is_ptr { | ||||||
|  | 					g.write('.val') | ||||||
|  | 				} | ||||||
| 				g.write(')') | 				g.write(')') | ||||||
| 			} else { | 			} else { | ||||||
| 				g.write(' $op ') | 				g.write(' $op ') | ||||||
|  | @ -831,6 +841,9 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { | ||||||
| 					g.write('${g.typ(stmt.left_types.first())}(') | 					g.write('${g.typ(stmt.left_types.first())}(') | ||||||
| 				} | 				} | ||||||
| 				g.expr(val) | 				g.expr(val) | ||||||
|  | 				if is_ptr { | ||||||
|  | 					g.write('.val') | ||||||
|  | 				} | ||||||
| 				if should_cast { | 				if should_cast { | ||||||
| 					g.write(')') | 					g.write(')') | ||||||
| 					g.cast_stack.delete_last() | 					g.cast_stack.delete_last() | ||||||
|  | @ -1302,14 +1315,20 @@ fn (mut g JsGen) gen_array_init_values(exprs []ast.Expr) { | ||||||
| 
 | 
 | ||||||
| fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { | fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { | ||||||
| 	g.call_stack << it | 	g.call_stack << it | ||||||
| 	expected_types := it.expected_arg_types |  | ||||||
| 	mut name := g.js_name(it.name) | 	mut name := g.js_name(it.name) | ||||||
| 	call_return_is_optional := it.return_type.has_flag(.optional) | 	call_return_is_optional := it.return_type.has_flag(.optional) | ||||||
| 	if it.is_method { | 	if call_return_is_optional { | ||||||
|  | 		g.writeln('(function(){') | ||||||
|  | 		g.inc_indent() | ||||||
|  | 		g.writeln('try {') | ||||||
|  | 		g.inc_indent() | ||||||
|  | 		g.write('return builtin.unwrap(') | ||||||
|  | 	} | ||||||
|  | 	g.expr(it.left) | ||||||
|  | 	if it.is_method { // foo.bar.baz()
 | ||||||
| 		sym := g.table.get_type_symbol(it.receiver_type) | 		sym := g.table.get_type_symbol(it.receiver_type) | ||||||
|  | 		g.write('.') | ||||||
| 		if sym.kind == .array && it.name in ['map', 'filter'] { | 		if sym.kind == .array && it.name in ['map', 'filter'] { | ||||||
| 			g.expr(it.left) |  | ||||||
| 			g.write('.') |  | ||||||
| 			// Prevent 'it' from getting shadowed inside the match
 | 			// Prevent 'it' from getting shadowed inside the match
 | ||||||
| 			node := it | 			node := it | ||||||
| 			g.write(it.name) | 			g.write(it.name) | ||||||
|  | @ -1342,52 +1361,6 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { | ||||||
| 			g.write(')') | 			g.write(')') | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	g.writeln('(function() { ') |  | ||||||
| 	g.inc_indent() |  | ||||||
| 	mut mut_args := map[int]MutArg{} |  | ||||||
| 	// store all the mutable arguments in temporary variable + allocate an object which boxes these arguments
 |  | ||||||
| 	for i, arg in it.args { |  | ||||||
| 		if arg.is_mut { |  | ||||||
| 			tmp_var := g.new_tmp_var() |  | ||||||
| 			g.writeln('const $tmp_var = ') |  | ||||||
| 			expr := arg.expr |  | ||||||
| 			match expr { |  | ||||||
| 				ast.Ident { |  | ||||||
| 					if expr.var_info().typ.is_ptr() { |  | ||||||
| 						g.write(expr.name) |  | ||||||
| 						g.writeln(';') |  | ||||||
| 					} else { |  | ||||||
| 						g.write('{ value: ') |  | ||||||
| 						g.expr(expr) |  | ||||||
| 						g.writeln(' }; ') |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				else { |  | ||||||
| 					g.write('{ value: ') |  | ||||||
| 					g.expr(expr) |  | ||||||
| 					g.writeln(' }; ') |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			mut_args[i] = MutArg{tmp_var, arg.expr} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	g.write('let result;') |  | ||||||
| 	if call_return_is_optional { |  | ||||||
| 		g.writeln('(function(){') |  | ||||||
| 		g.inc_indent() |  | ||||||
| 		g.writeln('try {') |  | ||||||
| 		g.inc_indent() |  | ||||||
| 		// g.write('return builtin.unwrap(')
 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	g.writeln('result = ') |  | ||||||
| 	g.expr(it.left) |  | ||||||
| 
 |  | ||||||
| 	if it.is_method { // foo.bar.baz()
 |  | ||||||
| 		g.write('.') |  | ||||||
| 	} else { | 	} else { | ||||||
| 		if name in g.builtin_fns { | 		if name in g.builtin_fns { | ||||||
| 			g.write('builtin.') | 			g.write('builtin.') | ||||||
|  | @ -1395,51 +1368,16 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { | ||||||
| 	} | 	} | ||||||
| 	g.write('${name}(') | 	g.write('${name}(') | ||||||
| 	for i, arg in it.args { | 	for i, arg in it.args { | ||||||
| 		if arg.is_mut { | 		g.expr(arg.expr) | ||||||
| 			mut_arg := mut_args[i] |  | ||||||
| 			g.write(mut_arg.tmp_var) |  | ||||||
| 		} else { |  | ||||||
| 			g.expr(arg.expr) |  | ||||||
| 		} |  | ||||||
| 		// TODO: Is this correct way of passing argument?
 |  | ||||||
| 		if i < expected_types.len && arg.typ.is_ptr() && !arg.is_mut && !expected_types[i].is_ptr() { |  | ||||||
| 			g.write('.value') |  | ||||||
| 		} |  | ||||||
| 		if i != it.args.len - 1 { | 		if i != it.args.len - 1 { | ||||||
| 			g.write(', ') | 			g.write(', ') | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// end method call
 | 	// end method call
 | ||||||
| 	g.writeln(');') | 	g.write(')') | ||||||
| 	// now unbox all the mutable arguments
 |  | ||||||
| 	for i, arg in it.args { |  | ||||||
| 		if arg.is_mut { |  | ||||||
| 			mut_arg := mut_args[i] |  | ||||||
| 			expr := mut_arg.expr |  | ||||||
| 			match expr { |  | ||||||
| 				ast.Ident { |  | ||||||
| 					if !expr.var_info().typ.is_ptr() { |  | ||||||
| 						g.writeln('$expr.name = ($mut_arg.tmp_var).value;') |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				ast.IndexExpr { |  | ||||||
| 					g.expr(mut_arg.expr) |  | ||||||
| 					g.writeln(' = ($mut_arg.tmp_var).value;') |  | ||||||
| 				} |  | ||||||
| 				ast.SelectorExpr { |  | ||||||
| 					g.expr(mut_arg.expr) |  | ||||||
| 					g.writeln(' = ($mut_arg.tmp_var).value;') |  | ||||||
| 				} |  | ||||||
| 				else { |  | ||||||
| 					// TODO
 |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if call_return_is_optional { | 	if call_return_is_optional { | ||||||
| 		// end unwrap
 | 		// end unwrap
 | ||||||
| 		g.writeln('result = builtin.unwrap(result)') | 		g.writeln(')') | ||||||
| 		g.dec_indent() | 		g.dec_indent() | ||||||
| 		// begin catch block
 | 		// begin catch block
 | ||||||
| 		g.writeln('} catch(err) {') | 		g.writeln('} catch(err) {') | ||||||
|  | @ -1450,7 +1388,7 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { | ||||||
| 				if it.or_block.stmts.len > 1 { | 				if it.or_block.stmts.len > 1 { | ||||||
| 					g.stmts(it.or_block.stmts[..it.or_block.stmts.len - 1]) | 					g.stmts(it.or_block.stmts[..it.or_block.stmts.len - 1]) | ||||||
| 				} | 				} | ||||||
| 				// g.write('result =  ')
 | 				g.write('return ') | ||||||
| 				g.stmt(it.or_block.stmts.last()) | 				g.stmt(it.or_block.stmts.last()) | ||||||
| 			} | 			} | ||||||
| 			.propagate { | 			.propagate { | ||||||
|  | @ -1468,11 +1406,8 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { | ||||||
| 		g.writeln('}') | 		g.writeln('}') | ||||||
| 		// end anon fn
 | 		// end anon fn
 | ||||||
| 		g.dec_indent() | 		g.dec_indent() | ||||||
| 		g.writeln('})()') | 		g.write('})()') | ||||||
| 	} | 	} | ||||||
| 	g.dec_indent() |  | ||||||
| 	g.writeln('return result;') |  | ||||||
| 	g.writeln('})()') |  | ||||||
| 	g.call_stack.delete_last() | 	g.call_stack.delete_last() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue