Work in progress
This commit is contained in:
107
parser.cpp
107
parser.cpp
@@ -9,6 +9,7 @@
|
||||
#define MAX_LABELS 256
|
||||
#define MAX_EXTERNAL_FUNCTIONS 256
|
||||
#define MAX_IDENTIFIER_LENGTH 40
|
||||
#define MAX_CONSTANTS 256
|
||||
|
||||
struct t_label {
|
||||
char name[MAX_IDENTIFIER_LENGTH];
|
||||
@@ -33,6 +34,11 @@ struct t_string {
|
||||
int num_references = 1;
|
||||
};
|
||||
|
||||
struct t_constant {
|
||||
char name[MAX_IDENTIFIER_LENGTH];
|
||||
byte value;
|
||||
};
|
||||
|
||||
static byte* code; // [MAX_CODE_SIZE];
|
||||
static word codepos = 0;
|
||||
|
||||
@@ -57,6 +63,9 @@ static int num_strings = 0;
|
||||
|
||||
static bool parser_finished = false;
|
||||
|
||||
static t_constant constants[MAX_CONSTANTS];
|
||||
static int num_constants;
|
||||
|
||||
/****************************************************************************************/
|
||||
/* GENERIC FUNCTIONS */
|
||||
/****************************************************************************************/
|
||||
@@ -119,11 +128,27 @@ static int get_variable_index(const char* string, const int array_size = 1) {
|
||||
else {
|
||||
variables = newvar;
|
||||
}
|
||||
return newvar->index;
|
||||
return newvar->index + 0xC000;
|
||||
}
|
||||
|
||||
static bool is_variable_array() { return variable_is_array; }
|
||||
|
||||
/****************************************************************************************/
|
||||
/* CONSTANT MANAGEMENT */
|
||||
/****************************************************************************************/
|
||||
void parser_register_constant(const char* name, const unsigned char value) {
|
||||
strcpy(constants[num_constants].name, name);
|
||||
constants[num_constants++].value = value;
|
||||
}
|
||||
|
||||
static const int get_constant(const char* name) {
|
||||
for (int i = 0; i < num_constants; i++) {
|
||||
if (strcmp(constants[i].name, name) == 0)
|
||||
return constants[i].value;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
/* LABEL MANAGEMENT */
|
||||
/****************************************************************************************/
|
||||
@@ -167,7 +192,7 @@ static void register_label_address(const char* string) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
num_known_labels++;
|
||||
//num_known_labels++;
|
||||
}
|
||||
|
||||
static void generate_anonymous_labelname(char* dest) {
|
||||
@@ -206,6 +231,14 @@ static void append_strings() {
|
||||
static void parse_expression();
|
||||
static void parse_statements();
|
||||
|
||||
static void parse_strleft();
|
||||
static void parse_str();
|
||||
static void parse_chr();
|
||||
|
||||
static void parse_strlen();
|
||||
static void parse_keypressed();
|
||||
static void parse_anykey();
|
||||
|
||||
#define EXPECT(X, Y) if (tkn_get_token() != X) { parser_finished = true; error_raise(Y); return; }
|
||||
|
||||
static void parse_concat_atom() {
|
||||
@@ -227,6 +260,9 @@ static void parse_concat_atom() {
|
||||
tkn_next();
|
||||
return;
|
||||
}
|
||||
if (tkn_get_token() == TOKEN_STRLEFT) { tkn_next(); parse_strleft(); return; }
|
||||
if (tkn_get_token() == TOKEN_STR) { tkn_next(); parse_str(); return; }
|
||||
if (tkn_get_token() == TOKEN_CHR) { tkn_next(); parse_chr(); return; }
|
||||
parser_finished = true; error_raise("Syntax error");
|
||||
return;
|
||||
}
|
||||
@@ -248,6 +284,13 @@ static void parse_expr_atom() {
|
||||
return;
|
||||
}
|
||||
if (tkn_get_token() == TOKEN_IDENTIFIER) {
|
||||
int constvalue = get_constant(tkn_get_string());
|
||||
if (constvalue != -1) {
|
||||
emmit(OP_PUSH);
|
||||
emmit(constvalue);
|
||||
tkn_next();
|
||||
return;
|
||||
}
|
||||
int ivar = get_variable_index(tkn_get_string());
|
||||
if (is_variable_array()) {
|
||||
tkn_next(); EXPECT(TOKEN_LPAR, "Expected array index");
|
||||
@@ -282,6 +325,10 @@ static void parse_expr_atom() {
|
||||
tkn_next();
|
||||
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_ANYKEY) { tkn_next(); parse_anykey(); return; }
|
||||
|
||||
parser_finished = true; error_raise("Syntax error");
|
||||
return;
|
||||
}
|
||||
@@ -339,6 +386,17 @@ static void parse_expression() {
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_const() {
|
||||
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
|
||||
char constname[40];
|
||||
strcpy(constname, tkn_get_string());
|
||||
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();
|
||||
}
|
||||
|
||||
static void parse_dim() {
|
||||
EXPECT(TOKEN_IDENTIFIER, "Expected variable");
|
||||
char varname[40];
|
||||
@@ -674,9 +732,22 @@ static void parse_border() {
|
||||
emmit_w(get_label_address("_sys_vdp_border"));
|
||||
}
|
||||
|
||||
static void parse_clrscr() {
|
||||
emmit(OP_JSR);
|
||||
emmit_w(get_label_address("_sys_vdp_clrscr"));
|
||||
}
|
||||
|
||||
static void parse_wait() {
|
||||
parse_expression();
|
||||
emmit(OP_SLEEP);
|
||||
}
|
||||
|
||||
|
||||
static void parse_statements() {
|
||||
while (!parser_finished) {
|
||||
switch (tkn_get_token()) {
|
||||
case TOKEN_CONST:
|
||||
tkn_next(); parse_const(); break;
|
||||
case TOKEN_DIM:
|
||||
tkn_next(); parse_dim(); break;
|
||||
case TOKEN_LET:
|
||||
@@ -704,16 +775,16 @@ static void parse_statements() {
|
||||
case TOKEN_REM:
|
||||
tkn_next(); break;
|
||||
|
||||
case TOKEN_STRLEFT:
|
||||
tkn_next(); parse_strleft(); break;
|
||||
case TOKEN_STRLEN:
|
||||
tkn_next(); parse_strlen(); break;
|
||||
//case TOKEN_STRLEFT: <--- Parsed in parse_concat_atom
|
||||
// tkn_next(); parse_strleft(); break;
|
||||
//case TOKEN_STRLEN: <--- Parsed in parse_expr_atom
|
||||
// tkn_next(); parse_strlen(); break;
|
||||
case TOKEN_DEBUG:
|
||||
tkn_next(); parse_debug(); break;
|
||||
case TOKEN_CHR:
|
||||
tkn_next(); parse_chr(); break;
|
||||
case TOKEN_STR:
|
||||
tkn_next(); parse_str(); break;
|
||||
//case TOKEN_CHR:
|
||||
// tkn_next(); parse_chr(); break; <--- Parsed in parse_concat_atom
|
||||
//case TOKEN_STR:
|
||||
// tkn_next(); parse_str(); break; <--- Parsed in parse_concat_atom
|
||||
case TOKEN_SETSPRITE:
|
||||
tkn_next(); parse_setsprite(); break;
|
||||
case TOKEN_PUTSPRITE:
|
||||
@@ -726,16 +797,20 @@ static void parse_statements() {
|
||||
tkn_next(); parse_putchar(); break;
|
||||
case TOKEN_SETCHAR:
|
||||
tkn_next(); parse_setchar(); break;
|
||||
case TOKEN_KEYPRESSED:
|
||||
tkn_next(); parse_keypressed(); break;
|
||||
case TOKEN_ANYKEY:
|
||||
tkn_next(); parse_anykey(); break;
|
||||
//case TOKEN_KEYPRESSED: <--- Parsed in parse_expr_atom
|
||||
// tkn_next(); parse_keypressed(); break;
|
||||
//case TOKEN_ANYKEY: <--- Parsed in parse_expr_atom
|
||||
// tkn_next(); parse_anykey(); break;
|
||||
case TOKEN_UPDATESCR:
|
||||
tkn_next(); parse_updatescr(); break;
|
||||
case TOKEN_COLOR:
|
||||
tkn_next(); parse_color(); break;
|
||||
case TOKEN_BORDER:
|
||||
tkn_next(); parse_border(); break;
|
||||
case TOKEN_CLRSCR:
|
||||
tkn_next(); parse_clrscr(); break;
|
||||
case TOKEN_WAIT:
|
||||
tkn_next(); parse_wait(); break;
|
||||
|
||||
case TOKEN_IDENTIFIER:
|
||||
for (int i = 0; i < num_external_functions; i++) {
|
||||
@@ -781,6 +856,10 @@ void parser_parse(const char* buffer, byte* mem) {
|
||||
parse_statements();
|
||||
append_strings();
|
||||
|
||||
FILE *f = fopen("test.bin", "wb");
|
||||
fwrite(mem, codepos, 1, f);
|
||||
fclose(f);
|
||||
|
||||
//return code;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user