From 6d93aa429faba96415a7be135eb7296e69fb70a9 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Fri, 20 Jan 2017 00:21:40 +0000 Subject: [PATCH] Fix issue #10 --- code/demo.odin | 134 ++++++++++++++++++++++++++++------------------- src/check_decl.c | 1 + src/check_expr.c | 1 + src/check_stmt.c | 9 ++++ src/ir.c | 3 +- src/ir_print.c | 67 ++++++++++++------------ src/parser.c | 54 +++++++------------ 7 files changed, 145 insertions(+), 124 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index a4081e139..eacc512a2 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,61 +1,85 @@ -#import "atomic.odin"; #import "fmt.odin"; -#import "hash.odin"; -#import "math.odin"; -#import "mem.odin"; -#import "opengl.odin"; #import "os.odin"; -#import win32 "sys/windows.odin"; -#import "sync.odin"; -#import "utf8.odin"; -T :: struct { x, y: int }; -thread_local t: T; +fgetc :: proc(fd : os.Handle) -> ?byte +{ + c : [1]byte; -main :: proc() { - immutable using t := T{123, 321}; - fmt.println(t); + if bytes_read, _ := os.read(fd, c[:]); bytes_read == 0 + { + return nil; + } - - // foo :: proc(x: ^i32) -> (int, int) { - // fmt.println("^int"); - // return 123, int(x^); - // } - // foo :: proc(x: rawptr) { - // fmt.println("rawptr"); - // } - - // THINGI :: 14451; - // THINGF :: 14451.1; - - // a: i32 = 111111; - // b: f32; - // c: rawptr; - // fmt.println(foo(^a)); - // foo(^b); - // foo(c); - // // foo(nil); - // atomic.store(^a, 1); - - // foo :: proc() { - // fmt.printf("Zero args\n"); - // } - // foo :: proc(i: int) { - // fmt.printf("int arg, i=%d\n", i); - // } - // foo :: proc(f: f64) { - // i := int(f); - // fmt.printf("f64 arg, f=%d\n", i); - // } - - // foo(); - // // foo(THINGI); - // foo(THINGF); - // foo(int(THINGI)); - // fmt.println(THINGI); - // fmt.println(THINGF); - - // f: proc(); - // f = foo; - // f(); + return c[0]; } + +main :: proc () +{ + b := fgetc(os.stdin); + + if bv, ok := b?; ok + { + fmt.println(b); + } +} +// #import "atomic.odin"; +// #import "fmt.odin"; +// #import "hash.odin"; +// #import "math.odin"; +// #import "mem.odin"; +// #import "opengl.odin"; +// #import "os.odin"; +// #import win32 "sys/windows.odin"; +// #import "sync.odin"; +// #import "utf8.odin"; + +// T :: struct { x, y: int }; +// thread_local t: T; + +// main :: proc() { +// immutable using t := T{123, 321}; +// fmt.println(t); + + +// // foo :: proc(x: ^i32) -> (int, int) { +// // fmt.println("^int"); +// // return 123, int(x^); +// // } +// // foo :: proc(x: rawptr) { +// // fmt.println("rawptr"); +// // } + +// // THINGI :: 14451; +// // THINGF :: 14451.1; + +// // a: i32 = 111111; +// // b: f32; +// // c: rawptr; +// // fmt.println(foo(^a)); +// // foo(^b); +// // foo(c); +// // // foo(nil); +// // atomic.store(^a, 1); + +// // foo :: proc() { +// // fmt.printf("Zero args\n"); +// // } +// // foo :: proc(i: int) { +// // fmt.printf("int arg, i=%d\n", i); +// // } +// // foo :: proc(f: f64) { +// // i := int(f); +// // fmt.printf("f64 arg, f=%d\n", i); +// // } + +// // foo(); +// // // foo(THINGI); +// // foo(THINGF); +// // foo(int(THINGI)); +// // fmt.println(THINGI); +// // fmt.println(THINGF); + +// // f: proc(); +// // f = foo; +// // f(); +// } diff --git a/src/check_decl.c b/src/check_decl.c index dd112d76c..600b4c0d6 100644 --- a/src/check_decl.c +++ b/src/check_decl.c @@ -40,6 +40,7 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex } t = default_type(t); } + GB_ASSERT(is_type_typed(t)); e->type = t; } diff --git a/src/check_expr.c b/src/check_expr.c index d708b40a4..4b26ca990 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -252,6 +252,7 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n return; } target_type = default_type(operand->type); + GB_ASSERT(is_type_typed(target_type)); add_type_info_type(c, type); add_type_info_type(c, target_type); } diff --git a/src/check_stmt.c b/src/check_stmt.c index 407205df2..1fa16e0ac 100644 --- a/src/check_stmt.c +++ b/src/check_stmt.c @@ -549,8 +549,17 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { if (rs->results.count == 0) { error_node(node, "Expected %td return values, got 0", result_count); } else { + // TokenPos pos = rs->token.pos; + // if (pos.line == 10) { + // gb_printf_err("%s\n", type_to_string(variables[0]->type)); + // } check_init_variables(c, variables, result_count, rs->results, str_lit("return statement")); + // if (pos.line == 10) { + // AstNode *x = rs->results.e[0]; + // gb_printf_err("%s\n", expr_to_string(x)); + // gb_printf_err("%s\n", type_to_string(type_of_expr(&c->info, x))); + // } } } else if (rs->results.count > 0) { error_node(rs->results.e[0], "No return values expected"); diff --git a/src/ir.c b/src/ir.c index 23f84abbe..5b195958f 100644 --- a/src/ir.c +++ b/src/ir.c @@ -4411,7 +4411,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { // No return values } else if (return_count == 1) { Entity *e = return_type_tuple->variables[0]; - v = ir_emit_conv(proc, ir_build_expr(proc, rs->results.e[0]), e->type); + v = ir_build_expr(proc, rs->results.e[0]); + v = ir_emit_conv(proc, v, e->type); } else { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena); diff --git a/src/ir_print.c b/src/ir_print.c index c24ae375a..63da3afe3 100644 --- a/src/ir_print.c +++ b/src/ir_print.c @@ -141,58 +141,59 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { i64 word_bits = 8*s.word_size; GB_ASSERT_NOT_NULL(t); t = default_type(t); + // GB_ASSERT(is_type_typed(t)); switch (t->kind) { case Type_Basic: switch (t->Basic.kind) { - case Basic_bool: ir_fprintf(f, "i1"); break; - case Basic_i8: ir_fprintf(f, "i8"); break; - case Basic_u8: ir_fprintf(f, "i8"); break; - case Basic_i16: ir_fprintf(f, "i16"); break; - case Basic_u16: ir_fprintf(f, "i16"); break; - case Basic_i32: ir_fprintf(f, "i32"); break; - case Basic_u32: ir_fprintf(f, "i32"); break; - case Basic_i64: ir_fprintf(f, "i64"); break; - case Basic_u64: ir_fprintf(f, "i64"); break; - // case Basic_i128: ir_fprintf(f, "i128"); break; - // case Basic_u128: ir_fprintf(f, "i128"); break; - // case Basic_f16: ir_fprintf(f, "half"); break; - case Basic_f32: ir_fprintf(f, "float"); break; - case Basic_f64: ir_fprintf(f, "double"); break; - // case Basic_f128: ir_fprintf(f, "fp128"); break; - case Basic_rawptr: ir_fprintf(f, "%%..rawptr"); break; - case Basic_string: ir_fprintf(f, "%%..string"); break; - case Basic_uint: ir_fprintf(f, "i%lld", word_bits); break; - case Basic_int: ir_fprintf(f, "i%lld", word_bits); break; - case Basic_any: ir_fprintf(f, "%%..any"); break; + case Basic_bool: ir_fprintf(f, "i1"); return; + case Basic_i8: ir_fprintf(f, "i8"); return; + case Basic_u8: ir_fprintf(f, "i8"); return; + case Basic_i16: ir_fprintf(f, "i16"); return; + case Basic_u16: ir_fprintf(f, "i16"); return; + case Basic_i32: ir_fprintf(f, "i32"); return; + case Basic_u32: ir_fprintf(f, "i32"); return; + case Basic_i64: ir_fprintf(f, "i64"); return; + case Basic_u64: ir_fprintf(f, "i64"); return; + // case Basic_i128: ir_fprintf(f, "i128"); return; + // case Basic_u128: ir_fprintf(f, "i128"); return; + // case Basic_f16: ir_fprintf(f, "half"); return; + case Basic_f32: ir_fprintf(f, "float"); return; + case Basic_f64: ir_fprintf(f, "double"); return; + // case Basic_f128: ir_fprintf(f, "fp128"); return; + case Basic_rawptr: ir_fprintf(f, "%%..rawptr"); return; + case Basic_string: ir_fprintf(f, "%%..string"); return; + case Basic_uint: ir_fprintf(f, "i%lld", word_bits); return; + case Basic_int: ir_fprintf(f, "i%lld", word_bits); return; + case Basic_any: ir_fprintf(f, "%%..any"); return; } break; case Type_Pointer: ir_print_type(f, m, t->Pointer.elem); ir_fprintf(f, "*"); - break; + return; case Type_Maybe: ir_fprintf(f, "{"); ir_print_type(f, m, t->Maybe.elem); ir_fprintf(f, ", "); ir_print_type(f, m, t_bool); ir_fprintf(f, "}"); - break; + return; case Type_Array: ir_fprintf(f, "[%lld x ", t->Array.count); ir_print_type(f, m, t->Array.elem); ir_fprintf(f, "]"); - break; + return; case Type_Vector: ir_fprintf(f, "<%lld x ", t->Vector.count); ir_print_type(f, m, t->Vector.elem); ir_fprintf(f, ">"); - break; + return; case Type_Slice: ir_fprintf(f, "{"); ir_print_type(f, m, t->Slice.elem); ir_fprintf(f, "*, i%lld, i%lld}", word_bits, word_bits); - break; + return; case Type_Record: { switch (t->Record.kind) { case TypeRecord_Struct: @@ -210,24 +211,24 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { if (t->Record.struct_is_packed) { ir_fprintf(f, ">"); } - break; + return; case TypeRecord_Union: { // NOTE(bill): The zero size array is used to fix the alignment used in a structure as // LLVM takes the first element's alignment as the entire alignment (like C) i64 size_of_union = type_size_of(s, heap_allocator(), t) - s.word_size; i64 align_of_union = type_align_of(s, heap_allocator(), t); ir_fprintf(f, "{[0 x <%lld x i8>], [%lld x i8], i%lld}", align_of_union, size_of_union, word_bits); - } break; + } return; case TypeRecord_RawUnion: { // NOTE(bill): The zero size array is used to fix the alignment used in a structure as // LLVM takes the first element's alignment as the entire alignment (like C) i64 size_of_union = type_size_of(s, heap_allocator(), t); i64 align_of_union = type_align_of(s, heap_allocator(), t); ir_fprintf(f, "{[0 x <%lld x i8>], [%lld x i8]}", align_of_union, size_of_union); - } break; + } return; case TypeRecord_Enum: ir_print_type(f, m, base_enum_type(t)); - break; + return; } } break; @@ -240,7 +241,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { } else { ir_print_type(f, m, base_type(t)); } - break; + return; case Type_Tuple: if (t->Tuple.variable_count == 1) { ir_print_type(f, m, t->Tuple.variables[0]->type); @@ -254,7 +255,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { } ir_fprintf(f, "}"); } - break; + return; case Type_Proc: { if (t->Proc.result_count == 0) { ir_fprintf(f, "void"); @@ -270,7 +271,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { ir_print_type(f, m, params->variables[i]->type); } ir_fprintf(f, ")*"); - } break; + } return; } } @@ -684,7 +685,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { } break; case irInstr_Store: { - Type *type = ir_type(instr->Store.value); + Type *type = type_deref(ir_type(instr->Store.address)); ir_fprintf(f, "store "); ir_print_type(f, m, type); ir_fprintf(f, " "); diff --git a/src/parser.c b/src/parser.c index 6afc807af..4223c36fe 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1096,6 +1096,7 @@ AstNode *make_import_decl(AstFile *f, Token token, bool is_import, Token relpath bool next_token(AstFile *f) { + Token prev = f->curr_token; if (f->curr_token_index+1 < f->tokens.count) { if (f->curr_token.kind != Token_Comment) { f->prev_token = f->curr_token; @@ -1959,8 +1960,8 @@ AstNode *parse_unary_expr(AstFile *f, bool lhs) { } // NOTE(bill): result == priority -i32 token_precedence(Token t) { - switch (t.kind) { +i32 token_precedence(TokenKind t) { + switch (t) { case Token_CmpOr: return 1; case Token_CmpAnd: @@ -1996,11 +1997,11 @@ i32 token_precedence(Token t) { AstNode *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { AstNode *expression = parse_unary_expr(f, lhs); - for (i32 prec = token_precedence(f->curr_token); prec >= prec_in; prec--) { + for (i32 prec = token_precedence(f->curr_token.kind); prec >= prec_in; prec--) { for (;;) { AstNode *right; Token op = f->curr_token; - i32 op_prec = token_precedence(op); + i32 op_prec = token_precedence(op.kind); if (op_prec != prec) { break; } @@ -2293,35 +2294,22 @@ AstNode *parse_var_type(AstFile *f, bool allow_ellipsis) { u32 parse_field_prefixes(AstFile *f) { - i32 using_count = 0; - i32 no_alias_count = 0; + i32 using_count = 0; + i32 no_alias_count = 0; i32 immutable_count = 0; - while (f->curr_token.kind == Token_using || - f->curr_token.kind == Token_no_alias || - f->curr_token.kind == Token_immutable) { - if (allow_token(f, Token_using)) { - using_count += 1; - } - if (allow_token(f, Token_no_alias)) { - no_alias_count += 1; - } - if (allow_token(f, Token_immutable)) { - immutable_count += 1; + bool loop = true; + while (loop) { + switch (f->curr_token.kind) { + default: loop = false; break; + case Token_using: using_count += 1; next_token(f); break; + case Token_no_alias: no_alias_count += 1; next_token(f); break; + case Token_immutable: immutable_count += 1; next_token(f); break; } } - if (using_count > 1) { - syntax_error(f->curr_token, "Multiple `using` in this field list"); - using_count = 1; - } - if (no_alias_count > 1) { - syntax_error(f->curr_token, "Multiple `no_alias` in this field list"); - no_alias_count = 1; - } - if (immutable_count > 1) { - syntax_error(f->curr_token, "Multiple `immutable` in this field list"); - immutable_count = 1; - } + if (using_count > 1) syntax_error(f->curr_token, "Multiple `using` in this field list"); + if (no_alias_count > 1) syntax_error(f->curr_token, "Multiple `no_alias` in this field list"); + if (immutable_count > 1) syntax_error(f->curr_token, "Multiple `immutable` in this field list"); u32 field_flags = 0; @@ -3095,16 +3083,14 @@ AstNode *parse_stmt(AstFile *f) { case AstNode_ValueDecl: if (!node->ValueDecl.is_var) { syntax_error(token, "`using` may not be applied to constant declarations"); - return make_bad_stmt(f, token, f->curr_token); } else { if (f->curr_proc == NULL) { syntax_error(token, "`using` is not allowed at the file scope"); } else { node->ValueDecl.flags |= VarDeclFlag_using; } - return node; } - break; + return node; case AstNode_ExprStmt: { AstNode *e = unparen_expr(node->ExprStmt.expr); while (e->kind == AstNode_SelectorExpr) { @@ -3127,11 +3113,10 @@ AstNode *parse_stmt(AstFile *f) { if (node->kind == AstNode_ValueDecl) { if (!node->ValueDecl.is_var) { syntax_error(token, "`immutable` may not be applied to constant declarations"); - return make_bad_stmt(f, token, f->curr_token); } else { node->ValueDecl.flags |= VarDeclFlag_immutable; - return node; } + return node; } syntax_error(token, "`immutable` may only be applied to a variable declaration"); return make_bad_stmt(f, token, f->curr_token); @@ -3144,7 +3129,6 @@ AstNode *parse_stmt(AstFile *f) { if (node->kind == AstNode_ValueDecl) { if (!node->ValueDecl.is_var) { syntax_error(token, "`thread_local` may not be applied to constant declarations"); - return make_bad_stmt(f, token, f->curr_token); } if (f->curr_proc != NULL) { syntax_error(token, "`thread_local` is only allowed at the file scope");