aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.h30
-rw-r--r--src/cli.h5
-rw-r--r--src/codegen.c10
-rw-r--r--src/common.h10
-rw-r--r--src/io.h10
-rw-r--r--src/parse.c107
-rw-r--r--src/preprocess.c40
-rw-r--r--src/std.h1
-rw-r--r--src/token.h20
-rw-r--r--src/tokenize.c5
10 files changed, 120 insertions, 118 deletions
diff --git a/src/ast.h b/src/ast.h
index 399befc..05c20e2 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -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);
diff --git a/src/cli.h b/src/cli.h
index 398ecaf..0fb106a 100644
--- a/src/cli.h
+++ b/src/cli.h
@@ -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);
diff --git a/src/io.h b/src/io.h
index 89394bf..fff3558 100644
--- a/src/io.h
+++ b/src/io.h
@@ -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) {
diff --git a/src/std.h b/src/std.h
index ad31747..0a40232 100644
--- a/src/std.h
+++ b/src/std.h
@@ -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));