diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast.h | 30 | ||||
| -rw-r--r-- | src/cli.h | 5 | ||||
| -rw-r--r-- | src/codegen.c | 10 | ||||
| -rw-r--r-- | src/common.h | 10 | ||||
| -rw-r--r-- | src/io.h | 10 | ||||
| -rw-r--r-- | src/parse.c | 107 | ||||
| -rw-r--r-- | src/preprocess.c | 40 | ||||
| -rw-r--r-- | src/std.h | 1 | ||||
| -rw-r--r-- | src/token.h | 20 | ||||
| -rw-r--r-- | src/tokenize.c | 5 |
10 files changed, 120 insertions, 118 deletions
@@ -3,7 +3,7 @@ #include "std.h" -enum StorageClass { +typedef enum { StorageClass_unspecified, StorageClass_auto, StorageClass_constexpr, @@ -12,10 +12,9 @@ enum StorageClass { StorageClass_static, StorageClass_thread_local, StorageClass_typedef, -}; -typedef enum StorageClass StorageClass; +} StorageClass; -enum TypeKind { +typedef enum { TypeKind_unknown, TypeKind_void, @@ -35,29 +34,26 @@ enum TypeKind { TypeKind_enum, TypeKind_ptr, TypeKind_array, -}; -typedef enum TypeKind TypeKind; +} TypeKind; const char* type_kind_stringify(TypeKind k); struct AstNode; typedef struct AstNode AstNode; -struct TypeRef { +typedef struct { struct AstNode* defs; size_t index; -}; -typedef struct TypeRef TypeRef; +} TypeRef; -struct Type { +typedef struct Type { TypeKind kind; StorageClass storage_class; // Check `base` instead of `kind` to test if the type is an array or a pointer. struct Type* base; int array_size; TypeRef ref; -}; -typedef struct Type Type; +} Type; Type* type_new(TypeKind kind); Type* type_new_ptr(Type* base); @@ -78,7 +74,7 @@ int type_alignof(Type* ty); int to_aligned(int n, int a); -enum AstNodeKind { +typedef enum { AstNodeKind_unknown, AstNodeKind_nop, @@ -119,8 +115,7 @@ enum AstNodeKind { // Intermediate ASTs: they are used only in parsing, not for parse result. AstNodeKind_declarator, -}; -typedef enum AstNodeKind AstNodeKind; +} AstNodeKind; #define node_items __n1 #define node_len __i1 @@ -157,12 +152,11 @@ struct AstNode { int __i2; }; -struct Program { +typedef struct { AstNode* funcs; AstNode* vars; const char** str_literals; -}; -typedef struct Program Program; +} Program; AstNode* ast_new(AstNodeKind kind); AstNode* ast_new_list(int capacity); @@ -3,7 +3,7 @@ #include "std.h" -struct CliArgs { +typedef struct { const char* input_filename; const char* output_filename; BOOL output_assembly; @@ -11,8 +11,7 @@ struct CliArgs { BOOL generate_deps; BOOL totally_deligate_to_gcc; const char* gcc_command; -}; -typedef struct CliArgs CliArgs; +} CliArgs; CliArgs* parse_cli_args(int argc, char** argv); diff --git a/src/codegen.c b/src/codegen.c index 9aa9a77..bce71c9 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -2,19 +2,17 @@ #include "common.h" #include "preprocess.h" -enum GenMode { +typedef enum { GenMode_lval, GenMode_rval, -}; -typedef enum GenMode GenMode; +} GenMode; -struct CodeGen { +typedef struct { FILE* out; int next_label; int* loop_labels; AstNode* current_func; -}; -typedef struct CodeGen CodeGen; +} CodeGen; static CodeGen* codegen_new(FILE* out) { CodeGen* g = calloc(1, sizeof(CodeGen)); diff --git a/src/common.h b/src/common.h index 98e27e1..b31dfc4 100644 --- a/src/common.h +++ b/src/common.h @@ -10,12 +10,11 @@ _Noreturn void fatal_error(const char* msg, ...); BOOL str_ends_with(const char* s, const char* suffix); -struct StrBuilder { +typedef struct { size_t len; size_t capacity; char* buf; -}; -typedef struct StrBuilder StrBuilder; +} StrBuilder; void strbuilder_init(StrBuilder* b); // `size` must include a trailing null byte. @@ -23,12 +22,11 @@ void strbuilder_reserve(StrBuilder* b, size_t size); void strbuilder_append_char(StrBuilder* b, int c); void strbuilder_append_string(StrBuilder* b, const char* s); -struct StrArray { +typedef struct { size_t len; size_t capacity; const char** data; -}; -typedef struct StrArray StrArray; +} StrArray; void strings_init(StrArray* strings); void strings_reserve(StrArray* strings, size_t size); @@ -4,20 +4,18 @@ #include "json.h" #include "std.h" -struct SourceLocation { +typedef struct { const char* filename; int line; -}; -typedef struct SourceLocation SourceLocation; +} SourceLocation; void sourcelocation_build_json(JsonBuilder* builder, SourceLocation* loc); -struct InFile { +typedef struct { const char* buf; int pos; SourceLocation loc; -}; -typedef struct InFile InFile; +} InFile; InFile* infile_open(const char* filename); BOOL infile_eof(InFile* f); diff --git a/src/parse.c b/src/parse.c index b4c33b5..57dd316 100644 --- a/src/parse.c +++ b/src/parse.c @@ -2,19 +2,17 @@ #include "common.h" #include "tokenize.h" -struct LocalVar { +typedef struct { const char* name; Type* ty; int stack_offset; -}; -typedef struct LocalVar LocalVar; +} LocalVar; -struct LocalVarArray { +typedef struct { size_t len; size_t capacity; LocalVar* data; -}; -typedef struct LocalVarArray LocalVarArray; +} LocalVarArray; static void lvars_init(LocalVarArray* lvars) { lvars->len = 0; @@ -37,18 +35,16 @@ static LocalVar* lvars_push_new(LocalVarArray* lvars) { return &lvars->data[lvars->len++]; } -struct ScopedSymbol { +typedef struct { const char* name; int index; -}; -typedef struct ScopedSymbol ScopedSymbol; +} ScopedSymbol; -struct ScopedSymbolArray { +typedef struct { size_t len; size_t capacity; ScopedSymbol* data; -}; -typedef struct ScopedSymbolArray ScopedSymbolArray; +} ScopedSymbolArray; static void scopedsymbols_init(ScopedSymbolArray* syms) { syms->len = 0; @@ -71,24 +67,21 @@ static ScopedSymbol* scopedsymbols_push_new(ScopedSymbolArray* syms) { return &syms->data[syms->len++]; } -struct Scope { +typedef struct Scope { struct Scope* outer; ScopedSymbolArray syms; -}; -typedef struct Scope Scope; +} Scope; -struct GlobalVar { +typedef struct { const char* name; Type* ty; -}; -typedef struct GlobalVar GlobalVar; +} GlobalVar; -struct GlobalVarArray { +typedef struct { size_t len; size_t capacity; GlobalVar* data; -}; -typedef struct GlobalVarArray GlobalVarArray; +} GlobalVarArray; static void gvars_init(GlobalVarArray* gvars) { gvars->len = 0; @@ -111,18 +104,16 @@ static GlobalVar* gvars_push_new(GlobalVarArray* gvars) { return &gvars->data[gvars->len++]; } -struct Func { +typedef struct { const char* name; Type* ty; -}; -typedef struct Func Func; +} Func; -struct FuncArray { +typedef struct { size_t len; size_t capacity; Func* data; -}; -typedef struct FuncArray FuncArray; +} FuncArray; static void funcs_init(FuncArray* funcs) { funcs->len = 0; @@ -145,7 +136,7 @@ static Func* funcs_push_new(FuncArray* funcs) { return &funcs->data[funcs->len++]; } -struct Parser { +typedef struct { TokenArray* tokens; int pos; LocalVarArray lvars; @@ -157,8 +148,8 @@ struct Parser { AstNode* enums; AstNode* typedefs; StrArray str_literals; -}; -typedef struct Parser Parser; + int anonymous_user_type_counter; +} Parser; static Parser* parser_new(TokenArray* tokens) { Parser* p = calloc(1, sizeof(Parser)); @@ -1352,14 +1343,31 @@ void parse_extern_var_decl(Parser* p, AstNode* decls) { } } +static char* generate_new_anonymous_user_type_name(Parser* p) { + char* buf = calloc(32, sizeof(char)); + sprintf(buf, "__anonymous_%d__", p->anonymous_user_type_counter++); + return buf; +} + // struct-specifier: // 'struct' TODO attribute-specifier-sequence? identifier? '{' member-declaration-list '}' // 'struct' TODO attribute-specifier-sequence? identifier static Type* parse_struct_specifier(Parser* p) { + SourceLocation struct_kw_pos = peek_token(p)->loc; next_token(p); - // TODO: support anonymous struct - const Token* name = parse_ident(p); + const Token* name; + char* anonymous_name = NULL; + if (peek_token(p)->kind == TokenKind_brace_l) { + anonymous_name = generate_new_anonymous_user_type_name(p); + Token* anonymous_token = calloc(1, sizeof(Token)); + anonymous_token->kind = TokenKind_ident; + anonymous_token->value.string = anonymous_name; + anonymous_token->loc = struct_kw_pos; + name = anonymous_token; + } else { + name = parse_ident(p); + } if (!consume_token_if(p, TokenKind_brace_l)) { int struct_idx = find_struct(p, name->value.string); @@ -1408,10 +1416,21 @@ static Type* parse_struct_specifier(Parser* p) { // 'union' TODO attribute-specifier-sequence? identifier? '{' member-declaration-list '}' // 'union' TODO attribute-specifier-sequence? identifier static Type* parse_union_specifier(Parser* p) { + SourceLocation union_kw_pos = peek_token(p)->loc; next_token(p); - // TODO: support anonymous union - const Token* name = parse_ident(p); + const Token* name; + char* anonymous_name = NULL; + if (peek_token(p)->kind == TokenKind_brace_l) { + anonymous_name = generate_new_anonymous_user_type_name(p); + Token* anonymous_token = calloc(1, sizeof(Token)); + anonymous_token->kind = TokenKind_ident; + anonymous_token->value.string = anonymous_name; + anonymous_token->loc = union_kw_pos; + name = anonymous_token; + } else { + name = parse_ident(p); + } if (!consume_token_if(p, TokenKind_brace_l)) { int union_idx = find_union(p, name->value.string); @@ -1460,10 +1479,21 @@ static Type* parse_union_specifier(Parser* p) { // 'enum' TODO attribute-specifier-sequence? identifier? TODO enum-type-specifier? '{' enumerator-list ','? '}' // 'enum' identifier TODO enum-type-specifier? static Type* parse_enum_specifier(Parser* p) { + SourceLocation enum_kw_pos = peek_token(p)->loc; next_token(p); - // TODO: support anonymous enum - const Token* name = parse_ident(p); + const Token* name; + char* anonymous_name = NULL; + if (peek_token(p)->kind == TokenKind_brace_l) { + anonymous_name = generate_new_anonymous_user_type_name(p); + Token* anonymous_token = calloc(1, sizeof(Token)); + anonymous_token->kind = TokenKind_ident; + anonymous_token->value.string = anonymous_name; + anonymous_token->loc = enum_kw_pos; + name = anonymous_token; + } else { + name = parse_ident(p); + } if (!consume_token_if(p, TokenKind_brace_l)) { int enum_idx = find_enum(p, name->value.string); @@ -1508,7 +1538,7 @@ static Type* parse_enum_specifier(Parser* p) { return ty; } -enum TypeSpecifierMask { +typedef enum { // TODO: define these constants with shift operators once ducc supports it. TypeSpecifierMask_void = 1, TypeSpecifierMask_char = 2, @@ -1533,8 +1563,7 @@ enum TypeSpecifierMask { TypeSpecifierMask_typeof = 1048576, TypeSpecifierMask_typeof_unqual = 2097152, TypeSpecifierMask_typedef_name = 4194304, -}; -typedef enum TypeSpecifierMask TypeSpecifierMask; +} TypeSpecifierMask; static Type* distinguish_type_from_type_specifiers(int type_specifiers) { if (type_specifiers == TypeSpecifierMask_void) { diff --git a/src/preprocess.c b/src/preprocess.c index 4b2bdaf..2fd334f 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -3,14 +3,13 @@ #include "parse.h" #include "sys.h" -enum MacroKind { +typedef enum { MacroKind_undef, MacroKind_obj, MacroKind_func, MacroKind_builtin_file, MacroKind_builtin_line, -}; -typedef enum MacroKind MacroKind; +} MacroKind; const char* macro_kind_stringify(MacroKind kind) { if (kind == MacroKind_undef) @@ -27,13 +26,12 @@ const char* macro_kind_stringify(MacroKind kind) { unreachable(); } -struct Macro { +typedef struct { MacroKind kind; const char* name; TokenArray parameters; TokenArray replacements; -}; -typedef struct Macro Macro; +} Macro; static int macro_find_param(Macro* macro, Token* tok) { if (tok->kind != TokenKind_ident) @@ -47,12 +45,11 @@ static int macro_find_param(Macro* macro, Token* tok) { return -1; } -struct MacroArray { +typedef struct { size_t len; size_t capacity; Macro* data; -}; -typedef struct MacroArray MacroArray; +} MacroArray; static MacroArray* macros_new() { MacroArray* macros = calloc(1, sizeof(MacroArray)); @@ -104,10 +101,9 @@ static void add_predefined_macros(MacroArray* macros) { define_macro_to_1(macros, "__LP64__"); } -struct MacroArg { +typedef struct { TokenArray tokens; -}; -typedef struct MacroArg MacroArg; +} MacroArg; void macroarg_build_json(JsonBuilder* builder, MacroArg* arg) { jsonbuilder_object_start(builder); @@ -117,12 +113,11 @@ void macroarg_build_json(JsonBuilder* builder, MacroArg* arg) { jsonbuilder_object_end(builder); } -struct MacroArgArray { +typedef struct { size_t len; size_t capacity; MacroArg* data; -}; -typedef struct MacroArgArray MacroArgArray; +} MacroArgArray; static MacroArgArray* macroargs_new() { MacroArgArray* macroargs = calloc(1, sizeof(MacroArgArray)); @@ -164,13 +159,12 @@ void macroargs_build_json(JsonBuilder* builder, MacroArgArray* macroargs) { jsonbuilder_object_end(builder); } -struct PpLexer { +typedef struct { InFile* src; BOOL at_bol; BOOL expect_header_name; TokenArray* pp_tokens; -}; -typedef struct PpLexer PpLexer; +} PpLexer; static PpLexer* pplexer_new(InFile* src) { PpLexer* ppl = calloc(1, sizeof(PpLexer)); @@ -559,15 +553,14 @@ static TokenArray* pp_tokenize(InFile* src) { return ppl->pp_tokens; } -struct Preprocessor { +typedef struct { TokenArray* pp_tokens; int pos; MacroArray* macros; int include_depth; StrArray include_paths; StrArray* included_files; -}; -typedef struct Preprocessor Preprocessor; +} Preprocessor; static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files); @@ -969,12 +962,11 @@ static BOOL expand_macro(Preprocessor* pp, BOOL skip_newline) { return TRUE; } -enum GroupDelimiterKind { +typedef enum { GroupDelimiterKind_normal, GroupDelimiterKind_after_if_directive, GroupDelimiterKind_after_else_directive, -}; -typedef enum GroupDelimiterKind GroupDelimiterKind; +} GroupDelimiterKind; static BOOL is_delimiter_of_current_group(GroupDelimiterKind delimiter_kind, TokenKind token_kind) { if (delimiter_kind == GroupDelimiterKind_normal) { @@ -3,7 +3,6 @@ #include <stddef.h> -struct FILE; typedef struct FILE FILE; extern FILE* stdin; diff --git a/src/token.h b/src/token.h index 7a624fb..72db22b 100644 --- a/src/token.h +++ b/src/token.h @@ -4,7 +4,7 @@ #include "io.h" #include "json.h" -enum TokenKind { +typedef enum { TokenKind_eof, // Only preprocessing phase. @@ -143,35 +143,31 @@ enum TokenKind { TokenKind_star, TokenKind_tilde, TokenKind_xor, -}; -typedef enum TokenKind TokenKind; +} TokenKind; const char* token_kind_stringify(TokenKind k); BOOL is_pp_directive(TokenKind k); // TokenValue is externally tagged by Token's kind. -union TokenValue { +typedef union { const char* string; int integer; -}; -typedef union TokenValue TokenValue; +} TokenValue; -struct Token { +typedef struct { TokenKind kind; TokenValue value; SourceLocation loc; -}; -typedef struct Token Token; +} Token; const char* token_stringify(Token* tok); void token_build_json(JsonBuilder* builder, Token* tok); -struct TokenArray { +typedef struct { size_t len; size_t capacity; Token* data; -}; -typedef struct TokenArray TokenArray; +} TokenArray; void tokens_init(TokenArray* tokens, size_t capacity); void tokens_reserve(TokenArray* tokens, size_t size); diff --git a/src/tokenize.c b/src/tokenize.c index b0e1447..7ba00cd 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -1,11 +1,10 @@ #include "tokenize.h" #include "common.h" -struct Lexer { +typedef struct { TokenArray* src; TokenArray* tokens; -}; -typedef struct Lexer Lexer; +} Lexer; static Lexer* lexer_new(TokenArray* pp_tokens) { Lexer* l = calloc(1, sizeof(Lexer)); |
