Add sentinel node to parser.
This commit is contained in:
1
ast.jai
1
ast.jai
@@ -4,6 +4,7 @@
|
|||||||
// [ ] Add a way to infer or get file path from a node
|
// [ ] Add a way to infer or get file path from a node
|
||||||
|
|
||||||
AST_Kind :: enum {
|
AST_Kind :: enum {
|
||||||
|
Invalid;
|
||||||
Program;
|
Program;
|
||||||
Function;
|
Function;
|
||||||
Return;
|
Return;
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ Compiler_Context :: struct {
|
|||||||
codegen_result_text : string;
|
codegen_result_text : string;
|
||||||
|
|
||||||
typed_buffers : Static_Array(Type_Variable_Handle, 32);
|
typed_buffers : Static_Array(Type_Variable_Handle, 32);
|
||||||
// structured_buffers : Static_Array(Type_Variable_Handle, 16);
|
|
||||||
|
|
||||||
scope_stack : Scope_Stack;
|
scope_stack : Scope_Stack;
|
||||||
type_variables : [..]Type_Variable;
|
type_variables : [..]Type_Variable;
|
||||||
|
|||||||
122
parsing.jai
122
parsing.jai
@@ -1,6 +1,6 @@
|
|||||||
////////////////////////////
|
////////////////////////////
|
||||||
//@nb - Parse_state state
|
//@nb - Parse_state state
|
||||||
Parse_State :: struct {
|
Parser :: struct {
|
||||||
current : *Token;
|
current : *Token;
|
||||||
previous : *Token;
|
previous : *Token;
|
||||||
|
|
||||||
@@ -9,6 +9,15 @@ Parse_State :: struct {
|
|||||||
ctx : *Compiler_Context;
|
ctx : *Compiler_Context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AST_SENTINEL : AST_Node : .{
|
||||||
|
kind = .Invalid,
|
||||||
|
name = "__SENTINEL__",
|
||||||
|
};
|
||||||
|
|
||||||
|
is_sentinel :: inline (node : *AST_Node) -> bool {
|
||||||
|
return node == *AST_SENTINEL;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
//@nb - Parsing helper types
|
//@nb - Parsing helper types
|
||||||
Separator_Type :: enum {
|
Separator_Type :: enum {
|
||||||
@@ -39,7 +48,7 @@ Precedence :: enum {
|
|||||||
PREC_PRIMARY;
|
PREC_PRIMARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parse_Fn :: #type (parse_state: *Parse_State, left : *AST_Node) -> *AST_Node;
|
Parse_Fn :: #type (parse_state: *Parser, left : *AST_Node) -> *AST_Node;
|
||||||
Parse_Rule :: struct {
|
Parse_Rule :: struct {
|
||||||
prefix : Parse_Fn;
|
prefix : Parse_Fn;
|
||||||
infix : Parse_Fn;
|
infix : Parse_Fn;
|
||||||
@@ -96,7 +105,7 @@ parse_rules :: #run -> [(cast(int)Token_Kind.TOKEN_ERROR) + 1]Parse_Rule {
|
|||||||
//@nb - Error handling functions
|
//@nb - Error handling functions
|
||||||
|
|
||||||
//nb - Record an error and report it immediately to the user.
|
//nb - Record an error and report it immediately to the user.
|
||||||
record_error :: (parse_state : *Parse_State, token : Token, message : string, report_source_location : bool = true) {
|
record_error :: (parse_state : *Parser, token : Token, message : string, report_source_location : bool = true) {
|
||||||
error : Compiler_Message;
|
error : Compiler_Message;
|
||||||
error.message_kind = .Error;
|
error.message_kind = .Error;
|
||||||
error.message = message;
|
error.message = message;
|
||||||
@@ -121,7 +130,7 @@ record_error :: (parse_state : *Parse_State, token : Token, message : string, re
|
|||||||
rewind_to_snapshot(parse_state, snap);
|
rewind_to_snapshot(parse_state, snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_source_location_from_token :: (state : *Parse_State, token : Token) -> Source_Range {
|
generate_source_location_from_token :: (state : *Parser, token : Token) -> Source_Range {
|
||||||
location : Source_Range;
|
location : Source_Range;
|
||||||
begin : Token = token;
|
begin : Token = token;
|
||||||
begin.index -= begin.column;
|
begin.index -= begin.column;
|
||||||
@@ -142,7 +151,7 @@ generate_source_location_from_token :: (state : *Parse_State, token : Token) ->
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
unexpected_token :: (state : *Parse_State, token : Token, message : string) {
|
unexpected_token :: (state : *Parser, token : Token, message : string) {
|
||||||
/*
|
/*
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@@ -176,7 +185,7 @@ unexpected_token :: (state : *Parse_State, token : Token, message : string) {
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
else_if_without_if :: (state : *Parse_State) {
|
else_if_without_if :: (state : *Parser) {
|
||||||
builder : String_Builder;
|
builder : String_Builder;
|
||||||
init_string_builder(*builder,, temp);
|
init_string_builder(*builder,, temp);
|
||||||
|
|
||||||
@@ -198,7 +207,7 @@ else_if_without_if :: (state : *Parse_State) {
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
else_without_if :: (state : *Parse_State) {
|
else_without_if :: (state : *Parser) {
|
||||||
builder : String_Builder;
|
builder : String_Builder;
|
||||||
init_string_builder(*builder,, temp);
|
init_string_builder(*builder,, temp);
|
||||||
|
|
||||||
@@ -220,7 +229,7 @@ else_without_if :: (state : *Parse_State) {
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unable_to_parse_statement :: (state : *Parse_State, token : Token, message : string = "") {
|
unable_to_parse_statement :: (state : *Parser, token : Token, message : string = "") {
|
||||||
builder : String_Builder;
|
builder : String_Builder;
|
||||||
init_string_builder(*builder,, temp);
|
init_string_builder(*builder,, temp);
|
||||||
|
|
||||||
@@ -240,7 +249,7 @@ unable_to_parse_statement :: (state : *Parse_State, token : Token, message : str
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_expression :: (state : *Parse_State, token : Token, message : string) {
|
expected_expression :: (state : *Parser, token : Token, message : string) {
|
||||||
builder : String_Builder;
|
builder : String_Builder;
|
||||||
init_string_builder(*builder,, temp);
|
init_string_builder(*builder,, temp);
|
||||||
|
|
||||||
@@ -259,7 +268,7 @@ expected_expression :: (state : *Parse_State, token : Token, message : string) {
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
missing_type_specifier :: (state : *Parse_State, token : Token, message : string) {
|
missing_type_specifier :: (state : *Parser, token : Token, message : string) {
|
||||||
builder : String_Builder;
|
builder : String_Builder;
|
||||||
init_string_builder(*builder,, temp);
|
init_string_builder(*builder,, temp);
|
||||||
|
|
||||||
@@ -283,7 +292,7 @@ missing_type_specifier :: (state : *Parse_State, token : Token, message : string
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
empty_block :: (state : *Parse_State, token : Token, message : string) {
|
empty_block :: (state : *Parser, token : Token, message : string) {
|
||||||
builder : String_Builder;
|
builder : String_Builder;
|
||||||
init_string_builder(*builder,, temp);
|
init_string_builder(*builder,, temp);
|
||||||
|
|
||||||
@@ -307,7 +316,7 @@ empty_block :: (state : *Parse_State, token : Token, message : string) {
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unable_to_open_file :: (state : *Parse_State, path : string, token : Token) {
|
unable_to_open_file :: (state : *Parser, path : string, token : Token) {
|
||||||
builder : String_Builder;
|
builder : String_Builder;
|
||||||
init_string_builder(*builder,, temp);
|
init_string_builder(*builder,, temp);
|
||||||
|
|
||||||
@@ -327,7 +336,7 @@ unable_to_open_file :: (state : *Parse_State, path : string, token : Token) {
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_point_requires_return_value :: (state : *Parse_State, token : Token) {
|
entry_point_requires_return_value :: (state : *Parser, token : Token) {
|
||||||
builder : String_Builder;
|
builder : String_Builder;
|
||||||
init_string_builder(*builder,, temp);
|
init_string_builder(*builder,, temp);
|
||||||
|
|
||||||
@@ -346,7 +355,7 @@ entry_point_requires_return_value :: (state : *Parse_State, token : Token) {
|
|||||||
record_error(state, token, final_message, false);
|
record_error(state, token, final_message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_node :: (parse_state : *Parse_State, message : string) -> *AST_Node {
|
error_node :: (parse_state : *Parser, message : string) -> *AST_Node {
|
||||||
node := make_node(parse_state, .Error);
|
node := make_node(parse_state, .Error);
|
||||||
node.name = copy_string(message);
|
node.name = copy_string(message);
|
||||||
|
|
||||||
@@ -355,7 +364,7 @@ error_node :: (parse_state : *Parse_State, message : string) -> *AST_Node {
|
|||||||
|
|
||||||
//nb - Advance to the next sync point.
|
//nb - Advance to the next sync point.
|
||||||
// A sync point is the next token that ends a statement or starts/ends a block.
|
// A sync point is the next token that ends a statement or starts/ends a block.
|
||||||
advance_to_sync_point :: (parse_state : *Parse_State) {
|
advance_to_sync_point :: (parse_state : *Parser) {
|
||||||
while true {
|
while true {
|
||||||
if parse_state.current.kind == .TOKEN_SEMICOLON || parse_state.current.kind == .TOKEN_RIGHTBRACE ||
|
if parse_state.current.kind == .TOKEN_SEMICOLON || parse_state.current.kind == .TOKEN_RIGHTBRACE ||
|
||||||
parse_state.current.kind == .TOKEN_LEFTBRACE || parse_state.current.kind == .TOKEN_EOF {
|
parse_state.current.kind == .TOKEN_LEFTBRACE || parse_state.current.kind == .TOKEN_EOF {
|
||||||
@@ -379,7 +388,7 @@ make_node :: (nodes : *[..]AST_Node, kind : AST_Kind) -> *AST_Node {
|
|||||||
return *(nodes.*[nodes.count - 1]);
|
return *(nodes.*[nodes.count - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
make_node :: (parse_state : *Parse_State, kind : AST_Kind) -> *AST_Node {
|
make_node :: (parse_state : *Parser, kind : AST_Kind) -> *AST_Node {
|
||||||
return make_node(*parse_state.ctx.nodes, kind);
|
return make_node(*parse_state.ctx.nodes, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,7 +529,7 @@ get_field_list :: (struct_or_func : *AST_Node) -> *AST_Node {
|
|||||||
return struct_or_func.children[0];
|
return struct_or_func.children[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
add_child :: (node : *AST_Node, child : *AST_Node) {
|
add_child :: inline (node : *AST_Node, child : *AST_Node) {
|
||||||
child.parent = node;
|
child.parent = node;
|
||||||
array_add(*node.children, child);
|
array_add(*node.children, child);
|
||||||
}
|
}
|
||||||
@@ -531,7 +540,7 @@ Sync_Snapshot :: struct {
|
|||||||
current_token_index : int;
|
current_token_index : int;
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot_state :: (parse_state : *Parse_State) -> Sync_Snapshot {
|
snapshot_state :: (parse_state : *Parser) -> Sync_Snapshot {
|
||||||
snapshot : Sync_Snapshot;
|
snapshot : Sync_Snapshot;
|
||||||
snapshot.current = parse_state.current;
|
snapshot.current = parse_state.current;
|
||||||
snapshot.previous = parse_state.previous;
|
snapshot.previous = parse_state.previous;
|
||||||
@@ -540,13 +549,13 @@ snapshot_state :: (parse_state : *Parse_State) -> Sync_Snapshot {
|
|||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
rewind_to_snapshot :: (parse_state : *Parse_State, snapshot : Sync_Snapshot) {
|
rewind_to_snapshot :: (parse_state : *Parser, snapshot : Sync_Snapshot) {
|
||||||
parse_state.current = snapshot.current;
|
parse_state.current = snapshot.current;
|
||||||
parse_state.previous = snapshot.previous;
|
parse_state.previous = snapshot.previous;
|
||||||
parse_state.current_token_index = snapshot.current_token_index;
|
parse_state.current_token_index = snapshot.current_token_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
advance :: (parse_state : *Parse_State) {
|
advance :: (parse_state : *Parser) {
|
||||||
parse_state.previous = parse_state.current;
|
parse_state.previous = parse_state.current;
|
||||||
|
|
||||||
while true {
|
while true {
|
||||||
@@ -564,18 +573,18 @@ advance :: (parse_state : *Parse_State) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//nb - Checks if the current token is of a certain kind and advances if it is
|
//nb - Checks if the current token is of a certain kind and advances if it is
|
||||||
match :: (parse_state : *Parse_State, kind : Token_Kind) -> bool {
|
match :: (parse_state : *Parser, kind : Token_Kind) -> bool {
|
||||||
if !check(parse_state, kind) return false;
|
if !check(parse_state, kind) return false;
|
||||||
advance(parse_state);
|
advance(parse_state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//nb - Checks if the current token is of a certain kind
|
//nb - Checks if the current token is of a certain kind
|
||||||
check :: (parse_state : *Parse_State, kind : Token_Kind) -> bool {
|
check :: (parse_state : *Parser, kind : Token_Kind) -> bool {
|
||||||
return parse_state.current.kind == kind;
|
return parse_state.current.kind == kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_any :: (parse_state : *Parse_State, kinds : ..Token_Kind) -> bool {
|
check_any :: (parse_state : *Parser, kinds : ..Token_Kind) -> bool {
|
||||||
for kind : kinds {
|
for kind : kinds {
|
||||||
if check(parse_state, kind) {
|
if check(parse_state, kind) {
|
||||||
return true;
|
return true;
|
||||||
@@ -585,12 +594,12 @@ check_any :: (parse_state : *Parse_State, kinds : ..Token_Kind) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//nb - Checks if the next token is of a certain kind
|
//nb - Checks if the next token is of a certain kind
|
||||||
check_next :: (parse_state : *Parse_State, kind : Token_Kind) -> bool {
|
check_next :: (parse_state : *Parser, kind : Token_Kind) -> bool {
|
||||||
return parse_state.ctx.tokens[parse_state.current_token_index].kind == kind;
|
return parse_state.ctx.tokens[parse_state.current_token_index].kind == kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
//nb - Consume a token if
|
//nb - Consume a token if
|
||||||
consume :: (parse_state : *Parse_State, kind : Token_Kind, message : string) {
|
consume :: (parse_state : *Parser, kind : Token_Kind, message : string) {
|
||||||
if parse_state.current.kind == kind {
|
if parse_state.current.kind == kind {
|
||||||
advance(parse_state);
|
advance(parse_state);
|
||||||
return;
|
return;
|
||||||
@@ -612,7 +621,7 @@ get_rule :: (kind : Token_Kind) -> *Parse_Rule {
|
|||||||
return *parse_rules[kind];
|
return *parse_rules[kind];
|
||||||
}
|
}
|
||||||
|
|
||||||
precedence :: (parse_state : *Parse_State, precedence : Precedence, message : string = "") -> *AST_Node {
|
precedence :: (parse_state : *Parser, precedence : Precedence, message : string = "") -> *AST_Node {
|
||||||
prev := parse_state.previous;
|
prev := parse_state.previous;
|
||||||
advance(parse_state);
|
advance(parse_state);
|
||||||
|
|
||||||
@@ -640,7 +649,7 @@ precedence :: (parse_state : *Parse_State, precedence : Precedence, message : st
|
|||||||
tok_s.count = parse_state.previous.length;
|
tok_s.count = parse_state.previous.length;
|
||||||
expected_expression(parse_state, parse_state.current, tprint("Reached end of file. Expected expression after '%'.", tok_s));
|
expected_expression(parse_state, parse_state.current, tprint("Reached end of file. Expected expression after '%'.", tok_s));
|
||||||
// @Incomplete: Add error node here?
|
// @Incomplete: Add error node here?
|
||||||
return null;
|
return *AST_SENTINEL;
|
||||||
}
|
}
|
||||||
infix_rule := get_rule(parse_state.previous.kind).infix;
|
infix_rule := get_rule(parse_state.previous.kind).infix;
|
||||||
left = infix_rule(parse_state, left);
|
left = infix_rule(parse_state, left);
|
||||||
@@ -649,7 +658,7 @@ precedence :: (parse_state : *Parse_State, precedence : Precedence, message : st
|
|||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
named_variable :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
named_variable :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
if check(parse_state, .TOKEN_LEFTPAREN) {
|
if check(parse_state, .TOKEN_LEFTPAREN) {
|
||||||
return call(parse_state, left);
|
return call(parse_state, left);
|
||||||
}
|
}
|
||||||
@@ -662,7 +671,7 @@ named_variable :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
|||||||
return variable;
|
return variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
binary :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
binary :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
op := parse_state.previous.*;
|
op := parse_state.previous.*;
|
||||||
rule := get_rule(op.kind);
|
rule := get_rule(op.kind);
|
||||||
|
|
||||||
@@ -704,7 +713,7 @@ binary :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
|||||||
return binary_expression;
|
return binary_expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
array_access :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
array_access :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
identifier := parse_state.ctx.tokens[parse_state.current_token_index - 3];
|
identifier := parse_state.ctx.tokens[parse_state.current_token_index - 3];
|
||||||
left_bracket := parse_state.ctx.tokens[parse_state.current_token_index - 2];
|
left_bracket := parse_state.ctx.tokens[parse_state.current_token_index - 2];
|
||||||
|
|
||||||
@@ -734,7 +743,7 @@ array_access :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
|||||||
return array_access;
|
return array_access;
|
||||||
}
|
}
|
||||||
|
|
||||||
unary :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
unary :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
op := parse_state.previous.*;
|
op := parse_state.previous.*;
|
||||||
rule := get_rule(op.kind);
|
rule := get_rule(op.kind);
|
||||||
|
|
||||||
@@ -755,13 +764,13 @@ unary :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
|||||||
return unary_expression;
|
return unary_expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
grouping :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
grouping :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
grouping := expression(parse_state);
|
grouping := expression(parse_state);
|
||||||
consume(parse_state, .TOKEN_RIGHTPAREN, "Expect ')' after group expression.");
|
consume(parse_state, .TOKEN_RIGHTPAREN, "Expect ')' after group expression.");
|
||||||
return grouping;
|
return grouping;
|
||||||
}
|
}
|
||||||
|
|
||||||
directive :: (state : *Parse_State) -> *AST_Node {
|
directive :: (state : *Parser) -> *AST_Node {
|
||||||
if state.current.ident_value == "foreign" {
|
if state.current.ident_value == "foreign" {
|
||||||
advance(state);
|
advance(state);
|
||||||
identifier_token := state.current;
|
identifier_token := state.current;
|
||||||
@@ -801,15 +810,12 @@ directive :: (state : *Parse_State) -> *AST_Node {
|
|||||||
return if_directive;
|
return if_directive;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return *AST_SENTINEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
call :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
call :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
call := make_node(parse_state, .Call);
|
call := make_node(parse_state, .Call);
|
||||||
source_location := generate_source_location_from_token(parse_state, parse_state.previous);
|
source_location := generate_source_location_from_token(parse_state, parse_state.previous);
|
||||||
// source_location : Source_Range;
|
|
||||||
// source_location.begin = parse_state.previous;
|
|
||||||
// source_location.main_token = parse_state.previous;
|
|
||||||
|
|
||||||
prev := parse_state.previous;
|
prev := parse_state.previous;
|
||||||
call.name = prev.ident_value;
|
call.name = prev.ident_value;
|
||||||
@@ -830,7 +836,7 @@ call :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
|||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
dot :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
dot :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
consume(parse_state, .TOKEN_IDENTIFIER, "Expect property name after '.'.");
|
consume(parse_state, .TOKEN_IDENTIFIER, "Expect property name after '.'.");
|
||||||
identifier := parse_state.previous;
|
identifier := parse_state.previous;
|
||||||
|
|
||||||
@@ -863,7 +869,7 @@ dot :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
|||||||
return access;
|
return access;
|
||||||
}
|
}
|
||||||
|
|
||||||
integer :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
integer :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
value := parse_state.previous.integer_value;
|
value := parse_state.previous.integer_value;
|
||||||
node := make_node(parse_state, .Integer);
|
node := make_node(parse_state, .Integer);
|
||||||
node.source_location.begin = parse_state.previous;
|
node.source_location.begin = parse_state.previous;
|
||||||
@@ -873,7 +879,7 @@ integer :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
floating :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
floating :: (parse_state : *Parser, left : *AST_Node) -> *AST_Node {
|
||||||
value := parse_state.previous.float_value;
|
value := parse_state.previous.float_value;
|
||||||
node := make_node(parse_state, .Float);
|
node := make_node(parse_state, .Float);
|
||||||
node.source_location.begin = parse_state.previous;
|
node.source_location.begin = parse_state.previous;
|
||||||
@@ -883,7 +889,7 @@ floating :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
expression :: (parse_state : *Parse_State, message : string = "") -> *AST_Node {
|
expression :: (parse_state : *Parser, message : string = "") -> *AST_Node {
|
||||||
expression := precedence(parse_state, .PREC_ASSIGNMENT, message);
|
expression := precedence(parse_state, .PREC_ASSIGNMENT, message);
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
@@ -891,7 +897,7 @@ expression :: (parse_state : *Parse_State, message : string = "") -> *AST_Node {
|
|||||||
////////////////////////////
|
////////////////////////////
|
||||||
//@nb - Statement parsing functions
|
//@nb - Statement parsing functions
|
||||||
|
|
||||||
field_assignment :: (parse_state : *Parse_State, identifier_token : *Token) -> *AST_Node {
|
field_assignment :: (parse_state : *Parser, identifier_token : *Token) -> *AST_Node {
|
||||||
node : *AST_Node = make_node(parse_state, .Field);
|
node : *AST_Node = make_node(parse_state, .Field);
|
||||||
|
|
||||||
identifier := identifier_token.*;
|
identifier := identifier_token.*;
|
||||||
@@ -910,7 +916,7 @@ field_assignment :: (parse_state : *Parse_State, identifier_token : *Token) -> *
|
|||||||
}
|
}
|
||||||
|
|
||||||
//nb - Non-const field declarations
|
//nb - Non-const field declarations
|
||||||
field_declaration :: (parse_state : *Parse_State, identifier_token : *Token) -> *AST_Node {
|
field_declaration :: (parse_state : *Parser, identifier_token : *Token) -> *AST_Node {
|
||||||
node : *AST_Node = make_node(parse_state, .Field);
|
node : *AST_Node = make_node(parse_state, .Field);
|
||||||
|
|
||||||
identifier := identifier_token.*;
|
identifier := identifier_token.*;
|
||||||
@@ -971,7 +977,7 @@ field_declaration :: (parse_state : *Parse_State, identifier_token : *Token) ->
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
argument_list :: (parse_state : *Parse_State) -> *AST_Node {
|
argument_list :: (parse_state : *Parser) -> *AST_Node {
|
||||||
node : *AST_Node;
|
node : *AST_Node;
|
||||||
|
|
||||||
source_location : Source_Range;
|
source_location : Source_Range;
|
||||||
@@ -1019,7 +1025,7 @@ argument_list :: (parse_state : *Parse_State) -> *AST_Node {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
expression_statement :: (parse_state : *Parse_State) -> *AST_Node {
|
expression_statement :: (parse_state : *Parser) -> *AST_Node {
|
||||||
node := make_node(parse_state, .Expression_Statement);
|
node := make_node(parse_state, .Expression_Statement);
|
||||||
|
|
||||||
source_location : Source_Range;
|
source_location : Source_Range;
|
||||||
@@ -1037,7 +1043,7 @@ expression_statement :: (parse_state : *Parse_State) -> *AST_Node {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
statement :: (parse_state : *Parse_State) -> *AST_Node {
|
statement :: (parse_state : *Parser) -> *AST_Node {
|
||||||
if match(parse_state, .TOKEN_RETURN) {
|
if match(parse_state, .TOKEN_RETURN) {
|
||||||
node := make_node(parse_state, .Return);
|
node := make_node(parse_state, .Return);
|
||||||
|
|
||||||
@@ -1155,7 +1161,7 @@ statement :: (parse_state : *Parse_State) -> *AST_Node {
|
|||||||
return error_node(parse_state, "Couldn't parse statement.");
|
return error_node(parse_state, "Couldn't parse statement.");
|
||||||
}
|
}
|
||||||
|
|
||||||
else_statement :: (parse_state : *Parse_State) -> *AST_Node {
|
else_statement :: (parse_state : *Parser) -> *AST_Node {
|
||||||
if check(parse_state, .TOKEN_IF) {
|
if check(parse_state, .TOKEN_IF) {
|
||||||
return statement(parse_state);
|
return statement(parse_state);
|
||||||
} else if check(parse_state, .TOKEN_DIRECTIVE) && parse_state.current.ident_value == "if" {
|
} else if check(parse_state, .TOKEN_DIRECTIVE) && parse_state.current.ident_value == "if" {
|
||||||
@@ -1164,7 +1170,7 @@ else_statement :: (parse_state : *Parse_State) -> *AST_Node {
|
|||||||
return block(parse_state);
|
return block(parse_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
block :: (parse_state : *Parse_State) -> *AST_Node {
|
block :: (parse_state : *Parser) -> *AST_Node {
|
||||||
node : *AST_Node = make_node(parse_state, .Block);
|
node : *AST_Node = make_node(parse_state, .Block);
|
||||||
array_reserve(*node.children, 32);
|
array_reserve(*node.children, 32);
|
||||||
|
|
||||||
@@ -1186,7 +1192,7 @@ block :: (parse_state : *Parse_State) -> *AST_Node {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
field_list :: (parse_state : *Parse_State, separator : Separator_Type, require_field_names := true) -> *AST_Node {
|
field_list :: (parse_state : *Parser, separator : Separator_Type, require_field_names := true) -> *AST_Node {
|
||||||
node : *AST_Node = make_node(parse_state, .FieldList);
|
node : *AST_Node = make_node(parse_state, .FieldList);
|
||||||
array_reserve(*node.children, 16);
|
array_reserve(*node.children, 16);
|
||||||
source_location : Source_Range;
|
source_location : Source_Range;
|
||||||
@@ -1231,7 +1237,7 @@ field_list :: (parse_state : *Parse_State, separator : Separator_Type, require_f
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function_declaration :: (parse_state : *Parse_State, identifier_token : *Token, entry_point_kind : Entry_Point_Type, expect_body : bool = true, require_field_names : bool = true) -> *AST_Node {
|
function_declaration :: (parse_state : *Parser, identifier_token : *Token, entry_point_kind : Entry_Point_Type, expect_body : bool = true, require_field_names : bool = true) -> *AST_Node {
|
||||||
node : *AST_Node;
|
node : *AST_Node;
|
||||||
source_location : Source_Range;
|
source_location : Source_Range;
|
||||||
|
|
||||||
@@ -1302,7 +1308,7 @@ function_declaration :: (parse_state : *Parse_State, identifier_token : *Token,
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer :: (state : *Parse_State, identifier_token : *Token = null) -> *AST_Node {
|
buffer :: (state : *Parser, identifier_token : *Token = null) -> *AST_Node {
|
||||||
node : *AST_Node = make_node(state, .Buffer);
|
node : *AST_Node = make_node(state, .Buffer);
|
||||||
source_location : Source_Range;
|
source_location : Source_Range;
|
||||||
source_location.begin = state.current;
|
source_location.begin = state.current;
|
||||||
@@ -1334,7 +1340,7 @@ buffer :: (state : *Parse_State, identifier_token : *Token = null) -> *AST_Node
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
constant_buffer :: (parse_state : *Parse_State, identifier_token : *Token = null) -> *AST_Node {
|
constant_buffer :: (parse_state : *Parser, identifier_token : *Token = null) -> *AST_Node {
|
||||||
node : *AST_Node = make_node(parse_state, .CBuffer);
|
node : *AST_Node = make_node(parse_state, .CBuffer);
|
||||||
source_location : Source_Range;
|
source_location : Source_Range;
|
||||||
source_location.begin = parse_state.current;
|
source_location.begin = parse_state.current;
|
||||||
@@ -1365,7 +1371,7 @@ constant_buffer :: (parse_state : *Parse_State, identifier_token : *Token = null
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct_declaration :: (parse_state : *Parse_State, identifier_token : *Token) -> *AST_Node {
|
struct_declaration :: (parse_state : *Parser, identifier_token : *Token) -> *AST_Node {
|
||||||
source_location := generate_source_location_from_token(parse_state, identifier_token);
|
source_location := generate_source_location_from_token(parse_state, identifier_token);
|
||||||
|
|
||||||
consume(parse_state, .TOKEN_LEFTBRACE, "Expect '{' before struct declaration.");
|
consume(parse_state, .TOKEN_LEFTBRACE, "Expect '{' before struct declaration.");
|
||||||
@@ -1383,13 +1389,13 @@ struct_declaration :: (parse_state : *Parse_State, identifier_token : *Token) ->
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
access :: (parse_state : *Parse_State, identifier_token : *Token) -> *AST_Node {
|
access :: (parse_state : *Parser, identifier_token : *Token) -> *AST_Node {
|
||||||
err_node := error_node(parse_state, tprint("Accessors not yet implemented. Token: %.", identifier_token.ident_value));
|
err_node := error_node(parse_state, tprint("Accessors not yet implemented. Token: %.", identifier_token.ident_value));
|
||||||
advance(parse_state);
|
advance(parse_state);
|
||||||
return err_node;
|
return err_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
const_declaration :: (parse_state : *Parse_State, identifier_token : *Token) -> *AST_Node {
|
const_declaration :: (parse_state : *Parser, identifier_token : *Token) -> *AST_Node {
|
||||||
if match(parse_state, .TOKEN_STRUCT) {
|
if match(parse_state, .TOKEN_STRUCT) {
|
||||||
return struct_declaration(parse_state, identifier_token);
|
return struct_declaration(parse_state, identifier_token);
|
||||||
} else if check(parse_state, .TOKEN_LEFTPAREN) {
|
} else if check(parse_state, .TOKEN_LEFTPAREN) {
|
||||||
@@ -1402,7 +1408,7 @@ const_declaration :: (parse_state : *Parse_State, identifier_token : *Token) ->
|
|||||||
return error_node(parse_state, tprint("Couldn't parse constant declaration at token %\n", parse_state.current.*));
|
return error_node(parse_state, tprint("Couldn't parse constant declaration at token %\n", parse_state.current.*));
|
||||||
}
|
}
|
||||||
|
|
||||||
declaration :: (parse_state : *Parse_State) -> *AST_Node {
|
declaration :: (parse_state : *Parser) -> *AST_Node {
|
||||||
skip_statement := false;
|
skip_statement := false;
|
||||||
decl_node : *AST_Node;
|
decl_node : *AST_Node;
|
||||||
if match(parse_state, .TOKEN_VERTEX) {
|
if match(parse_state, .TOKEN_VERTEX) {
|
||||||
@@ -1468,7 +1474,7 @@ parse :: (ctx : *Compiler_Context, allocator := temp) {
|
|||||||
init_context_allocators();
|
init_context_allocators();
|
||||||
defer clear_context_allocators();
|
defer clear_context_allocators();
|
||||||
|
|
||||||
parse_state : Parse_State;
|
parse_state : Parser;
|
||||||
array_reserve(*ctx.nodes, 4096);
|
array_reserve(*ctx.nodes, 4096);
|
||||||
parse_state.current_token_index = 0;
|
parse_state.current_token_index = 0;
|
||||||
parse_state.ctx = ctx;
|
parse_state.ctx = ctx;
|
||||||
|
|||||||
Reference in New Issue
Block a user