C codegen

This commit is contained in:
Krzosa Karol
2022-05-03 20:08:13 +02:00
parent 8c04044ea2
commit 557dde1936
11 changed files with 573 additions and 281 deletions

74
ast.c
View File

@@ -1,4 +1,6 @@
//-----------------------------------------------------------------------------
// Decls
//-----------------------------------------------------------------------------
function Decl *
decl_new(Parser *p, Decl_Kind kind, Token *pos, Intern_String name){
Decl *result = arena_push_struct(&p->main_arena, Decl);
@@ -9,9 +11,10 @@ decl_new(Parser *p, Decl_Kind kind, Token *pos, Intern_String name){
}
function Decl *
decl_struct(Parser *p, Decl_Kind kind, Token *pos, Intern_String name){
decl_struct(Parser *p, Decl_Kind kind, Token *pos, Intern_String name, Decl_Struct_Kind struct_kind){
assert(kind == DECL_Struct || kind == DECL_Union);
Decl *result = decl_new(p, kind, pos, name);
result->struct_decl.kind = struct_kind;
return result;
}
@@ -37,6 +40,23 @@ decl_variable(Parser *p, Token *pos, Intern_String name, Typespec *typespec, Exp
return result;
}
function Decl *
decl_function(Parser *p, Token *pos, Intern_String name, Typespec *ret){
Decl *result = decl_new(p, DECL_Function, pos, name);
result->function_decl.ret = ret;
return result;
}
function void
decl_function_push(Parser *p, Decl *parent, Token *pos, Intern_String name, Typespec *type){
assert(parent->kind == DECL_Function);
Decl_Function_Arg *result = arena_push_struct(&p->main_arena, Decl_Function_Arg);
result->name = name;
result->typespec = type;
result->pos = pos;
SLLQueuePush(parent->function_decl.first, parent->function_decl.last, result);
}
function void
decl_enum_push(Parser *p, Decl *parent, Token *pos, Intern_String name, Expr *expr, Note *notes){
assert(parent->kind == DECL_Enum);
@@ -61,6 +81,15 @@ decl_list_push(Decl *parent, Decl *child){
SLLQueuePush(parent->list.first, parent->list.last, child);
}
//-----------------------------------------------------------------------------
// Notes
//-----------------------------------------------------------------------------
function void
decl_pass_notes(Decl *a, Note *b){
a->first_note = b->first;
a->last_note = b->last;
}
function Note *
note_push_new(Parser *p, Note *parent, Token *pos, Intern_String name, Expr *expr){
Note *result = arena_push_struct(&p->main_arena, Note);
@@ -71,12 +100,38 @@ note_push_new(Parser *p, Note *parent, Token *pos, Intern_String name, Expr *exp
return result;
}
function void
decl_pass_notes(Decl *a, Note *b){
a->first_note = b->first;
a->last_note = b->last;
function Note *
find_note(Note *first, String string){
for(Note *n = first; n; n=n->next){
if(string_compare(string, n->name.s)){
return n;
}
}
return 0;
}
function String
find_string_note(Note *first, String string, String default_string){
Note *note = find_note(first, string);
if(note){
return note->expr->token->intern_val.s;
}
return default_string;
}
function Note *
decl_find_note(Decl *decl, String string){
return find_note(decl->first_note, string);
}
function String
decl_find_string_note(Decl *decl, String string, String default_string){
return find_string_note(decl->first_note, string, default_string);
}
//-----------------------------------------------------------------------------
// Typespec
//-----------------------------------------------------------------------------
function Typespec *
typespec_new(Parser *p, Typespec_Kind kind, Token *pos){
Typespec *result = arena_push_struct(&p->main_arena, Typespec);
@@ -85,13 +140,6 @@ typespec_new(Parser *p, Typespec_Kind kind, Token *pos){
return result;
}
function Typespec *
typespec_struct(Parser *p, Token *pos, Decl *aggregate){
Typespec *result = typespec_new(p, TS_Struct, pos);
result->struct_spec = aggregate;
return result;
}
function Typespec *
typespec_name(Parser *p, Token *pos, Intern_String name){
Typespec *result = typespec_new(p, TS_Name, pos);

64
ast.h
View File

@@ -1,7 +1,9 @@
typedef struct Decl_Enum_Child Decl_Enum_Child;
typedef struct Decl_Function_Arg Decl_Function_Arg;
typedef struct Typespec Typespec;
typedef struct Decl Decl;
typedef struct Note Note;
typedef struct Stmt Stmt;
//-----------------------------------------------------------------------------
// Type specifier
@@ -12,7 +14,6 @@ typedef enum Typespec_Kind{
TS_Pointer,
TS_Array,
TS_Function,
TS_Struct,
}Typespec_Kind;
struct Typespec{
@@ -21,7 +22,6 @@ struct Typespec{
Token *pos;
union{
Intern_String name;
Decl *struct_spec;
struct{
Typespec *first;
Typespec *last;
@@ -58,9 +58,22 @@ typedef enum Decl_Kind{
DECL_Enum,
DECL_Variable,
DECL_Typedef,
DECL_Function,
DECL_List,
}Decl_Kind;
typedef enum Decl_Struct_Kind{
STRUCT_Base ,
STRUCT_Nested,
}Decl_Struct_Kind;
struct Decl_Function_Arg{
Decl_Function_Arg *next;
Intern_String name;
Typespec *typespec;
Token *pos;
};
struct Decl_Enum_Child{
Decl_Enum_Child *next;
Intern_String name;
@@ -73,9 +86,10 @@ struct Decl_Enum_Child{
struct Decl{
Decl_Kind kind;
Decl *next;
Intern_String name;
Token *pos;
Decl *next;
Note *first_note;
Note *last_note;
@@ -87,6 +101,7 @@ struct Decl{
Typespec *typespec;
}enum_decl;
struct{
Decl_Struct_Kind kind;
Decl *first;
Decl *last;
} struct_decl;
@@ -97,6 +112,11 @@ struct Decl{
struct{
Typespec *type;
}typedef_decl;
struct{
Decl_Function_Arg *first;
Decl_Function_Arg *last ;
Typespec *ret;
}function_decl;
struct{
Decl *first;
Decl *last;
@@ -104,3 +124,41 @@ struct Decl{
};
};
//-----------------------------------------------------------------------------
// Statements
//-----------------------------------------------------------------------------
typedef enum Stmt_Kind{
STMT_None,
STMT_Decl,
STMT_Expr,
STMT_Return,
STMT_If,
STMT_For,
}Stmt_Kind;
typedef struct Stmt_List Stmt_List;
struct Stmt_List{
Stmt *first;
Stmt *last;
};
typedef struct Stmt_If Stmt_If;
struct Stmt_If{
Stmt_If *next;
Expr *expr;
union{
struct{Stmt *first; Stmt *last;};
Stmt_List *list;
};
};
struct Stmt{
Stmt_Kind kind;
Stmt *next;
union{
Decl *decl;
Expr *expr;
Stmt_If *if_stmt;
Stmt_List *list;
};
};

126
codegen_c.c Normal file
View File

@@ -0,0 +1,126 @@
function void gen_decl(Parser *p, Decl *node);
function void
gen_typespec(Parser *p, Typespec *spec, B32 is_left){
switch(spec->kind) {
case TS_Name: {
if(is_left) lex_print("%s", spec->name.s.str);
} break;
case TS_Pointer: {
gen_typespec(p, spec->base,is_left);
if(is_left) lex_print("*");
} break;
case TS_Array: {
gen_typespec(p, spec->array_spec.base,is_left);
if(!is_left){
lex_print("[");
expr_print(p, spec->array_spec.size);
lex_print("]");
}
} break;
case TS_Function: {
invalid_codepath;
} break;
default: {invalid_codepath;} break;
}
}
function Typespec *
typespec_get_func(Typespec *type){
switch(type->kind){
case TS_Name:{return 0;} break;
case TS_Pointer:{return typespec_get_func(type->base);} break;
case TS_Array:{return typespec_get_func(type->array_spec.base);} break;
case TS_Function:{return type;} break;
default: {invalid_codepath;} break;
}
return 0;
}
function void
gen_decl(Parser *p, Decl *node){
switch(node->kind) {
case DECL_List: {
for(Decl *n = node->list.first; n; n=n->next){
gen_decl(p,n);
lex_new_line();
}
} break;
case DECL_Variable:{
Typespec *func = typespec_get_func(node->variable_decl.type);
if(!func){
gen_typespec(p, node->variable_decl.type, true);
lex_print(" %s", node->name.s.str);
gen_typespec(p, node->variable_decl.type, false);
}
else{
gen_typespec(p, func->function_spec.ret, true);
lex_print("(*");
lex_print("%s", node->name.s.str);
lex_print(")");
lex_print("(");
for(Typespec *t = func->function_spec.first; t; t=t->next){
gen_typespec(p, t, true);
gen_typespec(p, t, false);
if(t != func->function_spec.last) lex_print(", ");
}
lex_print(")");
}
print_assign_expr(p,node->variable_decl.expr);
lex_print(";");
} break;
case DECL_Typedef:{
lex_print("typedef %s ", node->name.s.str);
gen_typespec(p, node->typedef_decl.type, true);
gen_typespec(p, node->typedef_decl.type, false);
lex_print(";");
} break;
case DECL_Struct:
case DECL_Union :{
U8 *struct_name = node->kind==DECL_Struct ? (U8*)"struct" : (U8*)"union";
U8 *name = node->name.s.str;
if(node->struct_decl.kind == STRUCT_Base)
lex_print("typedef %s %s %s;\n", struct_name, name, name);
lex_print("%s %s{\n", struct_name, name?name:(U8*)"");
for(Decl *n = node->struct_decl.first; n; n=n->next){
gen_decl(p, n);
lex_print("\n");
}
lex_print("};");
if(node->struct_decl.kind == STRUCT_Base)
lex_print("\n");
} break;
case DECL_Enum:{
lex_print("enum %s", node->name.s.str);
if(!intern_compare(node->enum_decl.typespec->name, intern_s64)){
lex_print(" : ");
lex_print("%s", node->enum_decl.typespec->name.s.str);
}
lex_print("{\n");
String prefix = decl_find_string_note(node, lit("prefix"), string_empty);
for(Decl_Enum_Child *n = node->enum_decl.first; n; n=n->next){
lex_print("%.*s%s", (int)prefix.len, prefix.str, n->name.s.str);
print_assign_expr(p, n->expr);
lex_print(",\n");
}
lex_print("};\n");
} break;
default: {invalid_codepath;} break;
}
}

View File

@@ -1,3 +1,4 @@
global String string_empty;
function S64
clamp_top_s64(S64 val, S64 max){

17
main.c
View File

@@ -26,6 +26,7 @@ global FILE *global_output_file;
#include "parse_expr.c"
#include "parse_decl.c"
#include "print.c"
#include "codegen_c.c"
function void
lex_test(){
@@ -96,24 +97,16 @@ parser_test(){
parser_lex_stream(&p, exprs[i], lit("File"));
Expr *expr = parse_expr(&p);
assert(expr);
expr_print(&p, expr);
lex_print("\n");
//expr_print(&p, expr);
//lex_print("\n");
}
/*
String string
= lit(
"@test Thing2 :: struct { thing: union{a:U32;}; _: union{ thing: U32*; }; }"
"Thing :: enum: U32 { @str=\"as\" Thing = 32, Thing2 = 15<<2, }"
"Thing :: struct{ identi: U64*[32]; InnerStruct :: struct { t: U32; } var: InnerStruct; pp :: enum { Thing_1 } }"
"thing:(S64*,U64) U32*@[10]; }"
);
*/
String string = os_read_file(lit("test.cc"));
parser_lex_stream(&p, string, lit("Parse"));
Decl *decls = parse(&p);
assert(decls->list.first);
print_decl(&p, decls);
gen_decl(&p, decls);
}
function S32

409
output.cc
View File

@@ -1,246 +1,243 @@
(((534>43)?435:42),234,((S64)32),Thing[10][2],Thing((1,2)))
(4+(2*53))
((4+2)*53)
(++5)
(--5)
(-5)
(+5)
(sizeof(32)+sizeof(S32*))
((S64**)5)
(((S64)5)+3)
((534>43)?435:42)
typedef struct OpenGL OpenGL;
struct OpenGL{
void(*glVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, GLvoid*);
void(*glBindTexture)(GLenum, GLuint);
void(*glDrawArrays)(GLenum, GLint, GLsizei);
};
typedef struct OS_Memory OS_Memory;
struct OS_Memory{
data: void*;
commit: SizeU;
reserve: SizeU;
void* data;
SizeU commit;
SizeU reserve;
};
typedef struct Arena Arena;
struct Arena{
@using memory: OS_Memory;
len: U64;
alignment: U64;
OS_Memory memory;
U64 len;
U64 alignment;
};
typedef struct String String;
struct String{
str: U8*;
len: S64;
U8* str;
S64 len;
};
typedef Intern_String String;
@stringify @prefix = TK_ enum Token_Kind : S64{
@str = End of stream End,
@str = * Mul,
@str = / Div,
@str = + Add,
@str = - Sub,
@str = % Mod,
@str = & BitAnd,
@str = | BitOr,
@str = ^ BitXor,
@str = ~ Neg,
@str = ! Not,
@str = ( OpenParen,
@str = CloseParen,
@str = { OpenBrace,
@str = } CloseBrace,
@str = [ OpenBracket,
@str = ] CloseBracket,
@str = , Comma,
@str = # Pound,
@str = ? Question,
@str = ... ThreeDots,
@str = ; Semicolon,
@str = . Dot,
@str = < LesserThen,
@str = > GreaterThen,
@str = : Colon,
@str = = Assign,
@str = /= DivAssign,
@str = *= MulAssign,
@str = %= ModAssign,
@str = -= SubAssign,
@str = += AddAssign,
@str = &= AndAssign,
@str = |= OrAssign,
@str = ^= XorAssign,
@str = <<= LeftShiftAssign,
@str = >>= RightShiftAssign,
@str = :: DoubleColon,
@str = @ At,
@str = -- Decrement,
@str = ++ Increment,
@str = -- PostDecrement,
@str = ++ PostIncrement,
@str = <= LesserThenOrEqual,
@str = >= GreaterThenOrEqual,
@str = == Equals,
@str = && And,
@str = || Or,
@str = != NotEquals,
@str = << LeftShift,
@str = >> RightShift,
@str = -> Arrow,
@str = sizeof ExprSizeof,
DocComment,
Comment,
Identifier,
StringLit,
U8Lit,
Character,
Error,
Float,
Int,
Keyword,
enum Token_Kind{
TK_End,
TK_Mul,
TK_Div,
TK_Add,
TK_Sub,
TK_Mod,
TK_BitAnd,
TK_BitOr,
TK_BitXor,
TK_Neg,
TK_Not,
TK_OpenParen,
TK_CloseParen,
TK_OpenBrace,
TK_CloseBrace,
TK_OpenBracket,
TK_CloseBracket,
TK_Comma,
TK_Pound,
TK_Question,
TK_ThreeDots,
TK_Semicolon,
TK_Dot,
TK_LesserThen,
TK_GreaterThen,
TK_Colon,
TK_Assign,
TK_DivAssign,
TK_MulAssign,
TK_ModAssign,
TK_SubAssign,
TK_AddAssign,
TK_AndAssign,
TK_OrAssign,
TK_XorAssign,
TK_LeftShiftAssign,
TK_RightShiftAssign,
TK_DoubleColon,
TK_At,
TK_Decrement,
TK_Increment,
TK_PostDecrement,
TK_PostIncrement,
TK_LesserThenOrEqual,
TK_GreaterThenOrEqual,
TK_Equals,
TK_And,
TK_Or,
TK_NotEquals,
TK_LeftShift,
TK_RightShift,
TK_Arrow,
TK_ExprSizeof,
TK_DocComment,
TK_Comment,
TK_Identifier,
TK_StringLit,
TK_U8Lit,
TK_Character,
TK_Error,
TK_Float,
TK_Int,
TK_Keyword,
};
typedef struct Token Token;
struct Token{
kind: Token_Kind;
@using string: String;
val: union {
integer: S64;
error: String;
intern: Intern_String;
};
file: String;
line: S64;
line_begin: U8*;
Token_Kind kind;
String string;
union {
S64 integer_val;
String error_val;
Intern_String intern_val;
};
String file;
S64 line;
U8* line_begin;
};
typedef struct Tokens Tokens;
struct Tokens{
@array tokens: Token*;
iter: S64;
Token* tokens;
S64 iter;
};
typedef struct Lex_Stream Lex_Stream;
struct Lex_Stream{
stream: U8*;
line_begin: U8*;
filename: String;
line: S64;
U8* stream;
U8* line_begin;
String filename;
S64 line;
};
@prefix = EK_ enum Expr_Kind : S64{
None,
Atom,
Unary,
Binary,
Ternary,
Cast,
List,
Call,
Index,
enum Expr_Kind{
EK_None,
EK_Atom,
EK_Unary,
EK_Binary,
EK_Ternary,
EK_Cast,
EK_List,
EK_Call,
EK_Index,
};
typedef struct Expr Expr;
struct Expr{
kind: Expr_Kind;
token: Token*;
next: Expr*;
_: union {
cast_val: struct {
type: AST_Node*;
expr: Expr*;
Expr_Kind kind;
Token* token;
Expr* next;
union {
struct cast_val{
AST_Node* type;
Expr* expr;
};
struct list{
Expr* first;
Expr* last;
};
struct call{
Expr* atom;
Expr* list;
};
struct index{
Expr* atom;
Expr* index;
};
struct unary{
Expr* expr;
};
struct binary{
Expr* left;
Expr* right;
};
struct ternary{
Expr* cond;
Expr* on_true;
Expr* on_false;
};
};
};
list: struct {
first: Expr*;
last: Expr*;
};
call: struct {
atom: Expr*;
list: Expr*;
};
index: struct {
atom: Expr*;
index: Expr*;
};
unary: struct {
expr: Expr*;
};
binary: struct {
left: Expr*;
right: Expr*;
};
ternary: struct {
cond: Expr*;
on_true: Expr*;
on_false: Expr*;
};
};
};
@prefix = AK_ enum AST_Kind : S64{
None,
BaseType,
Typedef,
Enum,
Struct,
Union,
Note,
List,
Pointer,
Array,
Function,
Variable,
EnumChild,
enum AST_Kind{
AK_None,
AK_BaseType,
AK_Typedef,
AK_Enum,
AK_Struct,
AK_Union,
AK_Note,
AK_List,
AK_Pointer,
AK_Array,
AK_Function,
AK_Variable,
AK_EnumChild,
};
typedef struct AST_Node AST_Node;
struct AST_Node{
kind: AST_Kind;
pos: Token*;
name: Intern_String;
next: AST_Node*;
next_scope: AST_Node*;
first_note: AST_Node*;
last_note: AST_Node*;
first_child: AST_Node*;
last_child: AST_Node*;
_: union {
base_type_size: SizeU;
pointer: AST_Node*;
typedef_type: AST_Node*;
variable_type: AST_Node*;
func_return_type: AST_Node*;
};
AST_Kind kind;
Token* pos;
Intern_String name;
AST_Node* next;
AST_Node* next_scope;
AST_Node* first_note;
AST_Node* last_note;
AST_Node* first_child;
AST_Node* last_child;
union {
SizeU base_type_size;
AST_Node* pointer;
AST_Node* typedef_type;
AST_Node* variable_type;
AST_Node* func_return_type;
};
};
typedef struct Parser_Error Parser_Error;
struct Parser_Error{
next: Parser_Error*;
message: String;
token: Token*;
Parser_Error* next;
String message;
Token* token;
};
typedef struct Scope Scope;
struct Scope{
next: Scope*;
first: AST_Node*;
last: AST_Node*;
Scope* next;
AST_Node* first;
AST_Node* last;
};
typedef struct Parser Parser;
struct Parser{
main_arena: Arena;
intern_table_arena: Arena;
symbol_table_arena: Arena;
scope_free_list: Scope*;
scope_stack: Scope*;
global_scope: Scope*;
symbols_inserted: S64;
symbols_count: S64;
symbols: AST_Node*;
interns: Intern_String*;
interns_in_bytes: S64;
interns_inserted: S64;
interns_count: S64;
first_keyword: U8*;
last_keyword: U8*;
@sllqueue default: Parser_Error;
@sllqueue error: Parser_Error;
@using token_array: Tokens;
Arena main_arena;
Arena intern_table_arena;
Arena symbol_table_arena;
Scope* scope_free_list;
Scope* scope_stack;
Scope* global_scope;
S64 symbols_inserted;
S64 symbols_count;
AST_Node* symbols;
Intern_String* interns;
S64 interns_in_bytes;
S64 interns_inserted;
S64 interns_count;
U8* first_keyword;
U8* last_keyword;
Parser_Error default;
Parser_Error error;
Tokens token_array;
};

View File

@@ -1,15 +1,7 @@
function Decl *parse_decl(Parser *p);
function Decl *parse_struct(Parser *p, Token *name, Decl_Kind kind);
function Decl *parse_struct(Parser *p, Token *name, Decl_Kind kind, Decl_Struct_Kind);
function Typespec *parse_type(Parser *p);
function Typespec *
parse_type_struct(Parser *p, Token *token){
Decl_Kind kind = intern_compare(token->intern_val, keyword_struct) ? DECL_Struct : DECL_Union;
Decl *decl = parse_struct(p, token, kind);
decl->name = (Intern_String){};
return typespec_struct(p, token, decl);
}
function Typespec *
parse_type_function(Parser *p, Token *token){
Typespec *result = typespec_function(p, token, 0);
@@ -35,14 +27,13 @@ parse_type_function(Parser *p, Token *token){
function Typespec *
parse_type(Parser *p){
// Parse as function type or normal
Token *token = 0;
Typespec *result = 0;
if((token = token_match(p, TK_Identifier))){
result = typespec_name(p, token, token->intern_val);
}
else if((token = token_match_keyword(p, keyword_struct)) || (token = token_match_keyword(p, keyword_union))){
result = parse_type_struct(p, token);
}
else if((token = token_match(p, TK_OpenParen))){
result = parse_type_function(p, token);
}
@@ -51,6 +42,7 @@ parse_type(Parser *p){
return 0;
}
// Parse Pointer/Array
for(;;){
if((token = token_match(p, TK_Mul))){
result = typespec_pointer(p, token, result);
@@ -65,6 +57,8 @@ parse_type(Parser *p){
}
else break;
}
return result;
}
@@ -111,6 +105,14 @@ parse_notes(Parser *p){
return result;
}
function Token *
parse_get_token_name(Parser *p, S32 count){
Token *result = token_next(p);
for(S32 i = 0; i < count; i++)
token_next(p);
return result;
}
function Decl *
parse_enum(Parser *p, Token *name){
Typespec *type = 0;
@@ -132,18 +134,35 @@ parse_enum(Parser *p, Token *name){
}
function Decl *
parse_struct(Parser *p, Token *name, Decl_Kind kind){
Decl *result = decl_struct(p, kind, name, name->intern_val);
parse_struct(Parser *p, Token *name, Decl_Kind kind, Decl_Struct_Kind struct_kind){
Decl *result = decl_struct(p, kind, name, name->intern_val, struct_kind);
token_expect(p, TK_OpenBrace);
while(!token_is(p, TK_CloseBrace)){
Decl *decl = 0;
if((decl = parse_decl(p))){
decl_struct_push(result, decl);
}
else if(token_match_keyword(p, keyword_union)){
decl = parse_struct(p, token_get(p), DECL_Union, STRUCT_Nested);
}
else if(token_match_keyword(p, keyword_struct)){
decl = parse_struct(p, token_get(p), DECL_Struct, STRUCT_Nested);
}
else if(token_is(p, TK_Identifier) &&
token_peek_is(p, 1, TK_Colon) &&
token_peek_is_keyword(p, 2, keyword_union)){
decl = parse_struct(p, parse_get_token_name(p, 2), DECL_Union, STRUCT_Nested);
}
else if(token_is(p, TK_Identifier) &&
token_peek_is(p, 1, TK_Colon) &&
token_peek_is_keyword(p, 2, keyword_struct)){
decl = parse_struct(p, parse_get_token_name(p, 2), DECL_Struct, STRUCT_Nested);
}
else {
parser_push_error(p, token_get(p), "Unexpected token while parsing struct");
break;
}
if(decl) decl_struct_push(result, decl);
}
token_expect(p, TK_CloseBrace);
return result;
@@ -163,13 +182,29 @@ parse_typedef(Parser *p, Token *name){
return decl_typedef(p, name, name->intern_val, type);
}
function Token *
parse_get_token_name(Parser *p, S32 count){
Token *result = token_next(p);
for(S32 i = 0; i < count; i++)
token_next(p);
/*
function Decl *
parse_function(Parser *p, Token *name){
Decl *result = decl_function(p, name, name->intern_val, 0);
if(!token_is(p, TK_CloseParen)){
for(;;) {
if((name = token_match(p, TK_Identifier)))
decl_function_push(p, result, name, name->intern_val, parse_type(p));
else if(!token_match(p, TK_Comma))
break;
}
}
token_expect(p, TK_CloseParen);
if(token_is(p, TK_Identifier))
result->function_decl.ret = parse_type(p);
token_expect(p, TK_OpenBrace);
parse_stmt_list(p, result);
token_expect(p, TK_CloseBrace);
return result;
}
*/
function Decl *
parse_decl(Parser *p){
@@ -179,10 +214,10 @@ parse_decl(Parser *p){
if(token_is(p, TK_Identifier)){
if(token_peek_is(p, 1, TK_DoubleColon)){
if(token_peek_is_keyword(p, 2, keyword_struct)){
result = parse_struct(p, parse_get_token_name(p,2), DECL_Struct);
result = parse_struct(p, parse_get_token_name(p,2), DECL_Struct, STRUCT_Base);
}
else if(token_peek_is_keyword(p, 2, keyword_union)){
result = parse_struct(p, parse_get_token_name(p,2), DECL_Union);
result = parse_struct(p, parse_get_token_name(p,2), DECL_Union, STRUCT_Base);
}
else if(token_peek_is_keyword(p, 2, keyword_enum)){
result = parse_enum(p, parse_get_token_name(p,2));
@@ -193,8 +228,6 @@ parse_decl(Parser *p){
}
else if(token_peek_is(p, 1, TK_Colon)){
if(token_peek_is(p, 2, TK_Identifier) ||
token_peek_is_keyword(p, 2, keyword_union) ||
token_peek_is_keyword(p, 2, keyword_struct) ||
token_peek_is(p, 2, TK_OpenParen)){
result = parse_variable(p, parse_get_token_name(p,1));
}

View File

@@ -95,6 +95,9 @@ intern_tokens(Parser *p){
t->kind = TK_Keyword;
}
}
else if(t->kind == TK_U8Lit){
t->intern_val = intern_string(p, t->string);
}
else if(t->kind == TK_Error){
parser_push_error(p, t, (char *)t->error_val.str);
}

View File

@@ -91,9 +91,6 @@ expr_print(Parser *p, Expr *expr){
}
}
global S64 indent;
function B32
print_typespec(Parser *p, Typespec *spec){
switch(spec->kind) {
@@ -101,10 +98,6 @@ print_typespec(Parser *p, Typespec *spec){
lex_print("%s", spec->name.s.str);
} break;
case TS_Struct:{
print_decl(p, spec->struct_spec);
return false;
} break;
case TS_Pointer: {
print_typespec(p, spec->base);

34
sym.h Normal file
View File

@@ -0,0 +1,34 @@
typedef enum Symbol_Kind{
SYM_None,
SYM_Decl,
SYM_Type,
}Symbol_Kind;
typedef enum Symbol_State{
SYM_STATE_Used,
SYM_STATE_Declared,
}Symbol_State;
typedef struct Symbol{
Symbol_Kind kind;
Symbol_State state;
Symbol *next;
union{
Decl *decl;
struct{
Typespec *spec;
} type;
};
} Symbol;
// First stage would add all symbols as underspecified to the table
// Every encountered typespec would be added to the table as either specified or
// just as encountered name
//
// Then second stage would loop over all of them and report errors on all symbols that were
// found in the wild but not declared
//
//
//
//

38
test.cc
View File

@@ -1,5 +1,11 @@
#if 0
OpenGL :: struct{
glVertexAttribPointer: (GLuint, GLint, GLenum, GLboolean, GLsizei, GLvoid*);
glBindTexture: (GLenum, GLuint);
glDrawArrays: (GLenum, GLint, GLsizei);
}
OS_Memory::struct{
data: void*;
commit: SizeU;
@@ -89,11 +95,11 @@ Token_Kind::enum{
Token::struct{
kind:Token_Kind;
@using string:String;
val: union{
integer:S64;
error:String;
intern:Intern_String;
};
union{
integer_val:S64;
error_val:String;
intern_val:Intern_String;
}
file:String;
line:S64;
line_begin:U8*;
@@ -128,36 +134,36 @@ Expr:: struct{
kind: Expr_Kind;
token: Token*;
next : Expr*;
_: union{
union{
cast_val: struct{
type: AST_Node*;
expr: Expr*;
};
}
list: struct{
first: Expr *;
last: Expr *;
};
}
call: struct{
atom: Expr *;
list: Expr *;
};
}
index: struct{
atom: Expr *;
index: Expr *;
};
}
unary: struct{
expr: Expr* ;
};
}
binary: struct{
left: Expr* ;
right: Expr* ;
};
}
ternary: struct{
cond: Expr* ;
on_true: Expr*;
on_false: Expr*;
};
};
}
}
}
@prefix="AK_"
@@ -190,13 +196,13 @@ AST_Node::struct{
first_child: AST_Node*;
last_child: AST_Node*;
_:union{
union{
base_type_size: SizeU;
pointer: AST_Node*;
typedef_type: AST_Node*;
variable_type: AST_Node*;
func_return_type: AST_Node*;
};
}
}
Parser_Error :: struct{