Ginger Bill 8 年 前
コミット
6d93aa429f
7 ファイル変更148 行追加127 行削除
  1. 82 58
      code/demo.odin
  2. 1 0
      src/check_decl.c
  3. 1 0
      src/check_expr.c
  4. 9 0
      src/check_stmt.c
  5. 2 1
      src/ir.c
  6. 34 33
      src/ir_print.c
  7. 19 35
      src/parser.c

+ 82 - 58
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;
-
-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();
+
+fgetc :: proc(fd : os.Handle) -> ?byte
+{
+	c : [1]byte;
+
+	if bytes_read, _ := os.read(fd, c[:]); bytes_read == 0
+	{
+		return nil;
+	}
+
+	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();
+// }

+ 1 - 0
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;
 	}
 

+ 1 - 0
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);
 		}

+ 9 - 0
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");

+ 2 - 1
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);
 

+ 34 - 33
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, " ");

+ 19 - 35
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");