cgen: array_set()
							parent
							
								
									63032c4bb7
								
							
						
					
					
						commit
						fbf80dc315
					
				| 
						 | 
					@ -8,15 +8,15 @@ import (
 | 
				
			||||||
	v.table
 | 
						v.table
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | 	
 | 
					pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
 | 
				
			||||||
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | 	
 | 
					FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
 | 
				
			||||||
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | 	
 | 
					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 = VarDecl | 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
 | 
				
			||||||
// pub type Type = StructType | ArrayType
 | 
					// pub type Type = StructType | ArrayType
 | 
				
			||||||
// pub struct StructType {
 | 
					// pub struct StructType {
 | 
				
			||||||
| 
						 | 
					@ -463,10 +463,12 @@ pub:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct AssignExpr {
 | 
					pub struct AssignExpr {
 | 
				
			||||||
pub:
 | 
					pub:
 | 
				
			||||||
	op   token.Kind
 | 
						op        token.Kind
 | 
				
			||||||
	pos  token.Position
 | 
						pos       token.Position
 | 
				
			||||||
	left Expr
 | 
						left      Expr
 | 
				
			||||||
	val  Expr
 | 
						val       Expr
 | 
				
			||||||
 | 
					//mut:
 | 
				
			||||||
 | 
						//left_type table.Type
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct GotoLabel {
 | 
					pub struct GotoLabel {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,6 +157,7 @@ fn (c mut Checker) assign_expr(assign_expr ast.AssignExpr) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	left_type := c.expr(assign_expr.left)
 | 
						left_type := c.expr(assign_expr.left)
 | 
				
			||||||
	c.expected_type = left_type
 | 
						c.expected_type = left_type
 | 
				
			||||||
 | 
						// assign_expr.left_type = left_type
 | 
				
			||||||
	// t := c.table.get_type_symbol(left_type)
 | 
						// t := c.table.get_type_symbol(left_type)
 | 
				
			||||||
	// println('setting exp type to $c.expected_type $t.name')
 | 
						// println('setting exp type to $c.expected_type $t.name')
 | 
				
			||||||
	right_type := c.expr(assign_expr.val)
 | 
						right_type := c.expr(assign_expr.val)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,14 +9,16 @@ import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Gen {
 | 
					struct Gen {
 | 
				
			||||||
	out         strings.Builder
 | 
						out            strings.Builder
 | 
				
			||||||
	typedefs    strings.Builder
 | 
						typedefs       strings.Builder
 | 
				
			||||||
	definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file)
 | 
						definitions    strings.Builder // typedefs, defines etc (everything that goes to the top of the file)
 | 
				
			||||||
	table       &table.Table
 | 
						table          &table.Table
 | 
				
			||||||
mut:
 | 
					mut:
 | 
				
			||||||
	fn_decl     &ast.FnDecl // pointer to the FnDecl we are currently inside otherwise 0
 | 
						fn_decl        &ast.FnDecl // pointer to the FnDecl we are currently inside otherwise 0
 | 
				
			||||||
	tmp_count   int
 | 
						tmp_count      int
 | 
				
			||||||
	is_c_call   bool // e.g. `C.printf("v")`
 | 
						is_c_call      bool // e.g. `C.printf("v")`
 | 
				
			||||||
 | 
						is_assign_expr bool
 | 
				
			||||||
 | 
						is_array_set   bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn cgen(files []ast.File, table &table.Table) string {
 | 
					pub fn cgen(files []ast.File, table &table.Table) string {
 | 
				
			||||||
| 
						 | 
					@ -383,9 +385,18 @@ fn (g mut Gen) expr(node ast.Expr) {
 | 
				
			||||||
			g.write('/* as */')
 | 
								g.write('/* as */')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ast.AssignExpr {
 | 
							ast.AssignExpr {
 | 
				
			||||||
 | 
								g.is_assign_expr = true
 | 
				
			||||||
			g.expr(it.left)
 | 
								g.expr(it.left)
 | 
				
			||||||
			g.write(' $it.op.str() ')
 | 
								// arr[i] = val => `array_set(arr, i, val)`, not `array_get(arr, i) = val`
 | 
				
			||||||
 | 
								if !g.is_array_set {
 | 
				
			||||||
 | 
									g.write(' $it.op.str() ')
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			g.expr(it.val)
 | 
								g.expr(it.val)
 | 
				
			||||||
 | 
								if g.is_array_set {
 | 
				
			||||||
 | 
									g.write(')')
 | 
				
			||||||
 | 
									g.is_array_set = false
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								g.is_assign_expr = false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ast.Assoc {
 | 
							ast.Assoc {
 | 
				
			||||||
			g.write('/* assoc */')
 | 
								g.write('/* assoc */')
 | 
				
			||||||
| 
						 | 
					@ -498,40 +509,7 @@ fn (g mut Gen) expr(node ast.Expr) {
 | 
				
			||||||
			g.index_expr(it)
 | 
								g.index_expr(it)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ast.InfixExpr {
 | 
							ast.InfixExpr {
 | 
				
			||||||
			// if it.left_type == table.string_type_idx {
 | 
								g.infix_expr(it)
 | 
				
			||||||
			// g.write('/*$it.left_type str*/')
 | 
					 | 
				
			||||||
			// }
 | 
					 | 
				
			||||||
			// string + string
 | 
					 | 
				
			||||||
			if it.op == .plus && it.left_type == table.string_type_idx {
 | 
					 | 
				
			||||||
				g.write('string_add(')
 | 
					 | 
				
			||||||
				g.expr(it.left)
 | 
					 | 
				
			||||||
				g.write(', ')
 | 
					 | 
				
			||||||
				g.expr(it.right)
 | 
					 | 
				
			||||||
				g.write(')')
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else if it.op == .eq && it.left_type == table.string_type_idx {
 | 
					 | 
				
			||||||
				g.write('string_eq(')
 | 
					 | 
				
			||||||
				g.expr(it.left)
 | 
					 | 
				
			||||||
				g.write(', ')
 | 
					 | 
				
			||||||
				g.expr(it.right)
 | 
					 | 
				
			||||||
				g.write(')')
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			// arr << val
 | 
					 | 
				
			||||||
			else if it.op == .left_shift && g.table.get_type_symbol(it.left_type).kind == .array {
 | 
					 | 
				
			||||||
				g.write('array_push(')
 | 
					 | 
				
			||||||
				g.expr(it.left)
 | 
					 | 
				
			||||||
				g.write(', ')
 | 
					 | 
				
			||||||
				g.expr(it.right)
 | 
					 | 
				
			||||||
				g.write(')')
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else {
 | 
					 | 
				
			||||||
				// if it.op == .dot {
 | 
					 | 
				
			||||||
				// println('!! dot')
 | 
					 | 
				
			||||||
				// }
 | 
					 | 
				
			||||||
				g.expr(it.left)
 | 
					 | 
				
			||||||
				g.write(' $it.op.str() ')
 | 
					 | 
				
			||||||
				g.expr(it.right)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ast.IntegerLiteral {
 | 
							ast.IntegerLiteral {
 | 
				
			||||||
			g.write(it.val.str())
 | 
								g.write(it.val.str())
 | 
				
			||||||
| 
						 | 
					@ -687,6 +665,49 @@ fn (g mut Gen) expr(node ast.Expr) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn (g mut Gen) infix_expr(it ast.InfixExpr) {
 | 
				
			||||||
 | 
						// if it.left_type == table.string_type_idx {
 | 
				
			||||||
 | 
						// g.write('/*$it.left_type str*/')
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
						// string + string, string == string etc
 | 
				
			||||||
 | 
						if it.left_type == table.string_type_idx {
 | 
				
			||||||
 | 
							fn_name := match it.op {
 | 
				
			||||||
 | 
								.plus{
 | 
				
			||||||
 | 
									'string_add('
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								.eq{
 | 
				
			||||||
 | 
									'string_eq('
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								.ne{
 | 
				
			||||||
 | 
									'string_ne('
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									''}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
							g.write(fn_name)
 | 
				
			||||||
 | 
							g.expr(it.left)
 | 
				
			||||||
 | 
							g.write(', ')
 | 
				
			||||||
 | 
							g.expr(it.right)
 | 
				
			||||||
 | 
							g.write(')')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// arr << val
 | 
				
			||||||
 | 
						else if it.op == .left_shift && g.table.get_type_symbol(it.left_type).kind == .array {
 | 
				
			||||||
 | 
							g.write('array_push(')
 | 
				
			||||||
 | 
							g.expr(it.left)
 | 
				
			||||||
 | 
							g.write(', ')
 | 
				
			||||||
 | 
							g.expr(it.right)
 | 
				
			||||||
 | 
							g.write(')')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							// if it.op == .dot {
 | 
				
			||||||
 | 
							// println('!! dot')
 | 
				
			||||||
 | 
							// }
 | 
				
			||||||
 | 
							g.expr(it.left)
 | 
				
			||||||
 | 
							g.write(' $it.op.str() ')
 | 
				
			||||||
 | 
							g.expr(it.right)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn (g mut Gen) index_expr(node ast.IndexExpr) {
 | 
					fn (g mut Gen) index_expr(node ast.IndexExpr) {
 | 
				
			||||||
	// TODO else doesn't work with sum types
 | 
						// TODO else doesn't work with sum types
 | 
				
			||||||
	mut is_range := false
 | 
						mut is_range := false
 | 
				
			||||||
| 
						 | 
					@ -729,11 +750,21 @@ fn (g mut Gen) index_expr(node ast.IndexExpr) {
 | 
				
			||||||
	if !is_range && node.container_type != 0 {
 | 
						if !is_range && node.container_type != 0 {
 | 
				
			||||||
		sym := g.table.get_type_symbol(node.container_type)
 | 
							sym := g.table.get_type_symbol(node.container_type)
 | 
				
			||||||
		if sym.kind == .array {
 | 
							if sym.kind == .array {
 | 
				
			||||||
			g.write('array_get(')
 | 
								if g.is_assign_expr {
 | 
				
			||||||
			g.expr(node.left)
 | 
									g.is_array_set = true
 | 
				
			||||||
			g.write(', ')
 | 
									g.write('array_set(&')
 | 
				
			||||||
			g.expr(node.index)
 | 
									g.expr(node.left)
 | 
				
			||||||
			g.write(')')
 | 
									g.write(', ')
 | 
				
			||||||
 | 
									g.expr(node.index)
 | 
				
			||||||
 | 
									g.write(', ')
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									g.write('array_get(')
 | 
				
			||||||
 | 
									g.expr(node.left)
 | 
				
			||||||
 | 
									g.write(', ')
 | 
				
			||||||
 | 
									g.expr(node.index)
 | 
				
			||||||
 | 
									g.write(')')
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if sym.kind == .string {
 | 
							else if sym.kind == .string {
 | 
				
			||||||
			g.write('string_at(')
 | 
								g.write('string_at(')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,6 +69,7 @@ i < 10; i++) {
 | 
				
			||||||
	array_int nums3 = array_slice(nums, 1, 2);
 | 
						array_int nums3 = array_slice(nums, 1, 2);
 | 
				
			||||||
	array_int nums4 = array_slice(nums, 1, nums.len);
 | 
						array_int nums4 = array_slice(nums, 1, nums.len);
 | 
				
			||||||
	int number = array_get(nums, 0);
 | 
						int number = array_get(nums, 0);
 | 
				
			||||||
 | 
						array_set(&nums, 1, 10);
 | 
				
			||||||
	array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), (bool[]){
 | 
						array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), (bool[]){
 | 
				
			||||||
		true, false,
 | 
							true, false,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,11 +59,12 @@ fn foo(a int) {
 | 
				
			||||||
	for i := 0; i < 10; i++ {
 | 
						for i := 0; i < 10; i++ {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	nums := [1,2,3]
 | 
						mut nums := [1,2,3]
 | 
				
			||||||
	nums2 := nums[..2]
 | 
						nums2 := nums[..2]
 | 
				
			||||||
	nums3 := nums[1..2]
 | 
						nums3 := nums[1..2]
 | 
				
			||||||
	nums4 := nums[1..]
 | 
						nums4 := nums[1..]
 | 
				
			||||||
	number := nums[0]
 | 
						number := nums[0]
 | 
				
			||||||
 | 
						nums[1] = 10
 | 
				
			||||||
	bools := [true, false]
 | 
						bools := [true, false]
 | 
				
			||||||
	users := [User{}]
 | 
						users := [User{}]
 | 
				
			||||||
	//ptr := &User{}
 | 
						//ptr := &User{}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue