cgen: fix remaining errors. hello world now compiles

pull/3996/head
Alexander Medvednikov 2020-03-12 09:11:41 +01:00
parent 853bb4c41e
commit 92d6eec09a
6 changed files with 46 additions and 21 deletions

View File

@ -6,7 +6,7 @@ module math
// with the sign bit of f and the result in the same bit position.
// f32_bits(f32_from_bits(x)) == x.
pub fn f32_bits(f f32) u32 {
p := *u32(&f)
p := &u32(&f)
return *p
}
@ -15,7 +15,7 @@ pub fn f32_bits(f f32) u32 {
// and the result in the same bit position.
// f32_from_bits(f32_bits(x)) == x.
pub fn f32_from_bits(b u32) f32 {
p := *f32(&b)
p := &f32(&b)
return *p
}
@ -23,7 +23,7 @@ pub fn f32_from_bits(b u32) f32 {
// with the sign bit of f and the result in the same bit position,
// and f64_bits(f64_from_bits(x)) == x.
pub fn f64_bits(f f64) u64 {
p := *u64(&f)
p := &u64(&f)
return *p
}
@ -32,7 +32,7 @@ pub fn f64_bits(f f64) u64 {
// and the result in the same bit position.
// f64_from_bits(f64_bits(x)) == x.
pub fn f64_from_bits(b u64) f64 {
p := *f64(&b)
p := &f64(&b)
return *p
}

View File

@ -163,6 +163,7 @@ mut:
name string
args []Expr
arg_types []table.Type
expr_types []table.Type
is_c bool
muts []bool
or_block OrExpr
@ -183,6 +184,7 @@ mut:
receiver_type table.Type // User
return_type table.Type
arg_types []table.Type
expr_types []table.Type
}
pub struct Return {

View File

@ -22,7 +22,7 @@ mut:
errors []string
expected_type table.Type
fn_return_type table.Type // current function's return type
// is_amp bool
is_amp bool
}
pub fn new_checker(table &table.Table) Checker {
@ -86,6 +86,9 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type
info := typ_sym.info as table.Struct
if struct_init.fields.len == 0 {
// Short syntax TODO check
if c.is_amp {
return table.type_to_ptr(struct_init.typ)
}
return struct_init.typ
}
if struct_init.exprs.len > info.fields.len {
@ -117,6 +120,10 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type
}
else {}
}
if c.is_amp {
println('XAXAXAX')
return table.type_to_ptr(struct_init.typ)
}
return struct_init.typ
}
@ -239,11 +246,14 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
return f.return_type
}
mut arg_types := []table.Type
mut expr_types := []table.Type
for i, arg_expr in call_expr.args {
arg := if f.is_variadic && i >= f.args.len - 1 { f.args[f.args.len - 1] } else { f.args[i] }
c.expected_type = arg.typ
typ := c.expr(arg_expr)
arg_types << typ
expr_types << typ
// arg_types << typ // arg.typ
arg_types << arg.typ
typ_sym := c.table.get_type_symbol(typ)
arg_typ_sym := c.table.get_type_symbol(arg.typ)
if !c.table.check(typ, arg.typ) {
@ -261,6 +271,7 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
}
}
call_expr.arg_types = arg_types
call_expr.expr_types = expr_types
return f.return_type
}
@ -271,6 +282,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr)
typ_sym := c.table.get_type_symbol(typ)
name := method_call_expr.name
mut arg_types := []table.Type
mut expr_types := []table.Type
// println('method call $name $method_call_expr.pos.line_nr')
if typ_sym.kind == .array && name in ['filter', 'clone', 'repeat'] {
if name == 'filter' {
@ -307,11 +319,12 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr)
for i, arg_expr in method_call_expr.args {
c.expected_type = method.args[i + 1].typ
arg_types << c.expected_type
c.expr(arg_expr)
expr_types << c.expr(arg_expr)
}
method_call_expr.receiver_type = method.args[0].typ
method_call_expr.return_type = method.return_type
method_call_expr.arg_types = arg_types
method_call_expr.expr_types = expr_types
return method.return_type
}
c.error('type `$typ_sym.name` has no method `$name`', method_call_expr.pos)
@ -643,7 +656,12 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
return c.postfix_expr(it)
}
ast.PrefixExpr {
return c.expr(it.right)
if it.op == .amp {
c.is_amp = true
}
res := c.expr(it.right)
c.is_amp = false
return res
}
ast.None {
return table.none_type
@ -888,10 +906,6 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type {
return info.value_type
}
else if typ_sym.kind in [.byteptr, .string] {
// TODO: hack need to handle &a[0] comment to see wyahsh errors
if typ_sym.kind == .byteptr {
return table.type_to_ptr(table.byte_type)
}
return table.byte_type
}
else if table.type_is_ptr(typ) {

View File

@ -67,6 +67,7 @@ pub fn (g &Gen) styp(t string) string {
}
*/
pub fn (g mut Gen) write_typedef_types() {
for typ in g.table.types {
match typ.kind {
@ -95,7 +96,7 @@ pub fn (g mut Gen) write_typedef_types() {
else {
continue
}
}
}
}
}
@ -524,7 +525,7 @@ fn (g mut Gen) expr(node ast.Expr) {
g.write('))')
}
else {
g.call_args(it.args, it.muts, it.arg_types)
g.call_args(it.args, it.muts, it.arg_types, it.expr_types)
g.write(')')
}
g.is_c_call = false
@ -730,8 +731,12 @@ fn (g mut Gen) expr(node ast.Expr) {
if table.type_is_ptr(it.receiver_type) && !table.type_is_ptr(it.expr_type) {
// The receiver is a reference, but the caller provided a value
// Add `&` automatically.
// TODO same logic in call_args()
g.write('&')
}
else if !table.type_is_ptr(it.receiver_type) && table.type_is_ptr(it.expr_type) {
g.write('/*rec*/*')
}
g.expr(it.expr)
if it.args.len > 0 {
g.write(', ')
@ -748,7 +753,7 @@ fn (g mut Gen) expr(node ast.Expr) {
}
*/
// ///////
g.call_args(it.args, it.muts, it.arg_types)
g.call_args(it.args, it.muts, it.arg_types, it.expr_types)
g.write(')')
}
ast.None {
@ -1018,17 +1023,22 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) {
}
}
fn (g mut Gen) call_args(args []ast.Expr, muts []bool, arg_types []table.Type) {
fn (g mut Gen) call_args(args []ast.Expr, muts []bool, arg_types []table.Type, expr_types []table.Type) {
for i, expr in args {
if arg_types.len > 0 {
// typ := arg_types[i]
arg_is_ptr := table.type_is_ptr(arg_types[i])
arg_is_ptr := table.type_is_ptr(arg_types[i]) || arg_types[i] == table.voidptr_type_idx
expr_is_ptr := i < expr_types.len && table.type_is_ptr(expr_types[i])
if muts[i] && !arg_is_ptr {
g.write('&/*mut*/')
}
else if arg_is_ptr {
else if arg_is_ptr && !expr_is_ptr {
g.write('&/*q*/')
}
else if !arg_is_ptr && expr_is_ptr {
// Dereference a pointer if a value is required
g.write('*/*d*/')
}
}
g.expr(expr)
if i != args.len - 1 {

View File

@ -59,7 +59,7 @@ int main() {
println(int_str(localmod__pub_int_const));
int g = ((int)(3.0));
byte* bytes = ((byte*)(0));
User user_ptr = (User*)memdup(&(User){}, sizeof(User));
User* user_ptr = (User*)memdup(&(User){}, sizeof(User));
return 0;
}

View File

@ -32,9 +32,8 @@ pub fn type_nr_muls(t Type) int {
// return true if pointer (nr_muls>0)
[inline]
pub fn type_is_ptr(t Type) bool {
return type_nr_muls(t) > 0
return type_nr_muls(t) > 0 // || t == voidptr_type_idx
}
// set nr_muls on Type and return it
[inline]
pub fn type_set_nr_muls(t Type, nr_muls int) Type {