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

cgen: lots of fixes

This commit is contained in:
Alexander Medvednikov 2020-03-05 00:43:02 +01:00
parent b7e2af8151
commit 4161cfcdb8
9 changed files with 104 additions and 67 deletions

View File

@ -199,6 +199,7 @@ fn (v mut V) cc() {
} }
if debug_mode { if debug_mode {
a << debug_options a << debug_options
a << ' -ferror-limit=5000 '
} }
if v.pref.is_prod { if v.pref.is_prod {
a << optimization_options a << optimization_options

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 {
@ -375,7 +375,8 @@ pub struct ForCStmt {
pub: pub:
init Stmt // i := 0; init Stmt // i := 0;
cond Expr // i < 10; cond Expr // i < 10;
inc Stmt // i++; //inc Stmt // i++;
inc Expr// i++;
stmts []Stmt stmts []Stmt
} }
@ -388,7 +389,7 @@ pub struct ReturnStmt {
// #include etc // #include etc
pub struct HashStmt { pub struct HashStmt {
pub: pub:
name string val string
} }
// filter(), map() // filter(), map()

View File

@ -444,7 +444,8 @@ fn (c mut Checker) stmt(node ast.Stmt) {
ast.ForCStmt { ast.ForCStmt {
c.stmt(it.init) c.stmt(it.init)
c.expr(it.cond) c.expr(it.cond)
c.stmt(it.inc) // c.stmt(it.inc)
c.expr(it.inc)
for stmt in it.stmts { for stmt in it.stmts {
c.stmt(stmt) c.stmt(stmt)
} }

View File

@ -54,7 +54,7 @@ pub fn (g mut Gen) init() {
for i, mr_typ in info.types { for i, mr_typ in info.types {
field_type_sym := g.table.get_type_symbol(mr_typ) field_type_sym := g.table.get_type_symbol(mr_typ)
type_name := field_type_sym.name.replace('.', '__') type_name := field_type_sym.name.replace('.', '__')
g.definitions.writeln('\t$type_name arg_${i+1};') g.definitions.writeln('\t$type_name arg${i};')
} }
g.definitions.writeln('} $name;\n') g.definitions.writeln('} $name;\n')
// g.typedefs.writeln('typedef struct $name $name;') // g.typedefs.writeln('typedef struct $name $name;')
@ -115,11 +115,12 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// TODO // TODO
} }
ast.Attr { ast.Attr {
g.writeln('[$it.name]') g.writeln('//[$it.name]')
} }
ast.BranchStmt { ast.BranchStmt {
// continue or break // continue or break
g.writeln(it.tok.str()) g.write(it.tok.kind.str())
g.writeln(';')
} }
ast.ConstDecl { ast.ConstDecl {
for i, field in it.fields { for i, field in it.fields {
@ -132,10 +133,10 @@ fn (g mut Gen) stmt(node ast.Stmt) {
} }
ast.CompIf { ast.CompIf {
// TODO // TODO
g.write('#ifdef ') g.writeln('//#ifdef ')
g.expr(it.cond) g.expr(it.cond)
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('#endif') g.writeln('//#endif')
} }
ast.DeferStmt { ast.DeferStmt {
g.writeln('// defer') g.writeln('// defer')
@ -218,7 +219,8 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// g.write('; ') // g.write('; ')
g.expr(it.cond) g.expr(it.cond)
g.write('; ') g.write('; ')
g.stmt(it.inc) //g.stmt(it.inc)
g.expr(it.inc)
g.writeln(') {') g.writeln(') {')
for stmt in it.stmts { for stmt in it.stmts {
g.stmt(stmt) g.stmt(stmt)
@ -226,7 +228,16 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.writeln('}') g.writeln('}')
} }
ast.ForInStmt { ast.ForInStmt {
g.writeln('for') if it.is_range {
i := g.new_tmp_var()
g.write('for (int $i = ')
g.expr(it.cond)
g.write('; $i < ')
g.expr(it.high)
g.writeln('; $i++) { ')
// g.stmts(it.stmts) TODO
g.writeln('}')
}
} }
ast.ForStmt { ast.ForStmt {
g.write('while (') g.write('while (')
@ -245,7 +256,8 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.writeln('$it.name:') g.writeln('$it.name:')
} }
ast.HashStmt { ast.HashStmt {
g.writeln('#$it.name') // #include etc
g.writeln('#$it.val')
} }
ast.Import {} ast.Import {}
ast.Return { ast.Return {
@ -303,7 +315,9 @@ fn (g mut Gen) expr(node ast.Expr) {
match node { match node {
ast.ArrayInit { ast.ArrayInit {
type_sym := g.table.get_type_symbol(it.typ) type_sym := g.table.get_type_symbol(it.typ)
g.writeln('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($type_sym.name), {\t') elem_sym := g.table.get_type_symbol(it.elem_type)
g.write('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($type_sym.name), ')
g.writeln('(${elem_sym.name}[]){\t')
for expr in it.exprs { for expr in it.exprs {
g.expr(expr) g.expr(expr)
g.write(', ') g.write(', ')
@ -325,7 +339,11 @@ fn (g mut Gen) expr(node ast.Expr) {
g.write(it.val.str()) g.write(it.val.str())
} }
ast.CallExpr { ast.CallExpr {
name := it.name.replace('.', '__') mut name := it.name.replace('.', '__')
if it.is_c {
// Skip "C__"
name = name[3..]
}
g.write('${name}(') g.write('${name}(')
g.call_args(it.args) g.call_args(it.args)
g.write(')') g.write(')')
@ -367,22 +385,42 @@ fn (g mut Gen) expr(node ast.Expr) {
tmp = g.new_tmp_var() tmp = g.new_tmp_var()
// g.writeln('$ti.name $tmp;') // g.writeln('$ti.name $tmp;')
} }
g.write('if (') // one line ?:
g.expr(it.cond) // TODO clean this up once `is` is supported
g.writeln(') {') if it.stmts.len == 1 && it.else_stmts.len == 1 && type_sym.kind != .void {
for i, stmt in it.stmts { cond := it.cond
// Assign ret value stmt1 := it.stmts[0]
if i == it.stmts.len - 1 && type_sym.kind != .void {} else_stmt1 := it.else_stmts[0]
// g.writeln('$tmp =') match stmt1 {
g.stmt(stmt) ast.ExprStmt {
g.expr(cond)
g.write(' ? ')
expr_stmt := stmt1 as ast.ExprStmt
g.expr(expr_stmt.expr)
g.write(' : ')
g.stmt(else_stmt1)
}
else {}
}
} }
g.writeln('}') else {
if it.else_stmts.len > 0 { g.write('if (')
g.writeln('else { ') g.expr(it.cond)
for stmt in it.else_stmts { g.writeln(') {')
for i, stmt in it.stmts {
// Assign ret value
if i == it.stmts.len - 1 && type_sym.kind != .void {}
// g.writeln('$tmp =')
g.stmt(stmt) g.stmt(stmt)
} }
g.writeln('}') g.writeln('}')
if it.else_stmts.len > 0 {
g.writeln('else { ')
for stmt in it.else_stmts {
g.stmt(stmt)
}
g.writeln('}')
}
} }
} }
ast.IfGuardExpr { ast.IfGuardExpr {

View File

@ -47,23 +47,22 @@ void foo(int a) {
while (true) { while (true) {
} }
for (int i = 0; for (int i = 0;
i < 10; i++; i < 10; i++) {
) {
} }
array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), { array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), (void[]){
1, 2, 3, 1, 2, 3,
}); });
array_int nums2 = array_slice(nums, 0, 2); array_int nums2 = array_slice(nums, 0, 2);
int number = nums[0]; int number = nums[0];
array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), { array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), (void[]){
true, false, true, false,
}); });
array_User users = new_array_from_c_array(1, 1, sizeof(array_User), { array_User users = new_array_from_c_array(1, 1, sizeof(array_User), (void[]){
(User){ (User){
}, },
}); });
bool b = bools[0]; bool b = bools[0];
array_string mystrings = new_array_from_c_array(2, 2, sizeof(array_string), { array_string mystrings = new_array_from_c_array(2, 2, sizeof(array_string), (void[]){
tos3("a"), tos3("b"), tos3("a"), tos3("b"),
}); });
string s = mystrings[0]; string s = mystrings[0];
@ -116,12 +115,7 @@ multi_return_int_string multi_return() {
void variadic(variadic_int a) { void variadic(variadic_int a) {
int x = path_sep; int x = path_sep;
int y = if (true) { int y = true ? 1 : 0;
1;
}
else {
0;
}
; ;
} }

View File

@ -65,8 +65,8 @@ void function2() {
} }
void init_array() { void init_array() {
array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), { array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), (void[]){
1, 2, 3, 4, 2, 3,
}); });
} }

View File

@ -61,7 +61,7 @@ fn function2() {
} }
fn init_array() { fn init_array() {
nums := [1,2,3] nums := [4,2,3]
} }

View File

@ -24,14 +24,14 @@ int main() {
d = tos3("hello"); d = tos3("hello");
string e = tos3("hello"); string e = tos3("hello");
e = testb(111); e = testb(111);
e = tos3("world"); e = tos3("world");
array_int f = new_array_from_c_array(4, 4, sizeof(array_int), { array_int f = new_array_from_c_array(4, 4, sizeof(array_int), (void[]){
testa(), 2, 3, 4, testa(), 2, 3, 4,
}); });
array_string g = new_array_from_c_array(2, 2, sizeof(array_string), { array_string g = new_array_from_c_array(2, 2, sizeof(array_string), (void[]){
testb(1), tos3("hello"), testb(1), tos3("hello"),
}); });
array_Foo arr_foo = new_array_from_c_array(1, 1, sizeof(array_Foo), { array_Foo arr_foo = new_array_from_c_array(1, 1, sizeof(array_Foo), (void[]){
a, a,
}); });
Foo af_idx_el = arr_foo[0]; Foo af_idx_el = arr_foo[0];

View File

@ -58,7 +58,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt {
pref: &pref.Preferences{} pref: &pref.Preferences{}
scope: scope scope: scope
// scope: &ast.Scope{start_pos: 0, parent: 0} // scope: &ast.Scope{start_pos: 0, parent: 0}
} }
p.init_parse_fns() p.init_parse_fns()
p.read_first_token() p.read_first_token()
@ -82,7 +82,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment
parent: 0 parent: 0
} }
// comments_mode: comments_mode // comments_mode: comments_mode
} }
p.read_first_token() p.read_first_token()
// p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0} // p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0}
@ -359,7 +359,7 @@ pub fn (p mut Parser) stmt() ast.Stmt {
return ast.ExprStmt{ return ast.ExprStmt{
expr: expr expr: expr
// typ: typ // typ: typ
} }
} }
} }
@ -662,7 +662,7 @@ pub fn (p mut Parser) name_expr() ast.Expr {
p.expr_mod = '' p.expr_mod = ''
return ast.EnumVal{ return ast.EnumVal{
enum_name: enum_name // lp.prepend_mod(enum_name) enum_name: enum_name // lp.prepend_mod(enum_name)
val: val val: val
pos: p.tok.position() pos: p.tok.position()
} }
@ -1052,7 +1052,8 @@ fn (p mut Parser) for_statement() ast.Stmt {
else if p.peek_tok.kind in [.decl_assign, .assign, .semicolon] || p.tok.kind == .semicolon { else if p.peek_tok.kind in [.decl_assign, .assign, .semicolon] || p.tok.kind == .semicolon {
mut init := ast.Stmt{} mut init := ast.Stmt{}
mut cond := ast.Expr{} mut cond := ast.Expr{}
mut inc := ast.Stmt{} //mut inc := ast.Stmt{}
mut inc := ast.Expr{}
if p.peek_tok.kind in [.assign, .decl_assign] { if p.peek_tok.kind in [.assign, .decl_assign] {
init = p.var_decl_and_assign_stmt() init = p.var_decl_and_assign_stmt()
} }
@ -1074,7 +1075,8 @@ fn (p mut Parser) for_statement() ast.Stmt {
} }
p.check(.semicolon) p.check(.semicolon)
if p.tok.kind != .lcbr { if p.tok.kind != .lcbr {
inc = p.stmt() //inc = p.stmt()
inc,_ = p.expr(0)
} }
stmts := p.parse_block() stmts := p.parse_block()
p.close_scope() p.close_scope()
@ -1236,11 +1238,11 @@ fn (p mut Parser) if_expr() ast.Expr {
stmts: stmts stmts: stmts
else_stmts: else_stmts else_stmts: else_stmts
// typ: typ // typ: typ
pos: pos pos: pos
has_else: has_else has_else: has_else
// left: left // left: left
} }
return node return node
} }
@ -1630,12 +1632,12 @@ fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt {
return ast.VarDecl{ return ast.VarDecl{
name: ident.name name: ident.name
// name2: name2 // name2: name2
expr: expr // p.expr(token.lowest_prec) expr: expr // p.expr(token.lowest_prec)
is_mut: info0.is_mut is_mut: info0.is_mut
// typ: typ // typ: typ
pos: p.tok.position() pos: p.tok.position()
} }
// return p.var_decl(ident[0], exprs[0]) // return p.var_decl(ident[0], exprs[0])
@ -1662,9 +1664,10 @@ fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt {
// pub fn (p mut Parser) assign_stmt() ast.AssignStmt {} // pub fn (p mut Parser) assign_stmt() ast.AssignStmt {}
// fn (p mut Parser) var_decl() ast.VarDecl {} // fn (p mut Parser) var_decl() ast.VarDecl {}
fn (p mut Parser) hash() ast.HashStmt { fn (p mut Parser) hash() ast.HashStmt {
val := p.tok.lit
p.next() p.next()
return ast.HashStmt{ return ast.HashStmt{
name: p.tok.lit val: val
} }
} }
@ -1747,7 +1750,6 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
branches << ast.MatchBranch{ branches << ast.MatchBranch{
exprs: exprs exprs: exprs
stmts: stmts stmts: stmts
} }
p.close_scope() p.close_scope()
if p.tok.kind == .rcbr { if p.tok.kind == .rcbr {