diff --git a/.gitignore b/.gitignore index b15602d..67fcd98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode +*.exe diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..d871ee4 --- /dev/null +++ b/main.cpp @@ -0,0 +1,21 @@ +#include "parser.h" +#include +#include + +static unsigned char mem[65536]; + +int main(void) { + + FILE *f = fopen("test.vb", "rb"); + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); //same as rewind(f); + char *program = (char*)malloc(fsize + 1); + fread(program, fsize, 1, f); + fclose(f); + program[fsize] = 0; + parser_parse(program, mem); + free(program); + + return 0; +} \ No newline at end of file diff --git a/parser.cpp b/parser.cpp index 2586b89..e8e9ba0 100644 --- a/parser.cpp +++ b/parser.cpp @@ -1,5 +1,7 @@ #include "parser.h" #include "tokenizer.h" +#include "scope.h" +#include "types.h" #include "error.h" #include #include @@ -159,7 +161,7 @@ static const uint32_t get_current_address() { /****************************************************************************************/ /* LABEL MANAGEMENT */ /****************************************************************************************/ - +/* static const word get_label_address(const char* string) { for (int i = 0; i < num_known_labels; i++) { if (strcmp(known_labels[i].name, string) == 0) return known_labels[i].address; } //unknown_labels[num_unknown_labels].name = (char*)malloc(strlen(string) + 1); @@ -205,54 +207,9 @@ static void register_label_address(const char* string) { static void generate_anonymous_labelname(char* dest) { int_to_string(num_anonymous_labels++, dest); } +*/ -/****************************************************************************************/ -/* STRING MANAGEMENT */ -/****************************************************************************************/ -static const bool same_string(const unsigned char* a, const unsigned char*b) { - for (int i = 0; i <= a[0]; i++) if (a[i] != b[i]) return false; - return true; -} -static void copy_string(unsigned char* dest, const unsigned char* src) { - memcpy(dest, src, src[0] + 1); - //for (int i = 0; i <= src[0]; i++) dest[i] = src[i]; -} -static void to_basic_string(unsigned char* dest, const char* src) { - int len = strlen(src); - *dest = len; dest++; - memcpy(dest, src, len); -} -static int register_array(const unsigned char* string) { - for (int i = 0; i < num_strings; i++) { - if (same_string(strings[i].string, string)) { strings[i].references[strings[i].num_references++] = get_current_address(); return 0; } - } - copy_string(strings[num_strings].string, string); - strings[num_strings++].references[0] = get_current_address(); - return 0; -} - -static int register_string(const char* string) { - unsigned char new_str[255]; to_basic_string(new_str, string); - for (int i = 0; i < num_strings; i++) { - if (same_string(strings[i].string, new_str)) { strings[i].references[strings[i].num_references++] = get_current_address(); return 0; } - } - copy_string(strings[num_strings].string, new_str); - strings[num_strings++].references[0] = get_current_address(); - return 0; -} - -static void append_strings() { - code[0] = codepos & 255; - code[1] = codepos >> 8; - emmit(num_strings); - for (int i = 0; i < num_strings; i++) { - for (int j = 0; j < strings[i].num_references; j++) { patch(strings[i].references[j], get_current_address()); } - //char len = strings[i].string[0]; - //emmit(len); - for (int j = 0; j <= strings[i].string[0]; j++) { emmit(strings[i].string[j]); } - } -} /****************************************************************************************/ /* PARSER */ @@ -274,7 +231,9 @@ static void parse_getcolor(); */ #define EXPECT(X, Y) if (tkn_get_token() != X) { parser_finished = true; error_raise(Y); return; } +#define HALT(Y) { parser_finished = true; error_raise(Y); return; } +/* static void parse_concat_atom() { if (tkn_get_token() == TOKEN_STRING) { emmit(OP_SETX); @@ -316,6 +275,7 @@ static void parse_concatenation() { emmit(OP_CONCAT); } } +*/ static void parse_expr_atom() { // NUM, VAR, UNARY, PAREN @@ -326,6 +286,17 @@ static void parse_expr_atom() { return; } if (tkn_get_token() == TOKEN_IDENTIFIER) { + if (scope_variable_exists(tkn_get_string())) { + // [RZC 03/05/2021] TODO: Revisar si hi ha que navegar un struct o array + emmit(scope_is_local() ? OP_LDL : OP_LD); + emmit(scope_get_variable_address()); + tkn_next(); + return; + } else { + // [RZC 03/05/2021] TODO: Revisar funcions + parser_finished = true; error_raise("Syntax error"); + return; + } // [RZC 27/04/2021] Per ara llevem les constants /*int constvalue = get_constant(tkn_get_string()); if (constvalue != -1) { @@ -348,9 +319,6 @@ static void parse_expr_atom() { emmit(OP_LOAD); emmit_w(ivar); }*/ - // [RZC 27/04/2021] Atenció! Ara les variables han de estar declarades abans, pel que pot haver error ací si no s'ha trobat. - tkn_next(); - return; } if (tkn_get_token() == TOKEN_MINUS) { tkn_next(); @@ -449,14 +417,17 @@ static void parse_const() { tkn_next(); EXPECT(TOKEN_IDENTIFIER, "Expected type identifier"); char type_name[40]; strcpy(type_name, tkn_get_string()); + const int type_num = types_exist(type_name); + if (type_num == -1) HALT("Unknown type"); + const int var_address = scope_declare_variable(const_name, type_num, 0); tkn_next(); EXPECT(TOKEN_EQ, "Expected '='"); - tkn_next(); EXPECT(TOKEN_NUMBER, "Expected integer constant"); - int constvalue = tkn_get_value(); - parser_register_constant(constname, constvalue); + tkn_next(); parse_expression(); + emmit(scope_is_local() ? OP_STL : OP_ST); + emmit_dw(var_address); tkn_next(); } -static void parse_dim() { +/*static void parse_dim() { EXPECT(TOKEN_IDENTIFIER, "Expected variable"); char varname[40]; strcpy(varname, tkn_get_string()); @@ -465,7 +436,7 @@ static void parse_dim() { get_variable_index(varname, tkn_get_value()); // register variable with size, no need to keep ival tkn_next(); EXPECT(TOKEN_RPAR, "Expected ')'"); tkn_next(); -} +}*/ // [RZC 27/04/2021] Desactivat INC i DEC per ara /*static void parse_inc() { EXPECT(TOKEN_IDENTIFIER, "Expected variable"); @@ -546,6 +517,7 @@ static void parse_dec() { } }*/ +/* static void parse_if() { char* previous_breaklabel = breaklabel; parse_expression(); @@ -636,6 +608,7 @@ static void parse_continue() { emmit(OP_JMP); emmit_w(get_label_address(contlabel)); } +*/ // [RZC 27/04/2021] Ni GOTO ni GOSUB /*static void parse_goto() { @@ -652,10 +625,12 @@ static void parse_gosub() { tkn_next(); }*/ +/* static void parse_return() { // [RZC 27/04/2021] [TODO] Falta afegir paràmetre de retorn emmit(OP_RET); } +*/ // [RZC 27/04/2021] No hi ha labels /*static void parse_label() { @@ -663,6 +638,7 @@ static void parse_return() { tkn_next(); }*/ +/* static void parse_call() { for (int i = 0; i < num_external_functions; i++) { if (strcmp(external_functions[i].name, tkn_get_string()) == 0) { @@ -702,10 +678,10 @@ static void parse_statements() { tkn_next(); parse_if(); break; case TOKEN_FOR: tkn_next(); parse_for(); break; - /*case TOKEN_BREAK: + case TOKEN_BREAK: tkn_next(); parse_break(); break; case TOKEN_CONTINUE: - tkn_next(); parse_continue(); break;*/ + tkn_next(); parse_continue(); break; case TOKEN_RETURN: tkn_next(); parse_return(); break; case TOKEN_REM: @@ -722,21 +698,25 @@ static void parse_statements() { } } +*/ static void parse_global_statements() { while (!parser_finished) { current_line = tkn_get_line(); switch (tkn_get_token()) { case TOKEN_CONST: tkn_next(); parse_const(); break; - case TOKEN_VAR: + /*case TOKEN_VAR: tkn_next(); parse_var(); break; case TOKEN_STRUCT: tkn_next(); parse_struct(); break; case TOKEN_FUNCTION: - tkn_next(); parse_function(); break; + tkn_next(); parse_function(); break;*/ case TOKEN_REM: tkn_next(); break; + case TOKEN_ENDFILE: + return; default: + HALT("Syntax error"); return; } } @@ -767,6 +747,8 @@ static void parse_global_statements() { void parser_parse(const char* buffer, byte* mem) { tkn_init(buffer); + scope_init(); + types_init(); parser_finished = false; //include_labels(); code = mem; @@ -774,7 +756,7 @@ void parser_parse(const char* buffer, byte* mem) { tkn_next(); parse_global_statements(); - append_strings(); // [RZC 27/04/2021] [TODO] Encara vull açò? si el bytecode no ha de ser independent, no veig que faça falta + //append_strings(); // [RZC 27/04/2021] [TODO] Encara vull açò? si el bytecode no ha de ser independent, no veig que faça falta if (error_raised()) { // [RZC 27/04/2021] Res, per ara que printf el error i pete error_print(NULL); @@ -790,11 +772,13 @@ void parser_parse(const char* buffer, byte* mem) { //return code; } -const int parser_get_codesize() { return codepos; } -const int parser_get_memory_usage() { return num_variables; } -unsigned short* parser_get_lines() { return lines; } +//const int parser_get_codesize() { return codepos; } +//const int parser_get_memory_usage() { return num_variables; } +//unsigned short* parser_get_lines() { return lines; } +/* void parser_register_external_function(const char* name, const char* parameters, void (*fun)(void)) { strcpy(external_functions[num_external_functions].name, name); external_functions[num_external_functions++].num_parameters = num_parameters; } +*/ diff --git a/parser.h b/parser.h index 081ba97..9db0b0a 100644 --- a/parser.h +++ b/parser.h @@ -7,8 +7,10 @@ enum OPS { OP_DUP, OP_SWAP, - OP_LOAD, - OP_STORE, + OP_LD, + OP_ST, + OP_LDL, + OP_STL, OP_JMP, OP_JNT, diff --git a/scope.cpp b/scope.cpp index cbf6bfa..afe50cd 100644 --- a/scope.cpp +++ b/scope.cpp @@ -24,6 +24,10 @@ void scope_init() { are_we_inside_local = false; } +const bool scope_is_local() { + return are_we_inside_local; +} + void scope_open_local() { are_we_inside_local = true; } @@ -49,7 +53,7 @@ void scope_close_block() { while (local.variables.size() > size_before_block) local.variables.pop_back(); } -const uint32_t scope_declare_variable(const std::string name, const int type, const int length) { +const int scope_declare_variable(const std::string name, const int type, const int length) { t_scope& scope = (are_we_inside_local ? local : global); if (are_we_inside_local) { for (int i = blocks.top(); i < scope.variables.size(); i++ ) if (scope.variables[i].name == name) return -1; @@ -69,6 +73,7 @@ const bool scope_variable_exists(const std::string name) { current_var = &v; return true; } + return false; } const uint32_t scope_get_variable_address() { diff --git a/scope.h b/scope.h index 6771304..3b8a57a 100644 --- a/scope.h +++ b/scope.h @@ -3,12 +3,13 @@ #include void scope_init(); +const bool scope_is_local(); void scope_open_local(); const int scope_close_local(); void scope_open_block(); void scope_close_block(); -const uint32_t scope_declare_variable(const std::string name, const int type, const int length); +const int scope_declare_variable(const std::string name, const int type, const int length); const bool scope_variable_exists(const std::string name); const uint32_t scope_get_variable_address(); diff --git a/test.vb b/test.vb new file mode 100644 index 0000000..4bd08a8 --- /dev/null +++ b/test.vb @@ -0,0 +1,4 @@ + +' Esto es un comentario + +const perico as number = 4-2