authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-16 00:07:20-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-16 00:07:34-07:00
log5f7685336f2b0bd5e14765d885b0cf87ebe1f578
tree84218637c6dcf91efde85759c5f4f0efdf6af2ed
parentca8d8f114f0db4f3ed51c410c0e9f93aaf03e14d

better main symbol prototype

closes #64

8 files changed, 242 insertions(+), 166 deletions(-)

example/cat/main.zig+1-1
......@@ -1,6 +1,6 @@
11export executable "cat";
22
3pub main(argv: [][]u8) -> i32 {
3pub fn main(argv: [][]u8) i32 => {
44
55
66 return 0;
example/guess_number/main.zig+1-1
......@@ -3,7 +3,7 @@ export executable "guess_number";
33import "std.zig";
44import "rand.zig";
55
6pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
6pub fn main(args: [][]u8) i32 => {
77 print_str("Welcome to the Guess Number Game in Zig.\n");
88
99 var seed : u32;
example/hello_world/hello.zig+1-1
......@@ -2,7 +2,7 @@ export executable "hello";
22
33import "std.zig";
44
5pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
5pub fn main(args: [][]u8) i32 => {
66 print_str("Hello, world!\n");
77 return 0;
88}
example/multiple_files/main.zig+1-1
......@@ -3,7 +3,7 @@ export executable "test-multiple-files";
33import "std.zig";
44import "foo.zig";
55
6pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
6pub fn main(args: [][]u8) i32 => {
77 private_function();
88 print_str("OK 2\n");
99 return 0;
src/analyze.cpp+35-86
......@@ -64,7 +64,7 @@ static AstNode *first_executing_node(AstNode *node) {
6464 case NodeTypeArrayType:
6565 return node;
6666 }
67 zig_panic("unreachable");
67 zig_unreachable();
6868}
6969
7070void add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
......@@ -81,29 +81,6 @@ void add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
8181 g->errors.append(err);
8282}
8383
84static int parse_version_string(Buf *buf, int *major, int *minor, int *patch) {
85 char *dot1 = strstr(buf_ptr(buf), ".");
86 if (!dot1)
87 return ErrorInvalidFormat;
88 char *dot2 = strstr(dot1 + 1, ".");
89 if (!dot2)
90 return ErrorInvalidFormat;
91
92 *major = (int)strtol(buf_ptr(buf), nullptr, 10);
93 *minor = (int)strtol(dot1 + 1, nullptr, 10);
94 *patch = (int)strtol(dot2 + 1, nullptr, 10);
95
96 return ErrorNone;
97}
98
99static void set_root_export_version(CodeGen *g, Buf *version_buf, AstNode *node) {
100 int err;
101 if ((err = parse_version_string(version_buf, &g->version_major, &g->version_minor, &g->version_patch))) {
102 add_node_error(g, node,
103 buf_sprintf("invalid version string"));
104 }
105}
106
10784TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
10885 TypeTableEntry *entry = allocate<TypeTableEntry>(1);
10986 entry->arrays_by_size.init(2);
......@@ -258,9 +235,7 @@ static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, ui
258235 }
259236}
260237
261static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, ImportTableEntry *import,
262 TypeTableEntry *child_type, bool is_const)
263{
238static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
264239 assert(child_type->id != TypeTableEntryIdInvalid);
265240 TypeTableEntry **parent_pointer = &child_type->unknown_size_array_parent[(is_const ? 1 : 0)];
266241 if (*parent_pointer) {
......@@ -268,8 +243,9 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, ImportTableEntry
268243 } else {
269244 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
270245
246 const char *const_str = is_const ? "const " : "";
271247 buf_resize(&entry->name, 0);
272 buf_appendf(&entry->name, "[]%s", buf_ptr(&child_type->name));
248 buf_appendf(&entry->name, "[]%s%s", const_str, buf_ptr(&child_type->name));
273249 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&entry->name));
274250
275251 TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const);
......@@ -818,47 +794,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
818794 preview_fn_proto(g, import, node);
819795 break;
820796 case NodeTypeRootExportDecl:
821 if (import == g->root_import) {
822 for (int i = 0; i < node->data.root_export_decl.directives->length; i += 1) {
823 AstNode *directive_node = node->data.root_export_decl.directives->at(i);
824 Buf *name = &directive_node->data.directive.name;
825 Buf *param = &directive_node->data.directive.param;
826 if (buf_eql_str(name, "version")) {
827 set_root_export_version(g, param, directive_node);
828 } else {
829 add_node_error(g, directive_node,
830 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
831 }
832 }
833
834 if (g->root_export_decl) {
835 add_node_error(g, node,
836 buf_sprintf("only one root export declaration allowed"));
837 } else {
838 g->root_export_decl = node;
839
840 if (!g->root_out_name)
841 g->root_out_name = &node->data.root_export_decl.name;
842
843 Buf *out_type = &node->data.root_export_decl.type;
844 OutType export_out_type;
845 if (buf_eql_str(out_type, "executable")) {
846 export_out_type = OutTypeExe;
847 } else if (buf_eql_str(out_type, "library")) {
848 export_out_type = OutTypeLib;
849 } else if (buf_eql_str(out_type, "object")) {
850 export_out_type = OutTypeObj;
851 } else {
852 add_node_error(g, node,
853 buf_sprintf("invalid export type: '%s'", buf_ptr(out_type)));
854 }
855 if (g->out_type == OutTypeUnknown)
856 g->out_type = export_out_type;
857 }
858 } else {
859 add_node_error(g, node,
860 buf_sprintf("root export declaration only valid in root source file"));
861 }
797 // handled earlier
862798 break;
863799 case NodeTypeStructDecl:
864800 {
......@@ -1126,7 +1062,7 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
11261062 if (expected_type->id == TypeTableEntryIdInt &&
11271063 actual_type->id == TypeTableEntryIdInt &&
11281064 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
1129 expected_type->size_in_bits > actual_type->size_in_bits)
1065 expected_type->size_in_bits >= actual_type->size_in_bits)
11301066 {
11311067 Expr *expr = get_resolved_expr(node);
11321068 expr->implicit_cast.after_type = expected_type;
......@@ -1149,7 +1085,7 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
11491085 return expected_type;
11501086 }
11511087
1152 // implicit non-const to const and ignore noalias
1088 // implicit non-const to const for pointers
11531089 if (expected_type->id == TypeTableEntryIdPointer &&
11541090 actual_type->id == TypeTableEntryIdPointer &&
11551091 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const))
......@@ -1163,6 +1099,23 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
11631099 return expected_type;
11641100 }
11651101
1102 // implicit non-const to const for unknown size arrays
1103 if (expected_type->id == TypeTableEntryIdStruct &&
1104 actual_type->id == TypeTableEntryIdStruct &&
1105 expected_type->data.structure.is_unknown_size_array &&
1106 actual_type->data.structure.is_unknown_size_array &&
1107 (!actual_type->data.structure.fields[0].type_entry->data.pointer.is_const ||
1108 expected_type->data.structure.fields[0].type_entry->data.pointer.is_const))
1109 {
1110 TypeTableEntry *resolved_type = resolve_type_compatibility(g, context, node,
1111 expected_type->data.structure.fields[0].type_entry->data.pointer.child_type,
1112 actual_type->data.structure.fields[0].type_entry->data.pointer.child_type);
1113 if (resolved_type->id == TypeTableEntryIdInvalid) {
1114 return resolved_type;
1115 }
1116 return expected_type;
1117 }
1118
11661119 add_node_error(g, first_executing_node(node),
11671120 buf_sprintf("expected type '%s', got '%s'",
11681121 buf_ptr(&expected_type->name),
......@@ -1511,15 +1464,15 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,
15111464 if (array_type->id == TypeTableEntryIdInvalid) {
15121465 return_type = g->builtin_types.entry_invalid;
15131466 } else if (array_type->id == TypeTableEntryIdArray) {
1514 return_type = get_unknown_size_array_type(g, import, array_type->data.array.child_type,
1467 return_type = get_unknown_size_array_type(g, array_type->data.array.child_type,
15151468 node->data.slice_expr.is_const);
15161469 } else if (array_type->id == TypeTableEntryIdPointer) {
1517 return_type = get_unknown_size_array_type(g, import, array_type->data.pointer.child_type,
1470 return_type = get_unknown_size_array_type(g, array_type->data.pointer.child_type,
15181471 node->data.slice_expr.is_const);
15191472 } else if (array_type->id == TypeTableEntryIdStruct &&
15201473 array_type->data.structure.is_unknown_size_array)
15211474 {
1522 return_type = get_unknown_size_array_type(g, import,
1475 return_type = get_unknown_size_array_type(g,
15231476 array_type->data.structure.fields[0].type_entry->data.pointer.child_type,
15241477 node->data.slice_expr.is_const);
15251478 } else {
......@@ -2045,6 +1998,11 @@ static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTa
20451998 add_node_error(g, source_node,
20461999 buf_sprintf("unable to infer variable type"));
20472000 implicit_type = g->builtin_types.entry_invalid;
2001 } else if (implicit_type->id == TypeTableEntryIdMetaType &&
2002 !variable_declaration->is_const)
2003 {
2004 add_node_error(g, source_node, buf_sprintf("variable of type 'type' must be constant"));
2005 implicit_type = g->builtin_types.entry_invalid;
20482006 }
20492007 }
20502008
......@@ -2175,12 +2133,12 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
21752133 return resolve_expr_const_val_as_type(g, node,
21762134 get_array_type(g, child_type, const_val->data.x_uint));
21772135 } else {
2178 add_node_error(g, size_node, buf_create_from_str("unable to resolve constant expression"));
2179 return g->builtin_types.entry_invalid;
2136 return resolve_expr_const_val_as_type(g, node,
2137 get_unknown_size_array_type(g, child_type, node->data.array_type.is_const));
21802138 }
21812139 } else {
21822140 return resolve_expr_const_val_as_type(g, node,
2183 get_unknown_size_array_type(g, import, child_type, node->data.array_type.is_const));
2141 get_unknown_size_array_type(g, child_type, node->data.array_type.is_const));
21842142 }
21852143}
21862144
......@@ -2587,7 +2545,6 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
25872545 return resolve_expr_const_val_as_type(g, node, type_entry);
25882546 }
25892547 }
2590
25912548 }
25922549 zig_unreachable();
25932550}
......@@ -3677,14 +3634,6 @@ void semantic_analyze(CodeGen *g) {
36773634 analyze_top_level_decls_root(g, import, import->root);
36783635 }
36793636 }
3680
3681 if (!g->root_out_name) {
3682 add_node_error(g, g->root_import->root,
3683 buf_sprintf("missing export declaration and output name not provided"));
3684 } else if (g->out_type == OutTypeUnknown) {
3685 add_node_error(g, g->root_import->root,
3686 buf_sprintf("missing export declaration and export type not provided"));
3687 }
36883637}
36893638
36903639Expr *get_resolved_expr(AstNode *node) {
src/codegen.cpp+145-21
......@@ -636,7 +636,19 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
636636
637637 return tmp_struct_ptr;
638638 } else if (array_type->id == TypeTableEntryIdPointer) {
639 zig_panic("TODO gen_slice_expr pointer");
639 LLVMValueRef start_val = gen_expr(g, node->data.slice_expr.start);
640 LLVMValueRef end_val = gen_expr(g, node->data.slice_expr.end);
641
642 add_debug_source_node(g, node);
643 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, "");
644 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
645 LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr);
646
647 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, "");
648 LLVMValueRef len_value = LLVMBuildSub(g->builder, end_val, start_val, "");
649 LLVMBuildStore(g->builder, len_value, len_field_ptr);
650
651 return tmp_struct_ptr;
640652 } else if (array_type->id == TypeTableEntryIdStruct) {
641653 assert(array_type->data.structure.is_unknown_size_array);
642654 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
......@@ -1767,25 +1779,62 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
17671779 }
17681780 gen_assign_raw(g, var_decl->expr, BinOpTypeAssign, variable->value_ref,
17691781 value, variable->type, expr_type);
1770 } else if (g->build_type != CodeGenBuildTypeRelease) {
1771 // memset uninitialized memory to 0xa
1772 add_debug_source_node(g, source_node);
1773 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
1774 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
1775 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");
1776 LLVMValueRef byte_count = LLVMConstInt(LLVMIntType(g->pointer_size_bytes * 8),
1777 variable->type->size_in_bits / 8, false);
1778 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(),
1779 variable->type->align_in_bits / 8, false);
1780 LLVMValueRef params[] = {
1781 dest_ptr,
1782 fill_char,
1783 byte_count,
1784 align_in_bytes,
1785 LLVMConstNull(LLVMInt1Type()), // is volatile
1786 };
1782 } else {
1783 bool ignore_uninit = false;
1784 TypeTableEntry *var_type = get_type_for_type_node(var_decl->type);
1785 if (var_type->id == TypeTableEntryIdStruct &&
1786 var_type->data.structure.is_unknown_size_array)
1787 {
1788 assert(var_decl->type->type == NodeTypeArrayType);
1789 AstNode *size_node = var_decl->type->data.array_type.size;
1790 if (size_node) {
1791 ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;
1792 if (!const_val->ok) {
1793 TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry;
1794 assert(ptr_type->id == TypeTableEntryIdPointer);
1795 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
1796
1797 LLVMValueRef size_val = gen_expr(g, size_node);
1798
1799 add_debug_source_node(g, source_node);
1800 LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref,
1801 size_val, "");
1802
1803 // store the freshly allocated pointer in the unknown size array struct
1804 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder,
1805 variable->value_ref, 0, "");
1806 LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr);
1807
1808 // store the size in the len field
1809 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder,
1810 variable->value_ref, 1, "");
1811 LLVMBuildStore(g->builder, size_val, len_field_ptr);
1812
1813 // don't clobber what we just did with debug initialization
1814 ignore_uninit = true;
1815 }
1816 }
1817 }
1818 if (!ignore_uninit && g->build_type != CodeGenBuildTypeRelease) {
1819 // memset uninitialized memory to 0xa
1820 add_debug_source_node(g, source_node);
1821 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
1822 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
1823 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");
1824 LLVMValueRef byte_count = LLVMConstInt(LLVMIntType(g->pointer_size_bytes * 8),
1825 variable->type->size_in_bits / 8, false);
1826 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(),
1827 variable->type->align_in_bits / 8, false);
1828 LLVMValueRef params[] = {
1829 dest_ptr,
1830 fill_char,
1831 byte_count,
1832 align_in_bytes,
1833 LLVMConstNull(LLVMInt1Type()), // is volatile
1834 };
17871835
1788 LLVMBuildCall(g->builder, g->memset_fn_val, params, 5, "");
1836 LLVMBuildCall(g->builder, g->memset_fn_val, params, 5, "");
1837 }
17891838 }
17901839
17911840 LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(source_node->line + 1, source_node->column + 1,
......@@ -2592,6 +2641,30 @@ static bool directives_contains_link_libc(ZigList<AstNode*> *directives) {
25922641 return false;
25932642}
25942643
2644static int parse_version_string(Buf *buf, int *major, int *minor, int *patch) {
2645 char *dot1 = strstr(buf_ptr(buf), ".");
2646 if (!dot1)
2647 return ErrorInvalidFormat;
2648 char *dot2 = strstr(dot1 + 1, ".");
2649 if (!dot2)
2650 return ErrorInvalidFormat;
2651
2652 *major = (int)strtol(buf_ptr(buf), nullptr, 10);
2653 *minor = (int)strtol(dot1 + 1, nullptr, 10);
2654 *patch = (int)strtol(dot2 + 1, nullptr, 10);
2655
2656 return ErrorNone;
2657}
2658
2659static void set_root_export_version(CodeGen *g, Buf *version_buf, AstNode *node) {
2660 int err;
2661 if ((err = parse_version_string(version_buf, &g->version_major, &g->version_minor, &g->version_patch))) {
2662 add_node_error(g, node,
2663 buf_sprintf("invalid version string"));
2664 }
2665}
2666
2667
25952668static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
25962669 Buf *src_dirname, Buf *src_basename, Buf *source_code)
25972670{
......@@ -2657,7 +2730,50 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
26572730 for (int decl_i = 0; decl_i < import_entry->root->data.root.top_level_decls.length; decl_i += 1) {
26582731 AstNode *top_level_decl = import_entry->root->data.root.top_level_decls.at(decl_i);
26592732
2660 if (top_level_decl->type == NodeTypeUse) {
2733 if (top_level_decl->type == NodeTypeRootExportDecl) {
2734 if (g->root_import) {
2735 add_node_error(g, top_level_decl,
2736 buf_sprintf("root export declaration only valid in root source file"));
2737 } else {
2738 for (int i = 0; i < top_level_decl->data.root_export_decl.directives->length; i += 1) {
2739 AstNode *directive_node = top_level_decl->data.root_export_decl.directives->at(i);
2740 Buf *name = &directive_node->data.directive.name;
2741 Buf *param = &directive_node->data.directive.param;
2742 if (buf_eql_str(name, "version")) {
2743 set_root_export_version(g, param, directive_node);
2744 } else {
2745 add_node_error(g, directive_node,
2746 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
2747 }
2748 }
2749
2750 if (g->root_export_decl) {
2751 add_node_error(g, top_level_decl,
2752 buf_sprintf("only one root export declaration allowed"));
2753 } else {
2754 g->root_export_decl = top_level_decl;
2755
2756 if (!g->root_out_name)
2757 g->root_out_name = &top_level_decl->data.root_export_decl.name;
2758
2759 Buf *out_type = &top_level_decl->data.root_export_decl.type;
2760 OutType export_out_type;
2761 if (buf_eql_str(out_type, "executable")) {
2762 export_out_type = OutTypeExe;
2763 } else if (buf_eql_str(out_type, "library")) {
2764 export_out_type = OutTypeLib;
2765 } else if (buf_eql_str(out_type, "object")) {
2766 export_out_type = OutTypeObj;
2767 } else {
2768 add_node_error(g, top_level_decl,
2769 buf_sprintf("invalid export type: '%s'", buf_ptr(out_type)));
2770 }
2771 if (g->out_type == OutTypeUnknown) {
2772 g->out_type = export_out_type;
2773 }
2774 }
2775 }
2776 } else if (top_level_decl->type == NodeTypeUse) {
26612777 Buf *import_target_path = &top_level_decl->data.use.path;
26622778 Buf full_path = BUF_INIT;
26632779 Buf *import_code = buf_alloc();
......@@ -2756,8 +2872,16 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
27562872
27572873 g->root_import = codegen_add_code(g, abs_full_path, src_dir, src_basename, source_code);
27582874
2875 if (!g->root_out_name) {
2876 add_node_error(g, g->root_import->root,
2877 buf_sprintf("missing export declaration and output name not provided"));
2878 } else if (g->out_type == OutTypeUnknown) {
2879 add_node_error(g, g->root_import->root,
2880 buf_sprintf("missing export declaration and export type not provided"));
2881 }
2882
27592883 if (!g->link_libc) {
2760 if (g->have_exported_main && g->out_type != OutTypeLib) {
2884 if (g->have_exported_main && (g->out_type == OutTypeObj || g->out_type == OutTypeExe)) {
27612885 g->bootstrap_import = add_special_code(g, "bootstrap.zig");
27622886 }
27632887
std/bootstrap.zig+15-16
......@@ -3,18 +3,28 @@ import "syscall.zig";
33// The compiler treats this file special by implicitly importing the function `main`
44// from the root source file.
55
6var argc: usize;
7var argv: &&u8;
68var env: &&u8;
79
810#attribute("naked")
911export fn _start() unreachable => {
10 const argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> isize));
11 const argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8));
12 argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> usize));
13 argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8));
1214 env = asm("lea 0x10(%%rsp,%%rdi,8), %[env]": [env] "=r" (-> &&u8));
15 call_main()
16}
1317
14 exit(main(argc, argv, env));
18fn strlen(ptr: &u8) usize => {
19 var count: usize = 0;
20 while (ptr[count] != 0) {
21 count += 1;
22 }
23 return count;
24}
1525
16/*
17 var args = @alloca_array([]u8, argc);
26fn call_main() unreachable => {
27 var args: [argc][]u8;
1828 var i : @typeof(argc) = 0;
1929 // TODO for in loop over the array
2030 while (i < argc) {
......@@ -23,15 +33,4 @@ export fn _start() unreachable => {
2333 i += 1;
2434 }
2535 exit(main(args))
26 */
27}
28
29/*
30fn strlen(ptr: &u8) isize => {
31 var count: isize = 0;
32 while (ptr[count]) {
33 count += 1;
34 }
35 return count;
3636}
37*/
test/run_tests.cpp+43-39
......@@ -101,7 +101,7 @@ extern {
101101 fn puts(s: &const u8) i32;
102102}
103103
104export fn main(argc: i32, argv: &&u8, env: &&u8) i32 => {
104export fn main(argc: i32, argv: &&u8) i32 => {
105105 puts(c"Hello, world!");
106106 return 0;
107107}
......@@ -114,7 +114,7 @@ import "syscall.zig";
114114fn empty_function_1() => {}
115115fn empty_function_2() => { return; }
116116
117pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
117pub fn main(args: [][]u8) i32 => {
118118 empty_function_1();
119119 empty_function_2();
120120 this_is_a_function();
......@@ -136,7 +136,7 @@ fn another_function() => {}
136136
137137/// this is a documentation comment
138138/// doc comment line 2
139pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
139pub fn main(args: [][]u8) i32 => {
140140 print_str(/* mid-line comment /* nested */ */ "OK\n");
141141 return 0;
142142}
......@@ -147,7 +147,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
147147import "std.zig";
148148import "foo.zig";
149149
150pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
150pub fn main(args: [][]u8) i32 => {
151151 private_function();
152152 print_str("OK 2\n");
153153 return 0;
......@@ -178,7 +178,7 @@ pub fn print_text() => {
178178import "foo.zig";
179179import "bar.zig";
180180
181pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
181pub fn main(args: [][]u8) i32 => {
182182 foo_function();
183183 bar_function();
184184 return 0;
......@@ -214,7 +214,7 @@ pub fn foo_function() bool => {
214214 add_simple_case("if statements", R"SOURCE(
215215import "std.zig";
216216
217pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
217pub fn main(args: [][]u8) i32 => {
218218 if (1 != 0) {
219219 print_str("1 is true\n");
220220 } else {
......@@ -239,7 +239,7 @@ fn add(a: i32, b: i32) i32 => {
239239 a + b
240240}
241241
242pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
242pub fn main(args: [][]u8) i32 => {
243243 if (add(22, 11) == 33) {
244244 print_str("pass\n");
245245 }
......@@ -261,7 +261,7 @@ done:
261261 return;
262262}
263263
264pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
264pub fn main(args: [][]u8) i32 => {
265265 loop(3);
266266 return 0;
267267}
......@@ -270,7 +270,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
270270 add_simple_case("local variables", R"SOURCE(
271271import "std.zig";
272272
273pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
273pub fn main(args: [][]u8) i32 => {
274274 const a : i32 = 1;
275275 const b = i32(2);
276276 if (a + b == 3) {
......@@ -283,7 +283,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
283283 add_simple_case("bool literals", R"SOURCE(
284284import "std.zig";
285285
286pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
286pub fn main(args: [][]u8) i32 => {
287287 if (true) { print_str("OK 1\n"); }
288288 if (false) { print_str("BAD 1\n"); }
289289 if (!true) { print_str("BAD 2\n"); }
......@@ -295,7 +295,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
295295 add_simple_case("separate block scopes", R"SOURCE(
296296import "std.zig";
297297
298pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
298pub fn main(args: [][]u8) i32 => {
299299 if (true) {
300300 const no_conflict : i32 = 5;
301301 if (no_conflict == 5) { print_str("OK 1\n"); }
......@@ -313,7 +313,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
313313 add_simple_case("void parameters", R"SOURCE(
314314import "std.zig";
315315
316pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
316pub fn main(args: [][]u8) i32 => {
317317 void_fun(1, void{}, 2);
318318 return 0;
319319}
......@@ -333,7 +333,7 @@ struct Foo {
333333 b : i32,
334334 c : void,
335335}
336pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
336pub fn main(args: [][]u8) i32 => {
337337 const foo = Foo {
338338 .a = void{},
339339 .b = 1,
......@@ -354,7 +354,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
354354 add_simple_case("void arrays", R"SOURCE(
355355import "std.zig";
356356
357pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
357pub fn main(args: [][]u8) i32 => {
358358 var array: [4]void;
359359 array[0] = void{};
360360 array[1] = array[2];
......@@ -373,7 +373,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
373373 add_simple_case("mutable local variables", R"SOURCE(
374374import "std.zig";
375375
376pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
376pub fn main(args: [][]u8) i32 => {
377377 var zero : i32 = 0;
378378 if (zero == 0) { print_str("zero\n"); }
379379
......@@ -393,7 +393,7 @@ done:
393393 add_simple_case("arrays", R"SOURCE(
394394import "std.zig";
395395
396pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
396pub fn main(args: [][]u8) i32 => {
397397 var array : [5]u32;
398398
399399 var i : u32 = 0;
......@@ -429,7 +429,7 @@ fn get_array_len(a: []u32) usize => {
429429 add_simple_case("hello world without libc", R"SOURCE(
430430import "std.zig";
431431
432pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
432pub fn main(args: [][]u8) i32 => {
433433 print_str("Hello, world!\n");
434434 return 0;
435435}
......@@ -439,7 +439,7 @@ pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
439439 add_simple_case("a + b + c", R"SOURCE(
440440import "std.zig";
441441
442pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
442pub fn main(args: [][]u8) i32 => {
443443 if (false || false || false) { print_str("BAD 1\n"); }
444444 if (true && true && false) { print_str("BAD 2\n"); }
445445 if (1 | 2 | 4 != 7) { print_str("BAD 3\n"); }
......@@ -461,7 +461,7 @@ pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
461461 add_simple_case("short circuit", R"SOURCE(
462462import "std.zig";
463463
464pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
464pub fn main(args: [][]u8) i32 => {
465465 if (true || { print_str("BAD 1\n"); false }) {
466466 print_str("OK 1\n");
467467 }
......@@ -484,7 +484,7 @@ pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
484484 add_simple_case("modify operators", R"SOURCE(
485485import "std.zig";
486486
487pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
487pub fn main(args: [][]u8) i32 => {
488488 var i : i32 = 0;
489489 i += 5; if (i != 5) { print_str("BAD +=\n"); }
490490 i -= 2; if (i != 3) { print_str("BAD -=\n"); }
......@@ -510,7 +510,7 @@ extern {
510510 fn printf(__format: &const u8, ...) i32;
511511}
512512
513export fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
513export fn main(argc: i32, argv: &&u8) i32 => {
514514 printf(c"\n");
515515
516516 printf(c"0: %llu\n",
......@@ -636,7 +636,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
636636 add_simple_case("structs", R"SOURCE(
637637import "std.zig";
638638
639pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
639pub fn main(args: [][]u8) i32 => {
640640 var foo : Foo;
641641 @memset(&foo, 0, @sizeof(Foo));
642642 foo.a += 1;
......@@ -711,7 +711,7 @@ import "std.zig";
711711const g1 : i32 = 1233 + 1;
712712var g2 : i32 = 0;
713713
714pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
714pub fn main(args: [][]u8) i32 => {
715715 if (g2 != 0) { print_str("BAD\n"); }
716716 g2 = g1;
717717 if (g2 != 1234) { print_str("BAD\n"); }
......@@ -722,7 +722,7 @@ pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
722722
723723 add_simple_case("while loop", R"SOURCE(
724724import "std.zig";
725pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
725pub fn main(args: [][]u8) i32 => {
726726 var i : i32 = 0;
727727 while (i < 4) {
728728 print_str("loop\n");
......@@ -739,7 +739,7 @@ fn f() i32 => {
739739
740740 add_simple_case("continue and break", R"SOURCE(
741741import "std.zig";
742pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
742pub fn main(args: [][]u8) i32 => {
743743 var i : i32 = 0;
744744 while (true) {
745745 print_str("loop\n");
......@@ -755,7 +755,7 @@ pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
755755
756756 add_simple_case("maybe type", R"SOURCE(
757757import "std.zig";
758pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
758pub fn main(args: [][]u8) i32 => {
759759 const x : ?bool = true;
760760
761761 if (const y ?= x) {
......@@ -790,7 +790,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
790790
791791 add_simple_case("implicit cast after unreachable", R"SOURCE(
792792import "std.zig";
793pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
793pub fn main(args: [][]u8) i32 => {
794794 const x = outer();
795795 if (x == 1234) {
796796 print_str("OK\n");
......@@ -807,7 +807,7 @@ fn outer() isize => {
807807import "std.zig";
808808const x: u16 = 13;
809809const z: @typeof(x) = 19;
810pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
810pub fn main(args: [][]u8) i32 => {
811811 const y: @typeof(x) = 120;
812812 print_u64(@sizeof(@typeof(y)));
813813 print_str("\n");
......@@ -823,7 +823,7 @@ struct Rand {
823823 r.seed
824824 }
825825}
826pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
826pub fn main(args: [][]u8) i32 => {
827827 const r = Rand {.seed = 1234};
828828 if (r.get_seed() != 1234) {
829829 print_str("BAD seed\n");
......@@ -836,7 +836,7 @@ pub fn main(argc : isize, argv : &&u8, env : &&u8) i32 => {
836836 add_simple_case("pointer dereferencing", R"SOURCE(
837837import "std.zig";
838838
839pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
839pub fn main(args: [][]u8) i32 => {
840840 var x = i32(3);
841841 const y = &x;
842842
......@@ -858,7 +858,7 @@ import "std.zig";
858858
859859const ARRAY_SIZE : u8 = 20;
860860
861pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
861pub fn main(args: [][]u8) i32 => {
862862 var array : [ARRAY_SIZE]u8;
863863 print_u64(@sizeof(@typeof(array)));
864864 print_str("\n");
......@@ -868,7 +868,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
868868
869869 add_simple_case("#min_value() and #max_value()", R"SOURCE(
870870import "std.zig";
871pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
871pub fn main(args: [][]u8) i32 => {
872872 print_str("max u8: ");
873873 print_u64(@max_value(u8));
874874 print_str("\n");
......@@ -956,7 +956,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
956956
957957 add_simple_case("slicing", R"SOURCE(
958958import "std.zig";
959pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
959pub fn main(args: [][]u8) i32 => {
960960 var array : [20]i32;
961961
962962 array[5] = 1234;
......@@ -984,7 +984,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
984984
985985 add_simple_case("else if expression", R"SOURCE(
986986import "std.zig";
987pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
987pub fn main(args: [][]u8) i32 => {
988988 if (f(1) == 1) {
989989 print_str("OK\n");
990990 }
......@@ -1003,7 +1003,7 @@ fn f(c: u8) u8 => {
10031003
10041004 add_simple_case("overflow intrinsics", R"SOURCE(
10051005import "std.zig";
1006pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
1006pub fn main(args: [][]u8) i32 => {
10071007 var result: u8;
10081008 if (!@add_with_overflow(u8, 250, 100, &result)) {
10091009 print_str("BAD\n");
......@@ -1021,7 +1021,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
10211021
10221022 add_simple_case("memcpy and memset intrinsics", R"SOURCE(
10231023import "std.zig";
1024pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
1024pub fn main(args: [][]u8) i32 => {
10251025 var foo : [20]u8;
10261026 var bar : [20]u8;
10271027
......@@ -1042,7 +1042,7 @@ import "std.zig";
10421042const z : @typeof(stdin_fileno) = 0;
10431043const x : @typeof(y) = 1234;
10441044const y : u16 = 5678;
1045pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
1045pub fn main(args: [][]u8) i32 => {
10461046 print_ok(x)
10471047}
10481048fn print_ok(val: @typeof(x)) @typeof(foo) => {
......@@ -1073,7 +1073,7 @@ enum Bar {
10731073 D,
10741074}
10751075
1076pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
1076pub fn main(args: [][]u8) i32 => {
10771077 const foo1 = Foo.One(13);
10781078 const foo2 = Foo.Two(Point { .x = 1234, .y = 5678, });
10791079 const bar = Bar.B;
......@@ -1106,7 +1106,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
11061106 add_simple_case("array literal", R"SOURCE(
11071107import "std.zig";
11081108
1109pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
1109pub fn main(args: [][]u8) i32 => {
11101110 const HEX_MULT = []u16{4096, 256, 16, 1};
11111111
11121112 if (HEX_MULT.len != 4) {
......@@ -1442,6 +1442,10 @@ fn f(noalias x: i32) => {}
14421442 add_compile_fail_case("struct init syntax for array", R"SOURCE(
14431443const foo = []u16{.x = 1024,};
14441444 )SOURCE", 1, ".tmp_source.zig:2:18: error: type '[]u16' does not support struct initialization syntax");
1445
1446 add_compile_fail_case("type variables must be constant", R"SOURCE(
1447var foo = u8;
1448 )SOURCE", 1, ".tmp_source.zig:2:1: error: variable of type 'type' must be constant");
14451449}
14461450
14471451static void print_compiler_invocation(TestCase *test_case) {