aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c86
1 files changed, 48 insertions, 38 deletions
diff --git a/src/parser.c b/src/parser.c
index 1dbfe48..608f670 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -12,7 +12,7 @@
typedef struct {
TslTokenizer tokenizer;
- TslBuffer /*TslBytecodeWriter*/ function_bytecode_list;
+ TslBuffer /*TslBytecode*/ function_bytecode_list;
TslBuffer /*int*/ function_bytecode_list_index;
} TslParser;
@@ -21,29 +21,30 @@ static int tsl_parser_get_current_function_index(TslParser *self) {
return *(int*)last_item;
}
-#define get_function_bytecode(self) ((TslBytecodeWriter*)tsl_buffer_begin(&self->function_bytecode_list) + tsl_parser_get_current_function_index(self))
+#define get_function_bytecode(self) ((TslBytecode*)tsl_buffer_begin(&self->function_bytecode_list) + tsl_parser_get_current_function_index(self))
static TslParseResult tsl_parser_parse_rhs(TslParser *self);
static TslParseResult tsl_parser_parse_expressions(TslParser *self, TslToken end_token);
static int tsl_parser_init(TslParser *self, const char *code, size_t code_size) {
- TslBytecodeWriter bytecode_writer;
- int result = 1;
+ TslBytecode bytecode_writer;
+ int result1 = 1;
+ int result2 = 1;
size_t bytecode_index = 0;
tsl_tokenizer_init(&self->tokenizer, code, code_size);
- tsl_bytecode_writer_init(&bytecode_writer);
+ tsl_bytecode_init(&bytecode_writer);
tsl_buffer_init(&self->function_bytecode_list);
- result = tsl_buffer_append(&self->function_bytecode_list, &bytecode_writer, sizeof(bytecode_writer));
tsl_buffer_init(&self->function_bytecode_list_index);
- result = tsl_buffer_append(&self->function_bytecode_list_index, &bytecode_index, sizeof(bytecode_index));
- return result;
+ result1 = tsl_buffer_append(&self->function_bytecode_list, &bytecode_writer, sizeof(bytecode_writer));
+ result2 = tsl_buffer_append(&self->function_bytecode_list_index, &bytecode_index, sizeof(bytecode_index));
+ return result1 && result2;
}
static void tsl_parser_deinit(TslParser *self) {
- TslBytecodeWriter *bytecode_writer = tsl_buffer_begin(&self->function_bytecode_list);
- TslBytecodeWriter *bytecode_writer_end = tsl_buffer_end(&self->function_bytecode_list);
+ TslBytecode *bytecode_writer = tsl_buffer_begin(&self->function_bytecode_list);
+ TslBytecode *bytecode_writer_end = tsl_buffer_end(&self->function_bytecode_list);
while(bytecode_writer != bytecode_writer_end) {
- tsl_bytecode_writer_deinit(bytecode_writer);
+ tsl_bytecode_deinit(bytecode_writer);
++bytecode_writer;
}
tsl_buffer_deinit(&self->function_bytecode_list);
@@ -52,10 +53,10 @@ static void tsl_parser_deinit(TslParser *self) {
static TslParseResult tsl_parser_push_function(TslParser *self) {
int function_index;
- TslBytecodeWriter bytecode_writer;
- tsl_bytecode_writer_init(&bytecode_writer);
+ TslBytecode bytecode_writer;
+ tsl_bytecode_init(&bytecode_writer);
/* TODO: Use bitshift ? */
- function_index = self->function_bytecode_list.size / sizeof(TslBytecodeWriter);
+ function_index = self->function_bytecode_list.size / sizeof(TslBytecode);
return_if_error(tsl_buffer_append(&self->function_bytecode_list, &bytecode_writer, sizeof(bytecode_writer)));
return tsl_buffer_append(&self->function_bytecode_list_index, &function_index, sizeof(function_index));
}
@@ -97,19 +98,19 @@ static TslParseResult tsl_parser_parse_map(TslParser *self, int *num_items) {
TslToken token = tsl_tokenizer_next(&self->tokenizer);
if(token == TSL_TOKEN_NUM) {
++*num_items;
- return_if_error(tsl_bytecode_writer_add_ins2(get_function_bytecode(self), TSL_OPCODE_LOADN, self->tokenizer.number_value));
+ return_if_error(tsl_bytecode_add_ins2(get_function_bytecode(self), TSL_OPCODE_LOADN, self->tokenizer.number_value));
parse_map_element_separator
} else if(token == TSL_TOKEN_BOOL) {
++*num_items;
- return_if_error(tsl_bytecode_writer_add_ins3(get_function_bytecode(self), TSL_OPCODE_LOADB, self->tokenizer.bool_value));
+ return_if_error(tsl_bytecode_add_ins3(get_function_bytecode(self), TSL_OPCODE_LOADB, self->tokenizer.bool_value));
parse_map_element_separator
} else if(token == TSL_TOKEN_NULL) {
++*num_items;
- return_if_error(tsl_bytecode_writer_add_ins5(get_function_bytecode(self), TSL_OPCODE_LOADNULL));
+ return_if_error(tsl_bytecode_add_ins5(get_function_bytecode(self), TSL_OPCODE_LOADNULL));
parse_map_element_separator
} else if(token == TSL_TOKEN_STRING) {
++*num_items;
- return_if_error(tsl_bytecode_writer_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.string));
+ return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.string));
parse_map_element_separator
} else if(token == TSL_TOKEN_RBRACE) {
/* '}' after trailing ',' or an empty map */
@@ -139,19 +140,19 @@ static TslParseResult tsl_parser_parse_list(TslParser *self, int *num_items) {
TslToken token = tsl_tokenizer_next(&self->tokenizer);
if(token == TSL_TOKEN_NUM) {
++*num_items;
- return_if_error(tsl_bytecode_writer_add_ins2(get_function_bytecode(self), TSL_OPCODE_LOADN, self->tokenizer.number_value));
+ return_if_error(tsl_bytecode_add_ins2(get_function_bytecode(self), TSL_OPCODE_LOADN, self->tokenizer.number_value));
parse_list_element_separator
} else if(token == TSL_TOKEN_BOOL) {
++*num_items;
- return_if_error(tsl_bytecode_writer_add_ins3(get_function_bytecode(self), TSL_OPCODE_LOADB, self->tokenizer.bool_value));
+ return_if_error(tsl_bytecode_add_ins3(get_function_bytecode(self), TSL_OPCODE_LOADB, self->tokenizer.bool_value));
parse_list_element_separator
} else if(token == TSL_TOKEN_NULL) {
++*num_items;
- return_if_error(tsl_bytecode_writer_add_ins5(get_function_bytecode(self), TSL_OPCODE_LOADNULL));
+ return_if_error(tsl_bytecode_add_ins5(get_function_bytecode(self), TSL_OPCODE_LOADNULL));
parse_list_element_separator
} else if(token == TSL_TOKEN_STRING) {
++*num_items;
- return_if_error(tsl_bytecode_writer_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.string));
+ return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.string));
parse_list_element_separator
} else if(token == TSL_TOKEN_RBRACKET) {
/* ']' after trailing ',' or an empty list */
@@ -200,7 +201,7 @@ static TslParseResult tsl_parser_parse_var_indexing(TslParser *self) {
return_if_error(tsl_tokenizer_accept(&self->tokenizer, TSL_TOKEN_LBRACKET));
return_if_error(tsl_parser_parse_rhs(self));
return_if_error(tsl_tokenizer_accept(&self->tokenizer, TSL_TOKEN_RBRACKET));
- return tsl_bytecode_writer_add_ins5(get_function_bytecode(self), TSL_OPCODE_MINDEX);
+ return tsl_bytecode_add_ins5(get_function_bytecode(self), TSL_OPCODE_MINDEX);
}
/* FUNC_CALL = '(' (RHS ',')* ')' */
@@ -239,7 +240,7 @@ static TslParseResult tsl_parser_parse_command(TslParser *self, int *num_args) {
TslCommandToken command_token = tsl_tokenizer_next_command_arg(&self->tokenizer, &command_arg);
if(command_token == TSL_COMMAND_TOKEN_ARG) {
++*num_args;
- return_if_error(tsl_bytecode_writer_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADCA, &command_arg));
+ return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADCA, &command_arg));
} else if(command_token == TSL_COMMAND_TOKEN_END) {
return TSL_PARSE_RESULT_OK;
} else {
@@ -270,14 +271,14 @@ static TslParseResult tsl_parser_parse_rhs_sub(TslParser *self) {
} else if(token == TSL_TOKEN_LPAREN) {
int num_args;
return_if_error(tsl_parser_parse_func_call(self, &num_args));
- return_if_error(tsl_bytecode_writer_add_ins1(get_function_bytecode(self), TSL_OPCODE_CALLF, num_args));
+ return_if_error(tsl_bytecode_add_ins1(get_function_bytecode(self), TSL_OPCODE_CALLF, num_args));
return tsl_parser_parse_rhs_sub(self);
} else if(token == TSL_TOKEN_ARITHMETIC) {
TslOpcode arithmetic_opcode;
tsl_tokenizer_consume_peek(&self->tokenizer); /* consume previous TSL_TOKEN_ARITHMETIC */
arithmetic_opcode = arithmetic_symbol_to_opcode(self->tokenizer.arithmetic_symbol);
/* TODO: Handle arithmetic expression precedence */
- return tsl_parser_parse_rhs(self) && tsl_bytecode_writer_add_ins5(get_function_bytecode(self), arithmetic_opcode);
+ return tsl_parser_parse_rhs(self) && tsl_bytecode_add_ins5(get_function_bytecode(self), arithmetic_opcode);
}
/*
No sub expression found, possibly a new expression after this (a new expression on a new line), let that
@@ -308,27 +309,27 @@ TslParseResult tsl_parser_parse_rhs(TslParser *self) {
switch(token) {
case TSL_TOKEN_IDENTIFIER: {
TslStringView var_name = self->tokenizer.identifier;
- return_if_error(tsl_bytecode_writer_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADV, &var_name));
+ return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADV, &var_name));
return tsl_parser_parse_rhs_sub(self);
}
case TSL_TOKEN_NUM:
- return_if_error(tsl_bytecode_writer_add_ins2(get_function_bytecode(self), TSL_OPCODE_LOADN, self->tokenizer.number_value));
+ return_if_error(tsl_bytecode_add_ins2(get_function_bytecode(self), TSL_OPCODE_LOADN, self->tokenizer.number_value));
return tsl_parser_parse_rhs_sub_arithmetic(self);
case TSL_TOKEN_BOOL:
- return tsl_bytecode_writer_add_ins3(get_function_bytecode(self), TSL_OPCODE_LOADB, self->tokenizer.bool_value);
+ return tsl_bytecode_add_ins3(get_function_bytecode(self), TSL_OPCODE_LOADB, self->tokenizer.bool_value);
case TSL_TOKEN_NULL:
- return tsl_bytecode_writer_add_ins5(get_function_bytecode(self), TSL_OPCODE_LOADNULL);
+ return tsl_bytecode_add_ins5(get_function_bytecode(self), TSL_OPCODE_LOADNULL);
case TSL_TOKEN_STRING:
- return tsl_bytecode_writer_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.string);
+ return tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.string);
case TSL_TOKEN_LBRACE: {
int num_items;
return tsl_parser_parse_map(self, &num_items) &&
- tsl_bytecode_writer_add_ins1(get_function_bytecode(self), TSL_OPCODE_MAP, num_items);
+ tsl_bytecode_add_ins1(get_function_bytecode(self), TSL_OPCODE_MAP, num_items);
}
case TSL_TOKEN_LBRACKET: {
int num_items;
return tsl_parser_parse_list(self, &num_items) &&
- tsl_bytecode_writer_add_ins1(get_function_bytecode(self), TSL_OPCODE_LIST, num_items);
+ tsl_bytecode_add_ins1(get_function_bytecode(self), TSL_OPCODE_LIST, num_items);
}
case TSL_TOKEN_FN: {
int function_index;
@@ -336,12 +337,12 @@ TslParseResult tsl_parser_parse_rhs(TslParser *self) {
return_if_error(tsl_parser_parse_fn(self));
function_index = tsl_parser_get_current_function_index(self);
tsl_parser_pop_function(self);
- return tsl_bytecode_writer_add_ins1(get_function_bytecode(self), TSL_OPCODE_LOADF, function_index);
+ return tsl_bytecode_add_ins1(get_function_bytecode(self), TSL_OPCODE_LOADF, function_index);
}
case TSL_TOKEN_DOLLAR_SIGN: {
int num_args;
return tsl_parser_parse_command(self, &num_args) &&
- tsl_bytecode_writer_add_ins1(get_function_bytecode(self), TSL_OPCODE_CALLC, num_args);
+ tsl_bytecode_add_ins1(get_function_bytecode(self), TSL_OPCODE_CALLC, num_args);
}
default:
fprintf(stderr, "Error: Expected variable, number, bool, null, map, list, function or command, got TODO (%d) (line: %d)\n", token, tsl_tokenizer_get_line_by_index(&self->tokenizer, self->tokenizer.prev_code_index));
@@ -361,10 +362,10 @@ TslParseResult tsl_parser_parse_expressions(TslParser *self, TslToken end_token)
if(tsl_tokenizer_peek(&self->tokenizer) == TSL_TOKEN_EQUAL) {
tsl_tokenizer_consume_peek(&self->tokenizer); /* consume previous TSL_TOKEN_EQUAL */
return_if_error(tsl_parser_parse_rhs(self));
- return_if_error(tsl_bytecode_writer_add_ins4(get_function_bytecode(self), TSL_OPCODE_SETV, &identifier));
+ return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_SETV, &identifier));
/* TODO: Assert if there are load bytecode opcodes not followed by set */
} else {
- return_if_error(tsl_bytecode_writer_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADV, &identifier));
+ return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADV, &identifier));
return_if_error(tsl_parser_parse_rhs_sub(self));
}
} else if(token == end_token) {
@@ -377,11 +378,20 @@ TslParseResult tsl_parser_parse_expressions(TslParser *self, TslToken end_token)
return TSL_PARSE_RESULT_OK;
}
-TslParseResult tsl_parse(const char *code, size_t code_size) {
+TslParseResult tsl_parse(const char *code, size_t code_size, TslProgram *program_output) {
TslParseResult result;
TslParser parser;
+
+ assert(code);
+ assert(program_output);
+
+ tsl_program_init(program_output);
return_if_error(tsl_parser_init(&parser, code, code_size));
+
result = tsl_parser_parse_expressions(&parser, TSL_TOKEN_END_OF_FILE);
+ if(result == TSL_PARSE_RESULT_OK)
+ tsl_buffer_move(&program_output->function_bytecode_list, &parser.function_bytecode_list);
+
tsl_parser_deinit(&parser);
return result;
}