Commit 76b1cbc2ea

Andrew Kelley <superjoe30@gmail.com>
2017-01-12 04:25:17
pass some parseh tests
1 parent 25a670d
Changed files (3)
src/ast_render.cpp
@@ -892,7 +892,7 @@ void ast_render(FILE *f, AstNode *node, int indent_size) {
     render_node_grouped(&ar, node);
 }
 
-static void ast_render_tld_fn(AstRender *ar, TldFn *tld_fn) {
+static void ast_render_tld_fn(AstRender *ar, Buf *name, TldFn *tld_fn) {
     FnTableEntry *fn_entry = tld_fn->fn_entry;
     FnTypeId *fn_type_id = &fn_entry->type_entry->data.fn.fn_type_id;
     const char *visib_mod_str = visib_mod_string(tld_fn->base.visib_mod);
@@ -917,15 +917,16 @@ static void ast_render_tld_fn(AstRender *ar, TldFn *tld_fn) {
     }
 }
 
-static void ast_render_tld_var(AstRender *ar, TldVar *tld_var) {
+static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
     VariableTableEntry *var = tld_var->var;
     const char *visib_mod_str = visib_mod_string(tld_var->base.visib_mod);
     const char *const_or_var = const_or_var_string(var->src_is_const);
     const char *extern_str = extern_string(var->is_extern);
-    fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(&var->name));
+    fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name));
 
     if (var->value.type->id == TypeTableEntryIdNumLitFloat ||
-        var->value.type->id == TypeTableEntryIdNumLitInt)
+        var->value.type->id == TypeTableEntryIdNumLitInt ||
+        var->value.type->id == TypeTableEntryIdMetaType)
     {
         // skip type
     } else {
@@ -937,11 +938,60 @@ static void ast_render_tld_var(AstRender *ar, TldVar *tld_var) {
         return;
     }
 
-    Buf buf = BUF_INIT;
-    buf_resize(&buf, 0);
-    render_const_value(&buf, &var->value);
+    fprintf(ar->f, " = ");
 
-    fprintf(ar->f, " = %s;\n", buf_ptr(&buf));
+    if (var->value.special == ConstValSpecialStatic &&
+        var->value.type->id == TypeTableEntryIdMetaType)
+    {
+        TypeTableEntry *type_entry = var->value.data.x_type;
+        if (type_entry->id == TypeTableEntryIdStruct) {
+            const char *extern_str = extern_string(type_entry->data.structure.is_extern);
+            fprintf(ar->f, "%sstruct {\n", extern_str);
+            for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
+                TypeStructField *field = &type_entry->data.structure.fields[i];
+                fprintf(ar->f, "    ");
+                print_symbol(ar, field->name);
+                fprintf(ar->f, ": %s,\n", buf_ptr(&field->type_entry->name));
+            }
+            fprintf(ar->f, "}");
+        } else if (type_entry->id == TypeTableEntryIdEnum) {
+            const char *extern_str = extern_string(type_entry->data.enumeration.is_extern);
+            fprintf(ar->f, "%senum {\n", extern_str);
+            for (size_t i = 0; i < type_entry->data.enumeration.src_field_count; i += 1) {
+                TypeEnumField *field = &type_entry->data.enumeration.fields[i];
+                fprintf(ar->f, "    ");
+                print_symbol(ar, field->name);
+                if (field->type_entry->id == TypeTableEntryIdVoid) {
+                    fprintf(ar->f, ",\n");
+                } else {
+                    fprintf(ar->f, ": %s,\n", buf_ptr(&field->type_entry->name));
+                }
+            }
+            fprintf(ar->f, "}");
+        } else if (type_entry->id == TypeTableEntryIdUnion) {
+            fprintf(ar->f, "union {");
+            fprintf(ar->f, "TODO");
+            fprintf(ar->f, "}");
+        } else {
+            fprintf(ar->f, "%s", buf_ptr(&type_entry->name));
+        }
+    } else {
+        Buf buf = BUF_INIT;
+        buf_resize(&buf, 0);
+        render_const_value(&buf, &var->value);
+        fprintf(ar->f, "%s", buf_ptr(&buf));
+    }
+
+    fprintf(ar->f, ";\n");
+}
+
+static void ast_render_tld_typedef(AstRender *ar, Buf *name, TldTypeDef *tld_typedef) {
+    TypeTableEntry *type_entry = tld_typedef->type_entry;
+    TypeTableEntry *canon_type = get_underlying_type(type_entry);
+
+    fprintf(ar->f, "pub type ");
+    print_symbol(ar, name);
+    fprintf(ar->f, " = %s;\n", buf_ptr(&canon_type->name));
 }
 
 void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
@@ -957,18 +1007,26 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
             break;
 
         Tld *tld = entry->value;
+
+        if (!buf_eql_buf(entry->key, tld->name)) {
+            fprintf(ar.f, "pub const ");
+            print_symbol(&ar, entry->key);
+            fprintf(ar.f, " = %s;\n", buf_ptr(tld->name));
+            continue;
+        }
+
         switch (tld->id) {
             case TldIdVar:
-                ast_render_tld_var(&ar, (TldVar *)tld);
+                ast_render_tld_var(&ar, entry->key, (TldVar *)tld);
                 break;
             case TldIdFn:
-                ast_render_tld_fn(&ar, (TldFn *)tld);
+                ast_render_tld_fn(&ar, entry->key, (TldFn *)tld);
                 break;
             case TldIdContainer:
                 fprintf(stdout, "container\n");
                 break;
             case TldIdTypeDef:
-                fprintf(stdout, "typedef\n");
+                ast_render_tld_typedef(&ar, entry->key, (TldTypeDef *)tld);
                 break;
         }
     }
src/parseh.cpp
@@ -110,8 +110,17 @@ static void add_global(Context *c, Tld *tld) {
 }
 
 static Tld *get_global(Context *c, Buf *name) {
-    auto entry = c->import->decls_scope->decl_table.maybe_get(name);
-    return entry ? entry->value : nullptr;
+    {
+        auto entry = c->import->decls_scope->decl_table.maybe_get(name);
+        if (entry)
+            return entry->value;
+    }
+    {
+        auto entry = c->macro_table.maybe_get(name);
+        if (entry)
+            return entry->value;
+    }
+    return nullptr;
 }
 
 static const char *decl_name(const Decl *decl) {
@@ -125,18 +134,18 @@ static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) {
 }
 
 static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_value, bool is_const) {
+    auto entry = c->import->decls_scope->decl_table.maybe_get(name);
+    if (entry) {
+        Tld *existing_tld = entry->value;
+        assert(existing_tld->id == TldIdVar);
+        return (TldVar *)existing_tld;
+    }
     TldVar *tld_var = allocate<TldVar>(1);
     parseh_init_tld(c, &tld_var->base, TldIdVar, name);
     tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, name, is_const, var_value);
     return tld_var;
 }
 
-static Tld *create_global_char_lit_var(Context *c, Buf *name, uint8_t value) {
-    ConstExprValue *var_val = create_const_unsigned_negative(c->codegen->builtin_types.entry_u8, value, false);
-    TldVar *tld_var = create_global_var(c, name, var_val, true);
-    return &tld_var->base;
-}
-
 static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) {
     TldVar *tld_var = create_global_var(c, name, create_const_str_lit(c->codegen, value), true);
     return &tld_var->base;
@@ -1156,7 +1165,7 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
         switch (tok->id) {
             case CTokIdCharLit:
                 if (is_last && is_first) {
-                    Tld *tld = create_global_char_lit_var(c, name, tok->data.char_lit);
+                    Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.char_lit, false);
                     c->macro_table.put(name, tld);
                 }
                 return;
@@ -1228,7 +1237,7 @@ static void process_symbol_macros(Context *c) {
             }
         }
 
-        add_global_alias(c, ms.value, existing_tld);
+        add_global_alias(c, ms.name, existing_tld);
     }
 }
 
test/run_tests.cpp
@@ -1754,13 +1754,14 @@ enum Foo {
     FooB,
     Foo1,
 };
-    )SOURCE", 3, R"(export enum enum_Foo {
+    )SOURCE", 5, R"(pub const enum_Foo = extern enum {
     A,
     B,
     @"1",
-})", R"(pub const FooA = enum_Foo.A;
-pub const FooB = enum_Foo.B;
-pub const Foo1 = enum_Foo.@"1";)",
+};)",
+            R"(pub const FooA = 0;)",
+            R"(pub const FooB = 1;)",
+            R"(pub const Foo1 = 2;)",
             R"(pub const Foo = enum_Foo;)");
 
     add_parseh_case("restrict -> noalias", AllowWarningsNo, R"SOURCE(
@@ -1773,10 +1774,10 @@ struct Foo {
     char *y;
 };
     )SOURCE", 2,
-            R"OUTPUT(export struct struct_Foo {
+            R"OUTPUT(const struct_Foo = extern struct {
     x: c_int,
     y: ?&u8,
-})OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT");
+};)OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT");
 
     add_parseh_case("qualified struct and enum", AllowWarningsNo, R"SOURCE(
 struct Foo {
@@ -1788,18 +1789,18 @@ enum Bar {
     BarB,
 };
 void func(struct Foo *a, enum Bar **b);
-    )SOURCE", 5, R"OUTPUT(export struct struct_Foo {
+    )SOURCE", 7, R"OUTPUT(pub const struct_Foo = extern struct {
     x: c_int,
     y: c_int,
-})OUTPUT", R"OUTPUT(
-export enum enum_Bar {
+};)OUTPUT", R"OUTPUT(pub const enum_Bar = extern enum {
     A,
     B,
-})OUTPUT", R"OUTPUT(pub const BarA = enum_Bar.A;
-pub const BarB = enum_Bar.B;)OUTPUT",
+};)OUTPUT",
+            R"OUTPUT(pub const BarA = 0;)OUTPUT",
+            R"OUTPUT(pub const BarB = 1;)OUTPUT",
             "pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);",
-    R"OUTPUT(pub const Foo = struct_Foo;
-pub const Bar = enum_Bar;)OUTPUT");
+    R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT",
+    R"OUTPUT(pub const Bar = enum_Bar;)OUTPUT");
 
     add_parseh_case("constant size array", AllowWarningsNo, R"SOURCE(
 void func(int array[20]);
@@ -1811,22 +1812,22 @@ void func(int array[20]);
 struct Foo {
     void (*derp)(struct Foo *foo);
 };
-    )SOURCE", 2, R"OUTPUT(export struct struct_Foo {
+    )SOURCE", 2, R"OUTPUT(pub const struct_Foo = extern struct {
     derp: ?extern fn(?&struct_Foo),
-})OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT");
+};)OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT");
 
 
     add_parseh_case("struct prototype used in func", AllowWarningsNo, R"SOURCE(
 struct Foo;
 struct Foo *some_func(struct Foo *foo, int x);
-    )SOURCE", 2, R"OUTPUT(pub type struct_Foo = u8;
-pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;)OUTPUT",
+    )SOURCE", 3, R"OUTPUT(pub type struct_Foo = u8;)OUTPUT",
+        R"OUTPUT(pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;)OUTPUT",
         R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT");
 
 
     add_parseh_case("#define a char literal", AllowWarningsNo, R"SOURCE(
 #define A_CHAR  'a'
-    )SOURCE", 1, R"OUTPUT(pub const A_CHAR = 'a';)OUTPUT");
+    )SOURCE", 1, R"OUTPUT(pub const A_CHAR = 97;)OUTPUT");
 
 
     add_parseh_case("#define an unsigned integer literal", AllowWarningsNo,
@@ -1863,12 +1864,12 @@ struct Bar {
     struct Foo *next;
 };
     )SOURCE", 2,
-            R"SOURCE(export struct struct_Bar {
+            R"SOURCE(pub const struct_Bar = extern struct {
     next: ?&struct_Foo,
-})SOURCE",
-            R"SOURCE(export struct struct_Foo {
+};)SOURCE",
+            R"SOURCE(pub const struct_Foo = extern struct {
     next: ?&struct_Bar,
-})SOURCE");
+};)SOURCE");
 
 
     add_parseh_case("typedef void", AllowWarningsNo, R"SOURCE(