ast: set IndexType.container_type; array_get()

pull/3944/head
Alexander Medvednikov 2020-03-06 17:05:58 +01:00
parent ea2a79ec20
commit 5c8617ec68
5 changed files with 95 additions and 81 deletions

View File

@ -314,7 +314,8 @@ pub:
pos token.Position
left Expr
index Expr // [0], [start..end] etc
// typ table.Type
mut:
container_type table.Type // array, map, fixed array
}
pub struct IfExpr {

View File

@ -566,7 +566,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
return table.bool_type
}
ast.IndexExpr {
return c.index_expr(it)
return c.index_expr(mut it)
}
ast.InfixExpr {
return c.infix_expr(it)
@ -798,7 +798,7 @@ pub fn (c mut Checker) postfix_expr(node ast.PostfixExpr) table.Type {
return typ
}
pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type {
pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type {
typ := c.expr(node.left)
mut is_range := false // TODO is_range := node.index is ast.RangeExpr
match node.index {
@ -808,6 +808,7 @@ pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type {
else {}
}
if !is_range {
node.container_type = typ
typ_sym := c.table.get_type_symbol(typ)
index_type := c.expr(node.index)
index_type_sym := c.table.get_type_symbol(index_type)

View File

@ -173,72 +173,8 @@ fn (g mut Gen) stmt(node ast.Stmt) {
}
}
ast.FnDecl {
if it.is_c || it.name == 'malloc' || it.no_body {
return
}
g.reset_tmp_count()
g.fn_decl = it // &it
is_main := it.name == 'main'
if is_main {
g.write('int ${it.name}(')
}
else {
type_sym := g.table.get_type_symbol(it.typ)
mut name := it.name
if it.is_method {
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
}
name = name.replace('.', '__')
// type_name := g.table.type_to_str(it.typ)
type_name := type_sym.name.replace('.', '__') // g.table.type_to_str(it.typ)
g.write('$type_name ${name}(')
g.definitions.write('$type_name ${name}(')
}
// Receiver is the first argument
if it.is_method {
// styp := g.table.type_to_str(it.receiver.typ)
sym := g.table.get_type_symbol(it.receiver.typ)
styp := sym.name.replace('.', '__')
g.write('$styp $it.receiver.name')
g.definitions.write('$styp $it.receiver.name')
if it.args.len > 0 {
g.write(', ')
g.definitions.write(', ')
}
}
//
no_names := it.args.len > 0 && it.args[0].name == 'arg_1'
for i, arg in it.args {
arg_type_sym := g.table.get_type_symbol(arg.typ)
mut arg_type_name := arg_type_sym.name.replace('.', '__')
if i == it.args.len - 1 && it.is_variadic {
arg_type_name = 'variadic_$arg_type_name'
}
if no_names {
g.write(arg_type_name)
g.definitions.write(arg_type_name)
}
else {
g.write(arg_type_name + ' ' + arg.name)
g.definitions.write(arg_type_name + ' ' + arg.name)
}
if i < it.args.len - 1 {
g.write(', ')
g.definitions.write(', ')
}
}
g.writeln(') { ')
if !is_main {
g.definitions.writeln(');')
}
for stmt in it.stmts {
g.stmt(stmt)
}
if is_main {
g.writeln('return 0;')
}
g.writeln('}')
g.fn_decl = 0
g.gen_fn_decl(it)
}
ast.ForCStmt {
g.write('for (')
@ -338,6 +274,74 @@ fn (g mut Gen) stmt(node ast.Stmt) {
}
}
fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
if it.is_c || it.name == 'malloc' || it.no_body {
return
}
g.reset_tmp_count()
is_main := it.name == 'main'
if is_main {
g.write('int ${it.name}(')
}
else {
type_sym := g.table.get_type_symbol(it.typ)
mut name := it.name
if it.is_method {
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
}
name = name.replace('.', '__')
// type_name := g.table.type_to_str(it.typ)
type_name := type_sym.name.replace('.', '__') // g.table.type_to_str(it.typ)
g.write('$type_name ${name}(')
g.definitions.write('$type_name ${name}(')
}
// Receiver is the first argument
if it.is_method {
// styp := g.table.type_to_str(it.receiver.typ)
sym := g.table.get_type_symbol(it.receiver.typ)
styp := sym.name.replace('.', '__')
g.write('$styp $it.receiver.name')
g.definitions.write('$styp $it.receiver.name')
if it.args.len > 0 {
g.write(', ')
g.definitions.write(', ')
}
}
//
no_names := it.args.len > 0 && it.args[0].name == 'arg_1'
for i, arg in it.args {
arg_type_sym := g.table.get_type_symbol(arg.typ)
mut arg_type_name := arg_type_sym.name.replace('.', '__')
if i == it.args.len - 1 && it.is_variadic {
arg_type_name = 'variadic_$arg_type_name'
}
if no_names {
g.write(arg_type_name)
g.definitions.write(arg_type_name)
}
else {
g.write(arg_type_name + ' ' + arg.name)
g.definitions.write(arg_type_name + ' ' + arg.name)
}
if i < it.args.len - 1 {
g.write(', ')
g.definitions.write(', ')
}
}
g.writeln(') { ')
if !is_main {
g.definitions.writeln(');')
}
for stmt in it.stmts {
g.stmt(stmt)
}
if is_main {
g.writeln('return 0;')
}
g.writeln('}')
g.fn_decl = 0
}
fn (g mut Gen) expr(node ast.Expr) {
// println('cgen expr() line_nr=$node.pos.line_nr')
match node {
@ -596,11 +600,19 @@ fn (g mut Gen) index_expr(node ast.IndexExpr) {
}
else {}
}
if !is_range {
// if !is_range && node.container_type == 0 {
// }
if !is_range && node.container_type != 0 {
sym := g.table.get_type_symbol(node.container_type)
if sym.kind == .array {
g.write('array_get(')
g.expr(node.left)
g.write('[')
g.write(', ')
// g.write('[')
g.expr(node.index)
g.write(']')
g.write(')')
}
// g.write(']')
}
}

View File

@ -66,7 +66,7 @@ i < 10; i++) {
1, 2, 3,
});
array_int nums2 = array_slice(nums, 0, 2);
int number = nums[0];
int number = array_get(nums, 0);
array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), (bool[]){
true, false,
});
@ -74,16 +74,16 @@ i < 10; i++) {
(User){
},
});
bool b = bools[0];
bool b = array_get(bools, 0);
array_string mystrings = new_array_from_c_array(2, 2, sizeof(array_string), (string[]){
tos3("a"), tos3("b"),
});
string s = mystrings[0];
string s = array_get(mystrings, 0);
int x = 0;
x = get_int2();
int n = get_int2();
bool q = true || false;
bool b2 = bools[0] || true;
bool b2 = array_get(bools, 0) || true;
bool b3 = get_bool() || true;
int f = array_int_first(nums);
}

View File

@ -50,7 +50,7 @@ int main() {
array_Foo arr_foo = new_array_from_c_array(1, 1, sizeof(array_Foo), (Foo[]){
a,
});
Foo af_idx_el = arr_foo[0];
Foo af_idx_el = array_get(arr_foo, 0);
string foo_a = af_idx_el.a;
return 0;
}