A bunch of new allocation related stuff.
This commit is contained in:
195
Parsing.jai
195
Parsing.jai
@@ -165,8 +165,10 @@ unexpected_token :: (state : *Parse_State, token : Token, message : string) {
|
||||
/*
|
||||
|
||||
*/
|
||||
sc := get_scratch();
|
||||
defer scratch_end(sc);
|
||||
builder : String_Builder;
|
||||
init_string_builder(*builder,, temp);
|
||||
init_string_builder(*builder,, sc.allocator);
|
||||
|
||||
print_to_builder(*builder, "%\n\n", message);
|
||||
|
||||
@@ -189,7 +191,7 @@ unexpected_token :: (state : *Parse_State, token : Token, message : string) {
|
||||
indent(*builder, 1);
|
||||
print_token_pointer(*builder, token);
|
||||
|
||||
final_message := builder_to_string(*builder);
|
||||
final_message := builder_to_string(*builder,, context.allocator);
|
||||
record_error(state, token, final_message, false);
|
||||
}
|
||||
|
||||
@@ -372,7 +374,8 @@ make_node :: (nodes : *[..]AST_Node, kind : AST_Kind, allocator : Allocator) ->
|
||||
node : AST_Node;
|
||||
|
||||
node.kind = kind;
|
||||
node.children.allocator = allocator;
|
||||
node.children.allocator = allocator;
|
||||
node.hint_tokens.allocator = allocator;
|
||||
array_add(nodes, node);
|
||||
|
||||
return *(nodes.*[nodes.count - 1]);
|
||||
@@ -388,7 +391,7 @@ make_node :: (parse_state : *Parse_State, kind : AST_Kind) -> *AST_Node {
|
||||
// return node;
|
||||
// }
|
||||
|
||||
make_builtin_token :: (builder : *String_Builder, kind : Token_Kind, text : string, col : *int, line : *int) -> Token {
|
||||
make_builtin_token :: (tokens : *[..]Token, builder : *String_Builder, kind : Token_Kind, text : string, col : *int, line : *int) -> *Token {
|
||||
tok : Token;
|
||||
tok.kind = kind;
|
||||
|
||||
@@ -418,55 +421,172 @@ make_builtin_token :: (builder : *String_Builder, kind : Token_Kind, text : stri
|
||||
tok.length = text.count;
|
||||
tok.builtin = true;
|
||||
|
||||
return tok;
|
||||
array_add(tokens, tok);
|
||||
|
||||
return *(tokens.*)[tokens.count - 1];
|
||||
}
|
||||
|
||||
new_builtin_struct_node :: (result : *Compile_Result, name : string, members : []Arg, allocator : Allocator) -> *AST_Node {
|
||||
sc := get_scratch(result, allocator);
|
||||
sc := get_scratch(allocator);
|
||||
defer scratch_end(sc);
|
||||
builder : String_Builder;
|
||||
builder.allocator = sc.allocator; // I want to find a good way to use scratch here...
|
||||
|
||||
node := make_node(*result.nodes, .Struct, allocator);
|
||||
|
||||
source_location : Source_Range;
|
||||
|
||||
col := 0;
|
||||
line := 0;
|
||||
|
||||
tok_index := result.tokens.count;
|
||||
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_IDENTIFIER, tprint("%", name), *col, *line));
|
||||
ident_token := make_builtin_token(*result.tokens, *builder, .TOKEN_IDENTIFIER, tprint("%", name), *col, *line);
|
||||
source_location.begin = ident_token;
|
||||
|
||||
append(*builder, " ");
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_DOUBLECOLON, "::", *col, *line));
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_DOUBLECOLON, "::", *col, *line);
|
||||
append(*builder, " ");
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_STRUCT, "struct", *col, *line));
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_STRUCT, "struct", *col, *line);
|
||||
append(*builder, " ");
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_LEFTBRACE, "{", *col, *line));
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_LEFTBRACE, "{", *col, *line);
|
||||
append(*builder, "\n");
|
||||
line += 1;
|
||||
col = 0;
|
||||
|
||||
field_list := make_node(*result.nodes, .FieldList, allocator);
|
||||
add_child(node, field_list);
|
||||
|
||||
for member : members {
|
||||
// @Incomplete: Missing field list
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_IDENTIFIER, tprint("%", member.name), *col, *line));
|
||||
field := make_node(*result.nodes, .Field, allocator);
|
||||
field_source_loc : Source_Range;
|
||||
|
||||
field_ident := make_builtin_token(*result.tokens, *builder, .TOKEN_IDENTIFIER, tprint("%", member.name), *col, *line);
|
||||
field_source_loc.begin = field_ident;
|
||||
field.token = field_ident;
|
||||
field.name = member.name;
|
||||
|
||||
append(*builder, " ");
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_COLON, ":", *col, *line));
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_COLON, ":", *col, *line);
|
||||
append(*builder, " ");
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_IDENTIFIER, tprint("%", member.typename), *col, *line));
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_SEMICOLON, ";", *col, *line));
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_IDENTIFIER, tprint("%", member.typename), *col, *line);
|
||||
semicolon_tok := make_builtin_token(*result.tokens, *builder, .TOKEN_SEMICOLON, ";", *col, *line);
|
||||
append(*builder, "\n");
|
||||
col = 0;
|
||||
line += 1;
|
||||
|
||||
field_source_loc.end = semicolon_tok;
|
||||
field.source_location = field_source_loc;
|
||||
|
||||
add_child(field_list, field);
|
||||
}
|
||||
|
||||
array_add(*result.tokens, make_builtin_token(*builder, .TOKEN_RIGHTBRACE, "}", *col, *line));
|
||||
brace_token := make_builtin_token(*result.tokens, *builder, .TOKEN_RIGHTBRACE, "}", *col, *line);
|
||||
append(*builder, "\n");
|
||||
|
||||
source_location.end = brace_token;
|
||||
|
||||
source := builder_to_string(*builder,, allocator);
|
||||
|
||||
source_location.begin.source = *source.data[source_location.begin.column];
|
||||
source_location.end.source = *source.data[source_location.end.column];
|
||||
|
||||
for i : tok_index..result.tokens.count - 1 {
|
||||
tok := *result.tokens[i];
|
||||
tok := result.tokens[i];
|
||||
tok.source = *source.data[tok.column];
|
||||
}
|
||||
|
||||
for field : field_list.children {
|
||||
field.source_location.begin.source = *source.data[field.source_location.begin.column];
|
||||
field.source_location.end.source = *source.data[field.source_location.end.column];
|
||||
// field.source_location.main_token.source = *source.data[tok.column];
|
||||
}
|
||||
|
||||
print_from_source_location(source_location, temp);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
new_builtin_function_node :: (result : *Compile_Result, name : string, members : []Arg, return_var : Arg, allocator : Allocator) -> *AST_Node {
|
||||
sc := get_scratch(allocator);
|
||||
defer scratch_end(sc);
|
||||
builder : String_Builder;
|
||||
builder.allocator = sc.allocator; // I want to find a good way to use scratch here...
|
||||
|
||||
node := make_node(*result.nodes, .Function, allocator);
|
||||
|
||||
source_location : Source_Range;
|
||||
|
||||
col := 0;
|
||||
line := 0;
|
||||
|
||||
tok_index := result.tokens.count;
|
||||
|
||||
ident_token := make_builtin_token(*result.tokens, *builder, .TOKEN_IDENTIFIER, tprint("%", name), *col, *line);
|
||||
source_location.begin = ident_token;
|
||||
|
||||
append(*builder, " ");
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_DOUBLECOLON, "::", *col, *line);
|
||||
append(*builder, " ");
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_LEFTPAREN, "(", *col, *line);
|
||||
field_list := make_node(*result.nodes, .FieldList, allocator);
|
||||
add_child(node, field_list);
|
||||
|
||||
for member : members {
|
||||
field := make_node(*result.nodes, .Field, allocator);
|
||||
field_source_loc : Source_Range;
|
||||
|
||||
field_ident := make_builtin_token(*result.tokens, *builder, .TOKEN_IDENTIFIER, tprint("%", member.name), *col, *line);
|
||||
field_source_loc.begin = field_ident;
|
||||
field.token = field_ident;
|
||||
field.name = member.name;
|
||||
|
||||
append(*builder, " ");
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_COLON, ":", *col, *line);
|
||||
append(*builder, " ");
|
||||
type_tok := make_builtin_token(*result.tokens, *builder, .TOKEN_IDENTIFIER, tprint("%", member.typename), *col, *line);
|
||||
|
||||
if it_index < members.count - 1 {
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_COMMA, ";", *col, *line);
|
||||
}
|
||||
|
||||
field_source_loc.end = type_tok;
|
||||
field.source_location = field_source_loc;
|
||||
|
||||
add_child(field_list, field);
|
||||
}
|
||||
|
||||
make_builtin_token(*result.tokens, *builder, .TOKEN_RIGHTPAREN, ")", *col, *line);
|
||||
semicolon_tok := make_builtin_token(*result.tokens, *builder, .TOKEN_SEMICOLON, ";", *col, *line);
|
||||
|
||||
source_location.end = semicolon_tok;
|
||||
|
||||
source := builder_to_string(*builder,, allocator);
|
||||
|
||||
source_location.begin.source = *source.data[source_location.begin.column];
|
||||
source_location.end.source = *source.data[source_location.end.column];
|
||||
|
||||
for i : tok_index..result.tokens.count - 1 {
|
||||
tok := result.tokens[i];
|
||||
tok.source = *source.data[tok.column];
|
||||
}
|
||||
|
||||
for field : field_list.children {
|
||||
field.source_location.begin.source = *source.data[field.source_location.begin.column];
|
||||
field.source_location.end.source = *source.data[field.source_location.end.column];
|
||||
// field.source_location.main_token.source = *source.data[tok.column];
|
||||
}
|
||||
|
||||
print_from_source_location(source_location, temp);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
get_field_list :: (struct_or_func : *AST_Node) -> *AST_Node {
|
||||
assert(struct_or_func.kind == .Function || struct_or_func.kind == .Struct || struct_or_func.kind == .Properties);
|
||||
return struct_or_func.children[0];
|
||||
}
|
||||
|
||||
add_child :: (node : *AST_Node, child : *AST_Node) {
|
||||
child.parent = node;
|
||||
array_add(*node.children, child);
|
||||
@@ -1461,28 +1581,35 @@ declaration :: (parse_state : *Parse_State) -> *AST_Node {
|
||||
return decl_node;
|
||||
}
|
||||
|
||||
parse :: (result : *Compile_Result) {
|
||||
parse :: (result : *Compile_Result, allocator := temp) {
|
||||
if result.had_error {
|
||||
return;
|
||||
}
|
||||
|
||||
parse_state : Parse_State;
|
||||
result.nodes.allocator = result.allocator;
|
||||
array_reserve(*result.nodes, 4096);
|
||||
parse_state.current_token_index = 0;
|
||||
parse_state.result = result;
|
||||
|
||||
advance(*parse_state);
|
||||
|
||||
if !match(*parse_state, .TOKEN_EOF) {
|
||||
parse_state.result.root = make_node(*parse_state, .Program);
|
||||
array_reserve(*parse_state.result.root.children, 1024);
|
||||
program := parse_state.result.root;
|
||||
new_context := context;
|
||||
new_context.allocator = allocator;
|
||||
push_context new_context {
|
||||
init_context_allocators();
|
||||
defer clear_context_allocators();
|
||||
|
||||
parse_state : Parse_State;
|
||||
result.nodes.allocator = result.allocator;
|
||||
array_reserve(*result.nodes, 4096);
|
||||
parse_state.current_token_index = 0;
|
||||
parse_state.result = result;
|
||||
|
||||
advance(*parse_state);
|
||||
|
||||
while !check(*parse_state, .TOKEN_EOF) {
|
||||
decl := declaration(*parse_state);
|
||||
if decl {
|
||||
add_child(program, decl);
|
||||
if !match(*parse_state, .TOKEN_EOF) {
|
||||
parse_state.result.root = make_node(*parse_state, .Program);
|
||||
array_reserve(*parse_state.result.root.children, 1024);
|
||||
program := parse_state.result.root;
|
||||
|
||||
while !check(*parse_state, .TOKEN_EOF) {
|
||||
decl := declaration(*parse_state);
|
||||
if decl {
|
||||
add_child(program, decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user