Backup, new approach to ast
This commit is contained in:
149
ast.h
149
ast.h
@@ -1,5 +1,16 @@
|
|||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
|
OS_Memory:struct{
|
||||||
|
data: void*;
|
||||||
|
commit: SizeU;
|
||||||
|
reserve: SizeU;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arena:struct{
|
||||||
|
@using memory: OS_Memory;
|
||||||
|
len: U64;
|
||||||
|
alignment: U64;
|
||||||
|
}
|
||||||
|
|
||||||
String:struct{
|
String:struct{
|
||||||
str: U8*;
|
str: U8*;
|
||||||
@@ -7,6 +18,8 @@ String:struct{
|
|||||||
}
|
}
|
||||||
Intern_String:typedef String;
|
Intern_String:typedef String;
|
||||||
|
|
||||||
|
@stringify
|
||||||
|
@prefix="TK_"
|
||||||
Token_Kind:enum{
|
Token_Kind:enum{
|
||||||
@str="End of stream" End,
|
@str="End of stream" End,
|
||||||
@str="*" Mul,
|
@str="*" Mul,
|
||||||
@@ -73,13 +86,9 @@ Token_Kind:enum{
|
|||||||
Keyword,
|
Keyword,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Token:struct{
|
Token:struct{
|
||||||
kind:Token_Kind;
|
kind:Token_Kind;
|
||||||
union:{
|
@using string:String;
|
||||||
string:String;
|
|
||||||
struct:{str:U8*; len:U64;}
|
|
||||||
}
|
|
||||||
union:{
|
union:{
|
||||||
int_val:S64;
|
int_val:S64;
|
||||||
error_val:String;
|
error_val:String;
|
||||||
@@ -90,17 +99,79 @@ Token:struct{
|
|||||||
line_begin:U8*;
|
line_begin:U8*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tokens:struct{
|
||||||
|
@array tokens: Token*;
|
||||||
|
iter : S64;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lex_Stream:struct{
|
||||||
|
stream: U8*;
|
||||||
|
line_begin: U8*;
|
||||||
|
filename: String;
|
||||||
|
line: S64;
|
||||||
|
}
|
||||||
|
|
||||||
|
@prefix="EK_"
|
||||||
|
Expr_Kind: enum{
|
||||||
|
None,
|
||||||
|
Atom,
|
||||||
|
Unary,
|
||||||
|
Binary,
|
||||||
|
Ternary,
|
||||||
|
Cast,
|
||||||
|
List,
|
||||||
|
Call,
|
||||||
|
Index,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Expr: struct{
|
||||||
|
kind: Expr_Kind;
|
||||||
|
token: Token*;
|
||||||
|
next : Expr*;
|
||||||
|
union:{
|
||||||
|
cast: 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_"
|
||||||
AST_Kind:enum{
|
AST_Kind:enum{
|
||||||
|
None,
|
||||||
BaseType,
|
BaseType,
|
||||||
Typedef,
|
Typedef,
|
||||||
Enum,
|
Enum,
|
||||||
Struct,
|
Struct,
|
||||||
Union,
|
Union,
|
||||||
|
|
||||||
Note,
|
Note,
|
||||||
List,
|
List,
|
||||||
|
|
||||||
Pointer,
|
Pointer,
|
||||||
Array,
|
Array,
|
||||||
Function,
|
Function,
|
||||||
@@ -110,7 +181,8 @@ AST_Kind:enum{
|
|||||||
|
|
||||||
AST_Node:struct{
|
AST_Node:struct{
|
||||||
kind: AST_Kind;
|
kind: AST_Kind;
|
||||||
node: AST_Node[16];
|
pos : Token*;
|
||||||
|
name: Intern_String;
|
||||||
|
|
||||||
next: AST_Node*;
|
next: AST_Node*;
|
||||||
next_scope: AST_Node*;
|
next_scope: AST_Node*;
|
||||||
@@ -129,6 +201,66 @@ AST_Node:struct{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Parser_Error: struct{
|
||||||
|
next: Parser_Error*;
|
||||||
|
message: String;
|
||||||
|
token : Token *;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scope: struct{
|
||||||
|
next : Scope*;
|
||||||
|
first: AST_Node*;
|
||||||
|
last : AST_Node*;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser: struct{
|
||||||
|
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 *;
|
||||||
|
|
||||||
|
//@map(type="sparse") symbols: AST_Node;
|
||||||
|
|
||||||
|
// @Todo(Krzosa): This adds default to function name currently
|
||||||
|
// And it's hard to anything else sort of except adding
|
||||||
|
// a variable of _var_name_lower_with_ or something
|
||||||
|
@sllqueue default: Parser_Error;
|
||||||
|
|
||||||
|
// This works ok
|
||||||
|
@sllqueue error: Parser_Error;
|
||||||
|
@using token_array: Tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
@register_tag(sllqueue)
|
||||||
|
@params(next=next,last=last,first=first)
|
||||||
|
function void
|
||||||
|
struct_type_lower_var_name_lower_push(struct_type *parent, var_type *child){
|
||||||
|
if(parent->first == 0){
|
||||||
|
- parent->first = parent->last = child;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
- parent->last = parent->last->next = child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -144,6 +276,7 @@ typedef enum AST_Kind{
|
|||||||
AK_Struct,
|
AK_Struct,
|
||||||
AK_Union,
|
AK_Union,
|
||||||
|
|
||||||
|
AK_Identifier,
|
||||||
AK_Note,
|
AK_Note,
|
||||||
AK_List,
|
AK_List,
|
||||||
|
|
||||||
|
|||||||
29
common.c
29
common.c
@@ -5,6 +5,12 @@ clamp_top_s64(S64 val, S64 max){
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SizeU
|
||||||
|
clamp_top_sizeu(SizeU val, SizeU max){
|
||||||
|
if(val>max)return max;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
function SizeU
|
function SizeU
|
||||||
get_align_offset(SizeU size, SizeU align){
|
get_align_offset(SizeU size, SizeU align){
|
||||||
SizeU mask = align - 1;
|
SizeU mask = align - 1;
|
||||||
@@ -55,3 +61,26 @@ string_compare(String a, String b){
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function U8
|
||||||
|
char_to_lower(U8 c){
|
||||||
|
if(c >= 'A' && c <= 'Z')
|
||||||
|
c += 32;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function U8
|
||||||
|
char_to_upper(U8 c){
|
||||||
|
if(c >= 'a' && c <= 'z')
|
||||||
|
c -= 32;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function String
|
||||||
|
string_to_lower(Arena *arena, String string){
|
||||||
|
String result = arena_push_string_copy(arena, string);
|
||||||
|
for(S64 i = 0; i < string.len; i++){
|
||||||
|
result.str[i] = char_to_lower(result.str[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
67
lex.h
67
lex.h
@@ -106,6 +106,7 @@ typedef struct Lex_Stream{
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
global String token_kind_string[] = {
|
global String token_kind_string[] = {
|
||||||
[TK_End] = lit("End of stream"),
|
[TK_End] = lit("End of stream"),
|
||||||
[TK_Error] = lit("Error"),
|
[TK_Error] = lit("Error"),
|
||||||
@@ -170,3 +171,69 @@ global String token_kind_string[] = {
|
|||||||
[TK_Arrow] = lit("->"),
|
[TK_Arrow] = lit("->"),
|
||||||
[TK_ExprSizeof] = lit("sizeof"),
|
[TK_ExprSizeof] = lit("sizeof"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
global String Token_Kind_metadata[] = {
|
||||||
|
[TK_End] = lit("End of stream"),
|
||||||
|
[TK_Mul] = lit("*"),
|
||||||
|
[TK_Div] = lit("/"),
|
||||||
|
[TK_Add] = lit("+"),
|
||||||
|
[TK_Sub] = lit("-"),
|
||||||
|
[TK_Mod] = lit("%"),
|
||||||
|
[TK_BitAnd] = lit("&"),
|
||||||
|
[TK_BitOr] = lit("|"),
|
||||||
|
[TK_BitXor] = lit("^"),
|
||||||
|
[TK_Neg] = lit("~"),
|
||||||
|
[TK_Not] = lit("!"),
|
||||||
|
[TK_OpenParen] = lit("("),
|
||||||
|
[TK_CloseParen] = lit(" "),
|
||||||
|
[TK_OpenBrace] = lit("{"),
|
||||||
|
[TK_CloseBrace] = lit("}"),
|
||||||
|
[TK_OpenBracket] = lit("["),
|
||||||
|
[TK_CloseBracket] = lit("]"),
|
||||||
|
[TK_Comma] = lit(","),
|
||||||
|
[TK_Pound] = lit("#"),
|
||||||
|
[TK_Question] = lit("?"),
|
||||||
|
[TK_ThreeDots] = lit("..."),
|
||||||
|
[TK_Semicolon] = lit(";"),
|
||||||
|
[TK_Dot] = lit("."),
|
||||||
|
[TK_LesserThen] = lit("<"),
|
||||||
|
[TK_GreaterThen] = lit(">"),
|
||||||
|
[TK_Colon] = lit(":"),
|
||||||
|
[TK_Assign] = lit("="),
|
||||||
|
[TK_DivAssign] = lit("/="),
|
||||||
|
[TK_MulAssign] = lit("*="),
|
||||||
|
[TK_ModAssign] = lit("%="),
|
||||||
|
[TK_SubAssign] = lit("-="),
|
||||||
|
[TK_AddAssign] = lit("+="),
|
||||||
|
[TK_AndAssign] = lit("&="),
|
||||||
|
[TK_OrAssign] = lit("|="),
|
||||||
|
[TK_XorAssign] = lit("^="),
|
||||||
|
[TK_LeftShiftAssign] = lit("<<="),
|
||||||
|
[TK_RightShiftAssign] = lit(">>="),
|
||||||
|
[TK_DoubleColon] = lit("::"),
|
||||||
|
[TK_At] = lit("@"),
|
||||||
|
[TK_Decrement] = lit("--"),
|
||||||
|
[TK_Increment] = lit("++"),
|
||||||
|
[TK_PostDecrement] = lit("--"),
|
||||||
|
[TK_PostIncrement] = lit("++"),
|
||||||
|
[TK_LesserThenOrEqual] = lit("<="),
|
||||||
|
[TK_GreaterThenOrEqual] = lit(">="),
|
||||||
|
[TK_Equals] = lit("=="),
|
||||||
|
[TK_And] = lit("&&"),
|
||||||
|
[TK_Or] = lit("||"),
|
||||||
|
[TK_NotEquals] = lit("!="),
|
||||||
|
[TK_LeftShift] = lit("<<"),
|
||||||
|
[TK_RightShift] = lit(">>"),
|
||||||
|
[TK_Arrow] = lit("->"),
|
||||||
|
[TK_ExprSizeof] = lit("sizeof"),
|
||||||
|
[TK_DocComment] = lit("DocComment"),
|
||||||
|
[TK_Comment] = lit("Comment"),
|
||||||
|
[TK_Identifier] = lit("Identifier"),
|
||||||
|
[TK_StringLit] = lit("StringLit"),
|
||||||
|
[TK_U8Lit] = lit("U8Lit"),
|
||||||
|
[TK_Character] = lit("Character"),
|
||||||
|
[TK_Error] = lit("Error"),
|
||||||
|
[TK_Float] = lit("Float"),
|
||||||
|
[TK_Int] = lit("Int"),
|
||||||
|
[TK_Keyword] = lit("Keyword"),
|
||||||
|
};
|
||||||
|
|||||||
52
main.c
52
main.c
@@ -81,7 +81,7 @@ parser_test(){
|
|||||||
|
|
||||||
String exprs[] = {
|
String exprs[] = {
|
||||||
lit("(4+2*53)"),
|
lit("(4+2*53)"),
|
||||||
lit("((4+2)*53"),
|
lit("((4+2)*53)"),
|
||||||
lit("++5"),
|
lit("++5"),
|
||||||
lit("5--"), // @Todo(Krzosa):
|
lit("5--"), // @Todo(Krzosa):
|
||||||
lit("-5"),
|
lit("-5"),
|
||||||
@@ -95,18 +95,10 @@ parser_test(){
|
|||||||
parser_lex_stream(&p, exprs[i], lit("File"));
|
parser_lex_stream(&p, exprs[i], lit("File"));
|
||||||
Expr *expr = parse_expr(&p);
|
Expr *expr = parse_expr(&p);
|
||||||
assert(expr);
|
assert(expr);
|
||||||
expr_print(expr);
|
//expr_print(expr);
|
||||||
lex_print("\n");
|
//lex_print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
String decls =
|
|
||||||
lit("@Test(a=\"thing\") @str=\"based\" Thing:enum{ Thing_1 = 1<<10, Thing_2 = 10 }"
|
|
||||||
"TTT:struct{ thing:U64; nested:struct{ thing:S64; }}"
|
|
||||||
""
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
String decls = os_read_file(lit("ast.h"));
|
String decls = os_read_file(lit("ast.h"));
|
||||||
parser_lex_stream(&p, decls, lit("File"));
|
parser_lex_stream(&p, decls, lit("File"));
|
||||||
AST_Node *node = parse(&p);
|
AST_Node *node = parse(&p);
|
||||||
@@ -114,6 +106,32 @@ parser_test(){
|
|||||||
assert(node->last_child);
|
assert(node->last_child);
|
||||||
ast_print(node);
|
ast_print(node);
|
||||||
|
|
||||||
|
for(AST_Node *n = node->first_child; n; n=n->next){
|
||||||
|
if(n->kind == AK_Enum){
|
||||||
|
AST_Node *prefix = ast_find_note(n, lit("prefix"));
|
||||||
|
lex_print("global String %s_metadata[] = {\n", n->name.s.str);
|
||||||
|
for(AST_Node *member = n->first_child; member; member=member->next){
|
||||||
|
lex_print("[");
|
||||||
|
if(prefix) expr_print(prefix->expr);
|
||||||
|
lex_print("%s] = ", member->name.s.str);
|
||||||
|
AST_Node *str = ast_find_note(member, lit("str"));
|
||||||
|
lex_print("lit(\"");
|
||||||
|
if(str){
|
||||||
|
expr_print(str->expr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lex_print("%s", member->name.s.str);
|
||||||
|
}
|
||||||
|
lex_print("\")");
|
||||||
|
lex_print(",\n");
|
||||||
|
}
|
||||||
|
lex_print("};\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(n->kind == AK_Struct){
|
||||||
|
gen_struct(n, (Intern_String){});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function S32
|
function S32
|
||||||
@@ -123,6 +141,18 @@ os_main(){
|
|||||||
lex_test();
|
lex_test();
|
||||||
parser_test();
|
parser_test();
|
||||||
|
|
||||||
|
String_Map maps[] = {
|
||||||
|
{lit("cap"), lit("cap")},
|
||||||
|
{lit("len"), lit("len")},
|
||||||
|
{lit("data"), lit("tokens")},
|
||||||
|
{lit("parent_type"), lit("Tokens")},
|
||||||
|
{lit("parent_type_lower"), lit("tokens")},
|
||||||
|
{lit("var_type_lower"), lit("token")},
|
||||||
|
{lit("var_type"), lit("Token")},
|
||||||
|
{lit("var_name"), lit("tokens")},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
String keywords[]={
|
String keywords[]={
|
||||||
lit("S64"),
|
lit("S64"),
|
||||||
|
|||||||
42
memory.c
42
memory.c
@@ -40,6 +40,23 @@ arena_push_size(Arena *a, SizeU size){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
arena_pop_pos(Arena *arena, SizeU pos){
|
||||||
|
pos = clamp_top_sizeu(pos, arena->len);
|
||||||
|
arena->len = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Arena_Checkpoint
|
||||||
|
arena_checkpoint(Arena *arena){
|
||||||
|
Arena_Checkpoint result = {arena, arena->len};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
arena_restore(Arena_Checkpoint checkpoint){
|
||||||
|
arena_pop_pos(checkpoint.arena, checkpoint.pos);
|
||||||
|
}
|
||||||
|
|
||||||
function String
|
function String
|
||||||
arena_push_string_copy(Arena *arena, String string){
|
arena_push_string_copy(Arena *arena, String string){
|
||||||
U8 *copy = arena_push_array(arena, U8, string.len+1);
|
U8 *copy = arena_push_array(arena, U8, string.len+1);
|
||||||
@@ -47,3 +64,28 @@ arena_push_string_copy(Arena *arena, String string){
|
|||||||
copy[string.len] = 0;
|
copy[string.len] = 0;
|
||||||
return (String){copy, string.len};
|
return (String){copy, string.len};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function String
|
||||||
|
string_fmtv(Arena *arena, const char *str, va_list args1) {
|
||||||
|
va_list args2;
|
||||||
|
va_copy(args2, args1);
|
||||||
|
U64 len = vsnprintf(0, 0, str, args2);
|
||||||
|
va_end(args2);
|
||||||
|
|
||||||
|
char *result = (char *)arena_push_size(arena, len + 1);
|
||||||
|
vsnprintf(result, len + 1, str, args1);
|
||||||
|
if (arena->len > 0)
|
||||||
|
arena->len -= 1;
|
||||||
|
|
||||||
|
return (String){(U8 *)result, len};
|
||||||
|
}
|
||||||
|
|
||||||
|
function String
|
||||||
|
string_fmt(Arena *arena, const char *str, ...) {
|
||||||
|
va_list args1;
|
||||||
|
va_start(args1, str);
|
||||||
|
String result = string_fmtv(arena, str, args1);
|
||||||
|
va_end(args1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
5
memory.h
5
memory.h
@@ -5,6 +5,11 @@ typedef struct Arena{
|
|||||||
U64 alignment;
|
U64 alignment;
|
||||||
}Arena;
|
}Arena;
|
||||||
|
|
||||||
|
typedef struct Arena_Checkpoint{
|
||||||
|
Arena *arena;
|
||||||
|
SizeU pos;
|
||||||
|
} Arena_Checkpoint;
|
||||||
|
|
||||||
function B32 string_compare(String a, String b);
|
function B32 string_compare(String a, String b);
|
||||||
function void *arena_push_size(Arena *a, SizeU size);
|
function void *arena_push_size(Arena *a, SizeU size);
|
||||||
function String arena_push_string_copy(Arena *arena, String string);
|
function String arena_push_string_copy(Arena *arena, String string);
|
||||||
|
|||||||
449
output.cc
449
output.cc
@@ -1,129 +1,166 @@
|
|||||||
(4+(2*53))
|
typedef struct OS_Memory OS_Memory;
|
||||||
Error: Expected token of kind: ), got instead token of kind: End of stream
|
struct OS_Memory{
|
||||||
((4+2)*53)
|
void *data;
|
||||||
(++5)
|
SizeU commit;
|
||||||
(--5)
|
SizeU reserve;
|
||||||
(-5)
|
};
|
||||||
(+5)
|
|
||||||
(()5)
|
typedef struct Arena Arena;
|
||||||
((()5)+3)
|
struct Arena{
|
||||||
((534>43)?435:42)
|
union{
|
||||||
(((534>43)?435:42),234,(()42),Thing[10][2],Thing(1,2))
|
OS_Memory memory;
|
||||||
|
struct {
|
||||||
|
void *data;
|
||||||
|
SizeU commit;
|
||||||
|
SizeU reserve;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
U64 len;
|
||||||
|
U64 alignment;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct String String;
|
typedef struct String String;
|
||||||
struct String{
|
struct String{
|
||||||
U8 *str;
|
U8 *str;
|
||||||
S64 len;
|
S64 len;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Intern_String;
|
typedef String Intern_String;
|
||||||
enum Token_Kind{
|
typedef enum Token_Kind{
|
||||||
End,
|
TK_End,
|
||||||
Mul,
|
TK_Mul,
|
||||||
Div,
|
TK_Div,
|
||||||
Add,
|
TK_Add,
|
||||||
Sub,
|
TK_Sub,
|
||||||
Mod,
|
TK_Mod,
|
||||||
BitAnd,
|
TK_BitAnd,
|
||||||
BitOr,
|
TK_BitOr,
|
||||||
BitXor,
|
TK_BitXor,
|
||||||
Neg,
|
TK_Neg,
|
||||||
Not,
|
TK_Not,
|
||||||
OpenParen,
|
TK_OpenParen,
|
||||||
CloseParen,
|
TK_CloseParen,
|
||||||
OpenBrace,
|
TK_OpenBrace,
|
||||||
CloseBrace,
|
TK_CloseBrace,
|
||||||
OpenBracket,
|
TK_OpenBracket,
|
||||||
CloseBracket,
|
TK_CloseBracket,
|
||||||
Comma,
|
TK_Comma,
|
||||||
Pound,
|
TK_Pound,
|
||||||
Question,
|
TK_Question,
|
||||||
ThreeDots,
|
TK_ThreeDots,
|
||||||
Semicolon,
|
TK_Semicolon,
|
||||||
Dot,
|
TK_Dot,
|
||||||
LesserThen,
|
TK_LesserThen,
|
||||||
GreaterThen,
|
TK_GreaterThen,
|
||||||
Colon,
|
TK_Colon,
|
||||||
Assign,
|
TK_Assign,
|
||||||
DivAssign,
|
TK_DivAssign,
|
||||||
MulAssign,
|
TK_MulAssign,
|
||||||
ModAssign,
|
TK_ModAssign,
|
||||||
SubAssign,
|
TK_SubAssign,
|
||||||
AddAssign,
|
TK_AddAssign,
|
||||||
AndAssign,
|
TK_AndAssign,
|
||||||
OrAssign,
|
TK_OrAssign,
|
||||||
XorAssign,
|
TK_XorAssign,
|
||||||
LeftShiftAssign,
|
TK_LeftShiftAssign,
|
||||||
RightShiftAssign,
|
TK_RightShiftAssign,
|
||||||
DoubleColon,
|
TK_DoubleColon,
|
||||||
At,
|
TK_At,
|
||||||
Decrement,
|
TK_Decrement,
|
||||||
Increment,
|
TK_Increment,
|
||||||
PostDecrement,
|
TK_PostDecrement,
|
||||||
PostIncrement,
|
TK_PostIncrement,
|
||||||
LesserThenOrEqual,
|
TK_LesserThenOrEqual,
|
||||||
GreaterThenOrEqual,
|
TK_GreaterThenOrEqual,
|
||||||
Equals,
|
TK_Equals,
|
||||||
And,
|
TK_And,
|
||||||
Or,
|
TK_Or,
|
||||||
NotEquals,
|
TK_NotEquals,
|
||||||
LeftShift,
|
TK_LeftShift,
|
||||||
RightShift,
|
TK_RightShift,
|
||||||
Arrow,
|
TK_Arrow,
|
||||||
ExprSizeof,
|
TK_ExprSizeof,
|
||||||
DocComment,
|
TK_DocComment,
|
||||||
Comment,
|
TK_Comment,
|
||||||
Identifier,
|
TK_Identifier,
|
||||||
StringLit,
|
TK_StringLit,
|
||||||
U8Lit,
|
TK_U8Lit,
|
||||||
Character,
|
TK_Character,
|
||||||
Error,
|
TK_Error,
|
||||||
Float,
|
TK_Float,
|
||||||
Int,
|
TK_Int,
|
||||||
Keyword,
|
TK_Keyword,
|
||||||
}
|
}Token_Kind;
|
||||||
|
|
||||||
typedef struct Token Token;
|
typedef struct Token Token;
|
||||||
struct Token{
|
struct Token{
|
||||||
Token_Kind kind;
|
Token_Kind kind;
|
||||||
union {
|
union{
|
||||||
String string;
|
String string;
|
||||||
struct {
|
struct {
|
||||||
U8 *str;
|
U8 *str;
|
||||||
U64 len;
|
S64 len;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
S64 int_val;
|
S64 int_val;
|
||||||
String error_val;
|
String error_val;
|
||||||
String intern_val;
|
Intern_String intern_val;
|
||||||
};
|
};
|
||||||
|
|
||||||
String file;
|
String file;
|
||||||
S64 line;
|
S64 line;
|
||||||
U8 *line_begin;
|
U8 *line_begin;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AST_Kind{
|
typedef struct Tokens Tokens;
|
||||||
BaseType,
|
struct Tokens{
|
||||||
Typedef,
|
Token *tokens;
|
||||||
Enum,
|
S64 len;
|
||||||
Struct,
|
S64 cap;
|
||||||
Union,
|
S64 iter;
|
||||||
Note,
|
};
|
||||||
List,
|
|
||||||
Pointer,
|
typedef struct Lex_Stream Lex_Stream;
|
||||||
Array,
|
struct Lex_Stream{
|
||||||
Function,
|
U8 *stream;
|
||||||
Variable,
|
U8 *line_begin;
|
||||||
EnumChild,
|
String filename;
|
||||||
}
|
S64 line;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum Expr_Kind{
|
||||||
|
EK_None,
|
||||||
|
EK_Atom,
|
||||||
|
EK_Unary,
|
||||||
|
EK_Binary,
|
||||||
|
EK_Ternary,
|
||||||
|
EK_Cast,
|
||||||
|
EK_List,
|
||||||
|
EK_Call,
|
||||||
|
EK_Index,
|
||||||
|
}Expr_Kind;
|
||||||
|
|
||||||
|
typedef 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,
|
||||||
|
}AST_Kind;
|
||||||
|
|
||||||
typedef struct AST_Node AST_Node;
|
typedef struct AST_Node AST_Node;
|
||||||
struct AST_Node{
|
struct AST_Node{
|
||||||
AST_Kind kind;
|
AST_Kind kind;
|
||||||
AST_Node node[16];
|
Token *pos;
|
||||||
|
Intern_String name;
|
||||||
AST_Node *next;
|
AST_Node *next;
|
||||||
AST_Node *next_scope;
|
AST_Node *next_scope;
|
||||||
AST_Node *first_note;
|
AST_Node *first_note;
|
||||||
@@ -137,6 +174,218 @@ AST_Node *typedef_type;
|
|||||||
AST_Node *variable_type;
|
AST_Node *variable_type;
|
||||||
AST_Node *func_return_type;
|
AST_Node *func_return_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct Parser_Error Parser_Error;
|
||||||
|
struct Parser_Error{
|
||||||
|
Parser_Error *next;
|
||||||
|
String message;
|
||||||
|
Token *token;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Scope Scope;
|
||||||
|
struct Scope{
|
||||||
|
Scope *next;
|
||||||
|
AST_Node *first;
|
||||||
|
AST_Node *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Parser Parser;
|
||||||
|
struct Parser{
|
||||||
|
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 *first_default;
|
||||||
|
Parser_Error *last_default;
|
||||||
|
|
||||||
|
Parser_Error *first_error;
|
||||||
|
Parser_Error *last_error;
|
||||||
|
|
||||||
|
union{
|
||||||
|
Tokens token_array;
|
||||||
|
struct {
|
||||||
|
Token *tokens;
|
||||||
|
S64 len;
|
||||||
|
S64 cap;
|
||||||
|
S64 iter;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
global String Token_Kind_metadata[] = {
|
||||||
|
[TK_End] = lit("End of stream"),
|
||||||
|
[TK_Mul] = lit("*"),
|
||||||
|
[TK_Div] = lit("/"),
|
||||||
|
[TK_Add] = lit("+"),
|
||||||
|
[TK_Sub] = lit("-"),
|
||||||
|
[TK_Mod] = lit("%"),
|
||||||
|
[TK_BitAnd] = lit("&"),
|
||||||
|
[TK_BitOr] = lit("|"),
|
||||||
|
[TK_BitXor] = lit("^"),
|
||||||
|
[TK_Neg] = lit("~"),
|
||||||
|
[TK_Not] = lit("!"),
|
||||||
|
[TK_OpenParen] = lit("("),
|
||||||
|
[TK_CloseParen] = lit(" "),
|
||||||
|
[TK_OpenBrace] = lit("{"),
|
||||||
|
[TK_CloseBrace] = lit("}"),
|
||||||
|
[TK_OpenBracket] = lit("["),
|
||||||
|
[TK_CloseBracket] = lit("]"),
|
||||||
|
[TK_Comma] = lit(","),
|
||||||
|
[TK_Pound] = lit("#"),
|
||||||
|
[TK_Question] = lit("?"),
|
||||||
|
[TK_ThreeDots] = lit("..."),
|
||||||
|
[TK_Semicolon] = lit(";"),
|
||||||
|
[TK_Dot] = lit("."),
|
||||||
|
[TK_LesserThen] = lit("<"),
|
||||||
|
[TK_GreaterThen] = lit(">"),
|
||||||
|
[TK_Colon] = lit(":"),
|
||||||
|
[TK_Assign] = lit("="),
|
||||||
|
[TK_DivAssign] = lit("/="),
|
||||||
|
[TK_MulAssign] = lit("*="),
|
||||||
|
[TK_ModAssign] = lit("%="),
|
||||||
|
[TK_SubAssign] = lit("-="),
|
||||||
|
[TK_AddAssign] = lit("+="),
|
||||||
|
[TK_AndAssign] = lit("&="),
|
||||||
|
[TK_OrAssign] = lit("|="),
|
||||||
|
[TK_XorAssign] = lit("^="),
|
||||||
|
[TK_LeftShiftAssign] = lit("<<="),
|
||||||
|
[TK_RightShiftAssign] = lit(">>="),
|
||||||
|
[TK_DoubleColon] = lit("::"),
|
||||||
|
[TK_At] = lit("@"),
|
||||||
|
[TK_Decrement] = lit("--"),
|
||||||
|
[TK_Increment] = lit("++"),
|
||||||
|
[TK_PostDecrement] = lit("--"),
|
||||||
|
[TK_PostIncrement] = lit("++"),
|
||||||
|
[TK_LesserThenOrEqual] = lit("<="),
|
||||||
|
[TK_GreaterThenOrEqual] = lit(">="),
|
||||||
|
[TK_Equals] = lit("=="),
|
||||||
|
[TK_And] = lit("&&"),
|
||||||
|
[TK_Or] = lit("||"),
|
||||||
|
[TK_NotEquals] = lit("!="),
|
||||||
|
[TK_LeftShift] = lit("<<"),
|
||||||
|
[TK_RightShift] = lit(">>"),
|
||||||
|
[TK_Arrow] = lit("->"),
|
||||||
|
[TK_ExprSizeof] = lit("sizeof"),
|
||||||
|
[TK_DocComment] = lit("DocComment"),
|
||||||
|
[TK_Comment] = lit("Comment"),
|
||||||
|
[TK_Identifier] = lit("Identifier"),
|
||||||
|
[TK_StringLit] = lit("StringLit"),
|
||||||
|
[TK_U8Lit] = lit("U8Lit"),
|
||||||
|
[TK_Character] = lit("Character"),
|
||||||
|
[TK_Error] = lit("Error"),
|
||||||
|
[TK_Float] = lit("Float"),
|
||||||
|
[TK_Int] = lit("Int"),
|
||||||
|
[TK_Keyword] = lit("Keyword"),
|
||||||
|
};
|
||||||
|
function
|
||||||
|
Token*Tokens_array_push_empty(Tokens*a){
|
||||||
|
if(a->cap==0){
|
||||||
|
a->cap=1024;
|
||||||
|
a->tokens=malloc(sizeof(Token)*a->cap);
|
||||||
|
}
|
||||||
|
else if(a->len+1>a->cap){
|
||||||
|
a->cap*=2;
|
||||||
|
a->tokens=realloc(a->tokens,sizeof(Token)*a->cap);
|
||||||
|
}
|
||||||
|
Token*result=a->tokens+a->len++;
|
||||||
|
memory_zero(result,sizeof(*result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
global String Expr_Kind_metadata[] = {
|
||||||
|
[EK_None] = lit("None"),
|
||||||
|
[EK_Atom] = lit("Atom"),
|
||||||
|
[EK_Unary] = lit("Unary"),
|
||||||
|
[EK_Binary] = lit("Binary"),
|
||||||
|
[EK_Ternary] = lit("Ternary"),
|
||||||
|
[EK_Cast] = lit("Cast"),
|
||||||
|
[EK_List] = lit("List"),
|
||||||
|
[EK_Call] = lit("Call"),
|
||||||
|
[EK_Index] = lit("Index"),
|
||||||
|
};
|
||||||
|
global String AST_Kind_metadata[] = {
|
||||||
|
[AK_None] = lit("None"),
|
||||||
|
[AK_BaseType] = lit("BaseType"),
|
||||||
|
[AK_Typedef] = lit("Typedef"),
|
||||||
|
[AK_Enum] = lit("Enum"),
|
||||||
|
[AK_Struct] = lit("Struct"),
|
||||||
|
[AK_Union] = lit("Union"),
|
||||||
|
[AK_Note] = lit("Note"),
|
||||||
|
[AK_List] = lit("List"),
|
||||||
|
[AK_Pointer] = lit("Pointer"),
|
||||||
|
[AK_Array] = lit("Array"),
|
||||||
|
[AK_Function] = lit("Function"),
|
||||||
|
[AK_Variable] = lit("Variable"),
|
||||||
|
[AK_EnumChild] = lit("EnumChild"),
|
||||||
|
};
|
||||||
|
function
|
||||||
|
void parser_default_push(Parser*parent,Parser_Error*child){
|
||||||
|
if(parent->first==0){
|
||||||
|
parent->first=parent->last=child;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
parent->last=parent->last->next=child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function
|
||||||
|
Parser_Error*parser_default_pop_first(Parser*parent){
|
||||||
|
if(parent->first==parent->last){
|
||||||
|
Parser_Error*node=parent->first;
|
||||||
|
parent->first=parent->last=0;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
else if(parent->first){
|
||||||
|
Parser_Error*node=parent->first;
|
||||||
|
parent->first=parent->first->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
void parser_error_push(Parser*parent,Parser_Error*child){
|
||||||
|
if(parent->first_error==0){
|
||||||
|
parent->first_error=parent->last_error=child;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
parent->last_error=parent->last_error->next_error=child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function
|
||||||
|
Parser_Error*parser_error_pop_first(Parser*parent){
|
||||||
|
if(parent->first_error==parent->last_error){
|
||||||
|
Parser_Error*node=parent->first_error;
|
||||||
|
parent->first_error=parent->last_error=0;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
else if(parent->first_error){
|
||||||
|
Parser_Error*node=parent->first_error;
|
||||||
|
parent->first_error=parent->first_error->next_error;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
Token*Parser_array_push_empty(Parser*a){
|
||||||
|
if(a->cap==0){
|
||||||
|
a->cap=1024;
|
||||||
|
a->tokens=malloc(sizeof(Token)*a->cap);
|
||||||
|
}
|
||||||
|
else if(a->len+1>a->cap){
|
||||||
|
a->cap*=2;
|
||||||
|
a->tokens=realloc(a->tokens,sizeof(Token)*a->cap);
|
||||||
|
}
|
||||||
|
Token*result=a->tokens+a->len++;
|
||||||
|
memory_zero(result,sizeof(*result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
212
print.c
212
print.c
@@ -87,7 +87,7 @@ ast_get_basis_type(AST_Node *node){
|
|||||||
switch(node->kind) {
|
switch(node->kind) {
|
||||||
case AK_Struct: case AK_Union: case AK_Enum: case AK_BaseType:{return node;} break;
|
case AK_Struct: case AK_Union: case AK_Enum: case AK_BaseType:{return node;} break;
|
||||||
case AK_Function:{return node;} break;
|
case AK_Function:{return node;} break;
|
||||||
case AK_Typedef:{return node->typedef_type;} break;
|
case AK_Typedef:{return node;} break;
|
||||||
case AK_Array: case AK_Pointer:{return ast_get_basis_type(node->pointer);} break;
|
case AK_Array: case AK_Pointer:{return ast_get_basis_type(node->pointer);} break;
|
||||||
default: invalid_codepath;
|
default: invalid_codepath;
|
||||||
}
|
}
|
||||||
@@ -149,6 +149,29 @@ ast_print_var(AST_Node *node){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AST_Node *
|
||||||
|
ast_find_note(AST_Node *node, String string){
|
||||||
|
for(AST_Node *n = node->first_note; n; n=n->next){
|
||||||
|
if(string_compare(n->name.s, string)){
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function String
|
||||||
|
ast_find_string(AST_Node *node, String string, String default_val){
|
||||||
|
AST_Node *find = ast_find_note(node, string);
|
||||||
|
if(find){
|
||||||
|
if(find->expr->kind == EK_Atom){
|
||||||
|
return find->expr->token->string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return default_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
global Arena todo_arena;
|
||||||
|
|
||||||
function void
|
function void
|
||||||
ast__print(AST_Node *node, S64 indent){
|
ast__print(AST_Node *node, S64 indent){
|
||||||
switch(node->kind){
|
switch(node->kind){
|
||||||
@@ -166,12 +189,40 @@ ast__print(AST_Node *node, S64 indent){
|
|||||||
if(indent == 0) lex_print("typedef %s %s %s;\n", type, node->name.s.str, node->name.s.str);
|
if(indent == 0) lex_print("typedef %s %s %s;\n", type, node->name.s.str, node->name.s.str);
|
||||||
lex_print("%s %s{\n", type, indent == 0 ? node->name.s.str:(U8 *)"");
|
lex_print("%s %s{\n", type, indent == 0 ? node->name.s.str:(U8 *)"");
|
||||||
for(AST_Node *n = node->first_child; n; n=n->next){
|
for(AST_Node *n = node->first_child; n; n=n->next){
|
||||||
|
AST_Node *using_note = ast_find_note(n, lit("using"));
|
||||||
|
AST_Node *array_note = ast_find_note(n, lit("array"));
|
||||||
|
AST_Node *sllqueue_note = ast_find_note(n, lit("sllqueue"));
|
||||||
|
if(using_note) {
|
||||||
|
assert(n->kind == AK_Variable);
|
||||||
|
lex_print("union{\n");
|
||||||
ast__print(n, indent+2);
|
ast__print(n, indent+2);
|
||||||
lex_print("\n");
|
lex_print("\n");
|
||||||
|
Intern_String name = n->variable_type->name;
|
||||||
|
n->variable_type->name = (Intern_String){0};
|
||||||
|
assert(n->variable_type->kind == AK_Struct || n->variable_type->kind == AK_Union);
|
||||||
|
ast__print(n->variable_type, indent+2);
|
||||||
|
n->variable_type->name = name;
|
||||||
|
lex_print("\n}");
|
||||||
|
}
|
||||||
|
else if(array_note){
|
||||||
|
AST_Node *cap = ast_find_note(n, lit("cap"));
|
||||||
|
AST_Node *len = ast_find_note(n, lit("len"));
|
||||||
|
ast__print(n, indent+2);
|
||||||
|
lex_print("\nS64 len;\nS64 cap;");
|
||||||
|
}
|
||||||
|
else if(sllqueue_note){
|
||||||
|
lex_print("%s *first_%s;\n", n->variable_type->name.s.str, string_to_lower(&todo_arena, n->name.s).str);
|
||||||
|
lex_print("%s *last_%s;\n", n->variable_type->name.s.str, string_to_lower(&todo_arena, n->name.s).str);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ast__print(n, indent+2);
|
||||||
|
}
|
||||||
|
lex_print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
lex_print("}");
|
lex_print("}");
|
||||||
lex_print("%s;\n", indent == 0 ? (U8 *)"":node->name.s.str?node->name.s.str:(U8*)"");
|
lex_print("%s;", indent == 0 ? (U8 *)"":node->name.s.str?node->name.s.str:(U8*)"");
|
||||||
|
if(indent == 0) lex_new_line();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AK_Variable:{
|
case AK_Variable:{
|
||||||
@@ -182,15 +233,20 @@ ast__print(AST_Node *node, S64 indent){
|
|||||||
|
|
||||||
case AK_Typedef:{
|
case AK_Typedef:{
|
||||||
lex_print("typedef ");
|
lex_print("typedef ");
|
||||||
lex_print("%s;", node->name.s.str);
|
ast_print_var(node);
|
||||||
|
lex_print(";");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AK_Enum:{
|
case AK_Enum:{
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
lex_print("enum %s{\n", node->name.s.str);
|
lex_print("typedef enum %s{\n", node->name.s.str);
|
||||||
|
AST_Node *prefix = ast_find_note(node, lit("prefix"));
|
||||||
|
|
||||||
for(AST_Node *n = node->first_child; n; n=n->next){
|
for(AST_Node *n = node->first_child; n; n=n->next){
|
||||||
print_indent(indent+2);
|
print_indent(indent+2);
|
||||||
|
if(prefix){
|
||||||
|
expr_print(prefix->expr);
|
||||||
|
}
|
||||||
lex_print("%s", n->name.s.str);
|
lex_print("%s", n->name.s.str);
|
||||||
if(n->expr){
|
if(n->expr){
|
||||||
lex_print(" = ");
|
lex_print(" = ");
|
||||||
@@ -200,7 +256,7 @@ ast__print(AST_Node *node, S64 indent){
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
lex_print("}\n");
|
lex_print("}%s;\n", node->name.s.str);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: invalid_codepath;
|
default: invalid_codepath;
|
||||||
@@ -211,3 +267,149 @@ function void
|
|||||||
ast_print(AST_Node *node){
|
ast_print(AST_Node *node){
|
||||||
ast__print(node, 0);
|
ast__print(node, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function B32
|
||||||
|
intern_is_empty(Intern_String string){
|
||||||
|
if(string.s.str == 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct String_Map{
|
||||||
|
String replace;
|
||||||
|
String with;
|
||||||
|
}String_Map;
|
||||||
|
|
||||||
|
function B32
|
||||||
|
token_is_number(Token *token){
|
||||||
|
B32 result = token->kind == TK_Int;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
print_string_replaced(String string, String_Map *maps, SizeU count){
|
||||||
|
Tokens tokens = lex_stream(string, lit("Replace"));
|
||||||
|
for(S64 i = 0; i < tokens.len; i++){
|
||||||
|
Token *t = tokens.tokens + i;
|
||||||
|
if(t->kind == TK_At) continue;
|
||||||
|
for(String_Map *map = maps; map != maps+count; map++){
|
||||||
|
if(string_compare(map->replace, t->string)){
|
||||||
|
t->string = map->with;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lex_print("%.*s", (S32)t->string.len, t->string.str);
|
||||||
|
if(t->kind == TK_Keyword) lex_print(" ");
|
||||||
|
if(t->kind == TK_Identifier &&
|
||||||
|
(t[1].kind== TK_Identifier || token_is_number(t+1))) lex_print(" ");
|
||||||
|
if(t->kind == TK_OpenBrace) lex_print("\n");
|
||||||
|
if(t->kind == TK_CloseBrace) lex_print("\n");
|
||||||
|
if(t->kind == TK_Semicolon) lex_print("\n");
|
||||||
|
}
|
||||||
|
free(tokens.tokens);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
gen_struct(AST_Node *n, Intern_String shadow_type_name){
|
||||||
|
for(AST_Node *member = n->first_child; member; member=member->next){
|
||||||
|
AST_Node *using_note = ast_find_note(member, lit("using"));
|
||||||
|
AST_Node *array_note = ast_find_note(member, lit("array"));
|
||||||
|
AST_Node *sllqueue_note = ast_find_note(member, lit("sllqueue"));
|
||||||
|
if(using_note){
|
||||||
|
gen_struct(member->variable_type, n->name);
|
||||||
|
}
|
||||||
|
if(array_note){
|
||||||
|
AST_Node *array_type = ast_get_basis_type(member->variable_type);
|
||||||
|
|
||||||
|
Intern_String type_name = n->name;
|
||||||
|
if(!intern_is_empty(shadow_type_name))
|
||||||
|
type_name = shadow_type_name;
|
||||||
|
|
||||||
|
|
||||||
|
String_Map maps[] = {
|
||||||
|
{lit("function"), lit("function\n")},
|
||||||
|
{lit("base_type"), type_name.s},
|
||||||
|
{lit("base_type_lower"), string_to_lower(&todo_arena, type_name.s)},
|
||||||
|
{lit("var_type"), array_type->name.s},
|
||||||
|
{lit("var_type_lower"), string_to_lower(&todo_arena, array_type->name.s)},
|
||||||
|
{lit("var_name"), member->name.s},
|
||||||
|
{lit("var_name_lower"), string_to_lower(&todo_arena, member->name.s)},
|
||||||
|
{lit("len"), ast_find_string(array_note, lit("len"), lit("len"))},
|
||||||
|
{lit("cap"), ast_find_string(array_note, lit("cap"), lit("cap"))},
|
||||||
|
{lit("data"), ast_find_string(array_note, lit("data"), lit("data"))},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
String a
|
||||||
|
= lit("function var_type *base_type@_array_push_empty(base_type *a){"
|
||||||
|
"if(a->cap == 0){\n"
|
||||||
|
" a->cap = 1024;\n"
|
||||||
|
" a->tokens = malloc(sizeof(var_type)*a->cap);\n"
|
||||||
|
"}\n"
|
||||||
|
"else if(a->len+1 > a->cap){\n"
|
||||||
|
" a->cap *= 2;\n"
|
||||||
|
" a->tokens = realloc(a->tokens, sizeof(var_type)*a->cap);\n"
|
||||||
|
"}\n"
|
||||||
|
|
||||||
|
"var_type *result = a->tokens + a->len++;\n"
|
||||||
|
"memory_zero(result, sizeof(*result));\n"
|
||||||
|
"return result;}");
|
||||||
|
print_string_replaced(a, maps, buff_cap(maps));
|
||||||
|
}
|
||||||
|
if(sllqueue_note){
|
||||||
|
String default_first = lit("first");
|
||||||
|
String default_last = lit("last");
|
||||||
|
String default_next = lit("next");
|
||||||
|
if(!string_compare(member->name.s, lit("default"))){
|
||||||
|
default_first = string_fmt(&todo_arena, "first_%s", member->name.s.str);
|
||||||
|
default_last = string_fmt(&todo_arena, "last_%s", member->name.s.str);
|
||||||
|
default_next = string_fmt(&todo_arena, "next_%s", member->name.s.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
String_Map maps[] = {
|
||||||
|
{lit("function"), lit("function\n")},
|
||||||
|
{lit("base_type"), n->name.s},
|
||||||
|
{lit("base_type_lower"), string_to_lower(&todo_arena, n->name.s)},
|
||||||
|
{lit("var_type"), member->variable_type->name.s},
|
||||||
|
{lit("var_type_lower"), string_to_lower(&todo_arena, member->variable_type->name.s)},
|
||||||
|
{lit("var_name"), member->name.s},
|
||||||
|
{lit("var_name_lower"), string_to_lower(&todo_arena, member->name.s)},
|
||||||
|
{lit("next"), ast_find_string(sllqueue_note, lit("next"), default_next)},
|
||||||
|
{lit("first"), ast_find_string(sllqueue_note, lit("first"), default_first)},
|
||||||
|
{lit("last"), ast_find_string(sllqueue_note, lit("last"), default_last)},
|
||||||
|
};
|
||||||
|
|
||||||
|
String string =
|
||||||
|
lit(
|
||||||
|
"function void "
|
||||||
|
"base_type_lower@_@var_name_lower@_push(base_type *parent, var_type *child){"
|
||||||
|
"if(parent->first == 0){"
|
||||||
|
"parent->first = parent->last = child;"
|
||||||
|
"}"
|
||||||
|
"else{"
|
||||||
|
"parent->last = parent->last->next = child;"
|
||||||
|
"}"
|
||||||
|
"}"
|
||||||
|
|
||||||
|
"function var_type * "
|
||||||
|
"base_type_lower@_@var_name_lower@_pop_first(base_type *parent){"
|
||||||
|
" if(parent->first == parent->last){"
|
||||||
|
" var_type *node = parent->first;"
|
||||||
|
" parent->first = parent->last = 0;"
|
||||||
|
" return node;"
|
||||||
|
" }"
|
||||||
|
" else if(parent->first){"
|
||||||
|
" var_type *node = parent->first;"
|
||||||
|
" parent->first = parent->first->next;"
|
||||||
|
" }"
|
||||||
|
"return 0;"
|
||||||
|
"}"
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
print_string_replaced(string, maps, buff_cap(maps));
|
||||||
|
lex_print("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user