[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
|
.vscode
|
||||||
*.exe
|
*.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_expression();
|
||||||
static void parse_statements();
|
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_strleft();
|
||||||
static void parse_str();
|
static void parse_str();
|
||||||
static void parse_chr();
|
static void parse_chr();
|
||||||
@@ -339,7 +339,7 @@ static void parse_expr_atom() {
|
|||||||
tkn_next();
|
tkn_next();
|
||||||
return;
|
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_STRLEN) { tkn_next(); parse_strlen(); return; }
|
||||||
if (tkn_get_token() == TOKEN_KEYPRESSED) { tkn_next(); parse_keypressed(); 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() {
|
static void parse_const() {
|
||||||
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
|
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
|
||||||
char const_name[40];
|
char const_name[40];
|
||||||
strcpy(const_name, tkn_get_string());
|
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_AS, "Expected 'as'");
|
||||||
tkn_next(); EXPECT(TOKEN_IDENTIFIER, "Expected type identifier");
|
tkn_next(); EXPECT(TOKEN_IDENTIFIER, "Expected type identifier");
|
||||||
char type_name[40];
|
char type_name[40];
|
||||||
strcpy(type_name, tkn_get_string());
|
strcpy(type_name, tkn_get_string());
|
||||||
const int type_num = types_exist(type_name);
|
const int type_num = types_exist(type_name);
|
||||||
if (type_num == -1) HALT("Unknown type");
|
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(); EXPECT(TOKEN_EQ, "Expected '='");
|
||||||
tkn_next(); parse_expression();
|
tkn_next(); parse_expression();
|
||||||
const int var_address = scope_declare_variable(const_name, type_num, 0);
|
const int var_address = scope_declare_variable(const_name, type_num, 0);
|
||||||
@@ -428,6 +435,61 @@ static void parse_const() {
|
|||||||
//tkn_next();
|
//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() {
|
/*static void parse_dim() {
|
||||||
EXPECT(TOKEN_IDENTIFIER, "Expected variable");
|
EXPECT(TOKEN_IDENTIFIER, "Expected variable");
|
||||||
char varname[40];
|
char varname[40];
|
||||||
@@ -706,11 +768,11 @@ static void parse_global_statements() {
|
|||||||
switch (tkn_get_token()) {
|
switch (tkn_get_token()) {
|
||||||
case TOKEN_CONST:
|
case TOKEN_CONST:
|
||||||
tkn_next(); parse_const(); break;
|
tkn_next(); parse_const(); break;
|
||||||
/*case TOKEN_VAR:
|
case TOKEN_VAR:
|
||||||
tkn_next(); parse_var(); break;
|
tkn_next(); parse_var(); break;
|
||||||
case TOKEN_STRUCT:
|
case TOKEN_STRUCT:
|
||||||
tkn_next(); parse_struct(); break;
|
tkn_next(); parse_struct(); break;
|
||||||
case TOKEN_FUNCTION:
|
/*case TOKEN_FUNCTION:
|
||||||
tkn_next(); parse_function(); break;*/
|
tkn_next(); parse_function(); break;*/
|
||||||
case TOKEN_REM:
|
case TOKEN_REM:
|
||||||
tkn_next(); break;
|
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() {
|
/*static void include_labels() {
|
||||||
FILE *f = fopen("rom.lbl", "rb");
|
FILE *f = fopen("rom.lbl", "rb");
|
||||||
byte num_labels;
|
byte num_labels;
|
||||||
|
|||||||
2
parser.h
2
parser.h
@@ -17,7 +17,7 @@ enum OPS {
|
|||||||
OP_JTR,
|
OP_JTR,
|
||||||
OP_RET,
|
OP_RET,
|
||||||
OP_CALL,
|
OP_CALL,
|
||||||
OP_CALLEX, // AFEGIT PER A JAILSCRIPT
|
OP_CALLEX, // AFEGIT PER A JAILBASIC
|
||||||
|
|
||||||
OP_ADD,
|
OP_ADD,
|
||||||
OP_SUB,
|
OP_SUB,
|
||||||
|
|||||||
@@ -53,14 +53,14 @@ void scope_close_block() {
|
|||||||
while (local.variables.size() > size_before_block) local.variables.pop_back();
|
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);
|
t_scope& scope = (are_we_inside_local ? local : global);
|
||||||
if (are_we_inside_local) {
|
if (are_we_inside_local) {
|
||||||
for (int i = blocks.top(); i < scope.variables.size(); i++ ) if (scope.variables[i].name == name) return -1;
|
for (int i = blocks.top(); i < scope.variables.size(); i++ ) if (scope.variables[i].name == name) return -1;
|
||||||
} else {
|
} else {
|
||||||
for (t_variable v : scope.variables) if (v.name == name) return -1;
|
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};
|
const t_variable var {name, type, length, address};
|
||||||
scope.variables.push_back(var);
|
scope.variables.push_back(var);
|
||||||
scope.total_size += types_get_length(type) + (length == 0 ? 1 : length);
|
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_open_block();
|
||||||
void scope_close_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 bool scope_variable_exists(const std::string name);
|
||||||
const uint32_t scope_get_variable_address();
|
const uint32_t scope_get_variable_address();
|
||||||
|
|||||||
8
test.vb
8
test.vb
@@ -1,2 +1,8 @@
|
|||||||
' Esto es un comentario
|
' 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 == '%') { NEXT; current_token = TOKEN_MOD; return; }
|
||||||
if (CCHR == 39) { NEXT; current_token = TOKEN_REM; while (CCHR != 0 && CCHR != 10) { NEXT; }; 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 == '&') {
|
/*if (CCHR == '&') {
|
||||||
NEXT;
|
NEXT;
|
||||||
if ((CCHR | 32) == 'h') {
|
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;
|
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
|
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;
|
for (auto m : types[type].members) if (m.name == name) return -1;
|
||||||
const t_variable new_var {name, var_type, length};
|
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;
|
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
|
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;
|
for (int i = 0; i < types[type].members.size(); i++) if (types[type].members[i].name == name) return i;
|
||||||
return -1;
|
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 (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
|
if (member >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||||
return types[type].members[variable].type;
|
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 (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
|
if (member >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai
|
||||||
return types[type].members[variable].length;
|
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_exist(const std::string name);
|
||||||
const int types_get_length(const uint32_t type);
|
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_add_member(const uint32_t type, const std::string name, const uint32_t var_type, const uint32_t length);
|
||||||
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);
|
||||||
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);
|
||||||
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);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
struct t_variable {
|
struct t_variable {
|
||||||
std::string name;
|
std::string name;
|
||||||
int type;
|
uint32_t type;
|
||||||
int length;
|
uint32_t length;
|
||||||
int address;
|
uint32_t address;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user