[BUG] Repaired types on some parameters.
[FEAT] Implemented struct, still testing. [FEAT] Implemented var, still testing.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
|
||||
.vscode
|
||||
*.exe
|
||||
jb
|
||||
|
||||
74
parser.cpp
74
parser.cpp
@@ -218,7 +218,7 @@ static void generate_anonymous_labelname(char* dest) {
|
||||
static void parse_expression();
|
||||
static void parse_statements();
|
||||
|
||||
/* [RZC 27/04/2021] No usat en JailScript
|
||||
/* [RZC 27/04/2021] No usat en JailBasic
|
||||
//static void parse_strleft();
|
||||
static void parse_str();
|
||||
static void parse_chr();
|
||||
@@ -339,7 +339,7 @@ static void parse_expr_atom() {
|
||||
tkn_next();
|
||||
return;
|
||||
}
|
||||
// [RZC 27/04/2021] No usat en JailScript, pero hi haurà que afegir les funcions
|
||||
// [RZC 27/04/2021] No usat en JailBasic, pero hi haurà que afegir les funcions
|
||||
/*
|
||||
if (tkn_get_token() == TOKEN_STRLEN) { tkn_next(); parse_strlen(); return; }
|
||||
if (tkn_get_token() == TOKEN_KEYPRESSED) { tkn_next(); parse_keypressed(); return; }
|
||||
@@ -409,17 +409,24 @@ static void parse_expression() {
|
||||
}
|
||||
}
|
||||
|
||||
static bool identifier_exists(const std::string identifier) {
|
||||
if (scope_variable_exists(identifier)) return true;
|
||||
if (types_exist(identifier) != -1) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void parse_const() {
|
||||
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
|
||||
char const_name[40];
|
||||
strcpy(const_name, tkn_get_string());
|
||||
if (scope_variable_exists(const_name)) HALT("Identifier already exists");
|
||||
if (identifier_exists(const_name)) HALT("Identifier already exists");
|
||||
tkn_next(); EXPECT(TOKEN_AS, "Expected 'as'");
|
||||
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");
|
||||
if (type_num >= 2) HALT("Only 'number' or 'string' constants allowed");
|
||||
tkn_next(); EXPECT(TOKEN_EQ, "Expected '='");
|
||||
tkn_next(); parse_expression();
|
||||
const int var_address = scope_declare_variable(const_name, type_num, 0);
|
||||
@@ -428,6 +435,61 @@ static void parse_const() {
|
||||
//tkn_next();
|
||||
}
|
||||
|
||||
static void parse_var() {
|
||||
int var_length = 1;
|
||||
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
|
||||
const std::string var_name = tkn_get_string();
|
||||
if (identifier_exists(var_name)) HALT("Identifier already exists");
|
||||
tkn_next(); EXPECT(TOKEN_AS, "Expected 'as'");
|
||||
tkn_next();
|
||||
if (tkn_get_token() == TOKEN_ARRAY) {
|
||||
tkn_next(); EXPECT(TOKEN_OF, "Expected 'of'");
|
||||
tkn_next(); EXPECT(TOKEN_NUMBER, "Expected number"); // [RZC 04/05/2021] TODO: Només deuria acceptar enters.
|
||||
var_length = tkn_get_value();
|
||||
tkn_next();
|
||||
}
|
||||
EXPECT(TOKEN_IDENTIFIER, "Expected type identifier");
|
||||
const std::string type_name = tkn_get_string();
|
||||
const int type_num = types_exist(type_name);
|
||||
if (type_num == -1) HALT("Unknown type");
|
||||
tkn_next();
|
||||
if (tkn_get_token() == TOKEN_EQ) {
|
||||
if (type_num >= 2) HALT("Only 'number' or 'string' variables can be initialized on declaration")
|
||||
if (var_length > 1) HALT("Array variables cannot be initialized on declaration")
|
||||
tkn_next(); parse_expression();
|
||||
const int var_address = scope_declare_variable(var_name, type_num, var_length);
|
||||
emmit(scope_is_local() ? OP_STL : OP_ST);
|
||||
emmit_dw(var_address);
|
||||
} else {
|
||||
scope_declare_variable(var_name, type_num, var_length);
|
||||
//tkn_next();
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_struct() {
|
||||
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
|
||||
char struct_name[40];
|
||||
strcpy(struct_name, tkn_get_string());
|
||||
if (identifier_exists(struct_name)) HALT("Identifier already exists");
|
||||
const int struct_num = types_add(struct_name);
|
||||
tkn_next();
|
||||
while (tkn_get_token() != TOKEN_END) {
|
||||
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
|
||||
char member_name[40];
|
||||
strcpy(member_name, tkn_get_string());
|
||||
tkn_next(); EXPECT(TOKEN_AS, "Expected 'as'");
|
||||
// [RZC 04/05/2021] TODO: Implement support for arrays
|
||||
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");
|
||||
types_add_member(struct_num, member_name, type_num, 1);
|
||||
tkn_next();
|
||||
}
|
||||
tkn_next();
|
||||
}
|
||||
|
||||
/*static void parse_dim() {
|
||||
EXPECT(TOKEN_IDENTIFIER, "Expected variable");
|
||||
char varname[40];
|
||||
@@ -706,11 +768,11 @@ static void parse_global_statements() {
|
||||
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:
|
||||
/*case TOKEN_FUNCTION:
|
||||
tkn_next(); parse_function(); break;*/
|
||||
case TOKEN_REM:
|
||||
tkn_next(); break;
|
||||
@@ -723,7 +785,7 @@ static void parse_global_statements() {
|
||||
}
|
||||
}
|
||||
|
||||
// [RZC 27/04/2021] No usat en JailScript
|
||||
// [RZC 27/04/2021] No usat en JailBasic
|
||||
/*static void include_labels() {
|
||||
FILE *f = fopen("rom.lbl", "rb");
|
||||
byte num_labels;
|
||||
|
||||
2
parser.h
2
parser.h
@@ -17,7 +17,7 @@ enum OPS {
|
||||
OP_JTR,
|
||||
OP_RET,
|
||||
OP_CALL,
|
||||
OP_CALLEX, // AFEGIT PER A JAILSCRIPT
|
||||
OP_CALLEX, // AFEGIT PER A JAILBASIC
|
||||
|
||||
OP_ADD,
|
||||
OP_SUB,
|
||||
|
||||
@@ -53,14 +53,14 @@ void scope_close_block() {
|
||||
while (local.variables.size() > size_before_block) local.variables.pop_back();
|
||||
}
|
||||
|
||||
const int scope_declare_variable(const std::string name, const int type, const int length) {
|
||||
const int scope_declare_variable(const std::string name, const uint32_t type, const uint32_t 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;
|
||||
} else {
|
||||
for (t_variable v : scope.variables) if (v.name == name) return -1;
|
||||
}
|
||||
const int address = scope.total_size;
|
||||
const uint32_t address = scope.total_size;
|
||||
const t_variable var {name, type, length, address};
|
||||
scope.variables.push_back(var);
|
||||
scope.total_size += types_get_length(type) + (length == 0 ? 1 : length);
|
||||
|
||||
2
scope.h
2
scope.h
@@ -9,7 +9,7 @@ const int scope_close_local();
|
||||
void scope_open_block();
|
||||
void scope_close_block();
|
||||
|
||||
const int scope_declare_variable(const std::string name, const int type, const int length);
|
||||
const int scope_declare_variable(const std::string name, const uint32_t type, const uint32_t length);
|
||||
|
||||
const bool scope_variable_exists(const std::string name);
|
||||
const uint32_t scope_get_variable_address();
|
||||
|
||||
8
test.vb
8
test.vb
@@ -1,2 +1,8 @@
|
||||
' Esto es un comentario
|
||||
const perico as number = 4-perico
|
||||
struct point
|
||||
x as number
|
||||
y as number
|
||||
end
|
||||
|
||||
var peiv as point
|
||||
const perico as number = 4-peiv
|
||||
|
||||
@@ -118,7 +118,7 @@ static void tkn_do_next() {
|
||||
if (CCHR == '%') { NEXT; current_token = TOKEN_MOD; return; }
|
||||
if (CCHR == 39) { NEXT; current_token = TOKEN_REM; while (CCHR != 0 && CCHR != 10) { NEXT; }; return; }
|
||||
|
||||
// Per a agafar numeros en hexadecimal o binari, heretat de PaCO, no se si li fa falta a JailScript
|
||||
// Per a agafar numeros en hexadecimal o binari, heretat de PaCO, no se si li fa falta a JailBasic
|
||||
/*if (CCHR == '&') {
|
||||
NEXT;
|
||||
if ((CCHR | 32) == 'h') {
|
||||
|
||||
16
types.cpp
16
types.cpp
@@ -32,7 +32,7 @@ const int types_get_length(const uint32_t type) {
|
||||
return types[type].size;
|
||||
}
|
||||
|
||||
const int types_add_variable(const uint32_t type, const std::string name, const int var_type, const int length) {
|
||||
const int types_add_member(const uint32_t type, const std::string name, const uint32_t var_type, const uint32_t length) {
|
||||
if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||
for (auto m : types[type].members) if (m.name == name) return -1;
|
||||
const t_variable new_var {name, var_type, length};
|
||||
@@ -41,20 +41,20 @@ const int types_add_variable(const uint32_t type, const std::string name, const
|
||||
return types[type].members.size()-1;
|
||||
}
|
||||
|
||||
const int types_variable_exists(const uint32_t type, const std::string name) {
|
||||
const int types_member_exists(const uint32_t type, const std::string name) {
|
||||
if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||
for (int i = 0; i < types[type].members.size(); i++) if (types[type].members[i].name == name) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int types_get_variable_type(const uint32_t type, const uint32_t variable) {
|
||||
const int types_get_member_type(const uint32_t type, const uint32_t member) {
|
||||
if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||
if (variable >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||
return types[type].members[variable].type;
|
||||
if (member >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||
return types[type].members[member].type;
|
||||
}
|
||||
|
||||
const int types_get_variable_length(const uint32_t type, const uint32_t variable) {
|
||||
const int types_get_member_length(const uint32_t type, const uint32_t member) {
|
||||
if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||
if (variable >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||
return types[type].members[variable].length;
|
||||
if (member >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||
return types[type].members[member].length;
|
||||
}
|
||||
8
types.h
8
types.h
@@ -7,7 +7,7 @@ const int types_add(const std::string name);
|
||||
const int types_exist(const std::string name);
|
||||
const int types_get_length(const uint32_t type);
|
||||
|
||||
const int types_add_variable(const uint32_t type, const std::string name, const uint32_t var_type, const int length);
|
||||
const int types_variable_exists(const uint32_t type, const std::string name);
|
||||
const int types_get_variable_type(const uint32_t type, const uint32_t variable);
|
||||
const int types_get_variable_length(const uint32_t type, const uint32_t variable);
|
||||
const int types_add_member(const uint32_t type, const std::string name, const uint32_t var_type, const uint32_t length);
|
||||
const int types_member_exists(const uint32_t type, const std::string name);
|
||||
const int types_get_member_type(const uint32_t type, const uint32_t member);
|
||||
const int types_get_member_length(const uint32_t type, const uint32_t member);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
struct t_variable {
|
||||
std::string name;
|
||||
int type;
|
||||
int length;
|
||||
int address;
|
||||
uint32_t type;
|
||||
uint32_t length;
|
||||
uint32_t address;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user