Backup, new approach to ast

This commit is contained in:
Krzosa Karol
2022-05-02 09:29:21 +02:00
parent c5498b03ad
commit 6d68fd07aa
8 changed files with 882 additions and 125 deletions

149
ast.h
View File

@@ -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,

View File

@@ -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
View File

@@ -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
View File

@@ -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"),

View File

@@ -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;
}

View File

@@ -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
View File

@@ -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;
}

214
print.c
View File

@@ -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__print(n, indent+2); 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);
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("\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");
}
}
}