1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: array_set()

This commit is contained in:
Alexander Medvednikov 2020-03-07 16:39:15 +01:00
parent 63032c4bb7
commit fbf80dc315
5 changed files with 95 additions and 59 deletions

View File

@ -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 {

View File

@ -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)

View File

@ -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(')

View File

@ -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,
}); });

View File

@ -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{}