Started implementation of function parsing

This commit is contained in:
2021-05-04 18:49:18 +02:00
parent 2ff14cd2f1
commit 1516043f17
5 changed files with 144 additions and 22 deletions

View File

@@ -2,11 +2,13 @@
#include "tokenizer.h"
#include "scope.h"
#include "types.h"
#include "function.h"
#include "error.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stack>
#define MAX_CODE_SIZE 65536
#define MAX_LABELS 256
@@ -417,6 +419,7 @@ 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;
if (function_exists(identifier)) return true;
return false;
}
@@ -474,8 +477,7 @@ static void parse_var() {
static void parse_struct() {
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
char struct_name[40];
strcpy(struct_name, tkn_get_string());
const std::string struct_name = tkn_get_string();
if (identifier_exists(struct_name)) HALT("Identifier already exists");
const int struct_num = types_add(struct_name);
tkn_next();
@@ -485,7 +487,6 @@ static void parse_struct() {
char member_name[40];
strcpy(member_name, tkn_get_string());
tkn_next(); EXPECT(TOKEN_AS, "Expected 'as'");
// TODO [RZC 04/05/2021] Implement support for arrays
tkn_next();
if (tkn_get_token() == TOKEN_ARRAY) {
tkn_next(); EXPECT(TOKEN_OF, "Expected 'of'");
@@ -495,8 +496,7 @@ static void parse_struct() {
tkn_next();
}
EXPECT(TOKEN_IDENTIFIER, "Expected type identifier");
char type_name[40];
strcpy(type_name, tkn_get_string());
const std::string 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, member_length);
@@ -505,6 +505,51 @@ static void parse_struct() {
tkn_next();
}
static void parse_function() {
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
const std::string function_name = tkn_get_string();
if (identifier_exists(function_name)) HALT("Identifier already exists");
function_register(function_name, codepos);
tkn_next(); EXPECT(TOKEN_LPAR, "Expected '('");
tkn_next();
scope_open_local();
std::stack<uint32_t> addresses;
while (tkn_get_token() != TOKEN_RPAR) {
if (function_get_num_parameters() != 0) {
EXPECT(TOKEN_COMMA, "Expected ',' or ')'");
tkn_next();
}
EXPECT(TOKEN_IDENTIFIER, "Expected identifier");
const std::string param_name = tkn_get_string();
tkn_next(); EXPECT(TOKEN_AS, "Expected 'as'");
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");
if (!function_parameter_add(param_name, type_num)) HALT("Parameter name already used");
addresses.push(scope_declare_variable(param_name, type_num, 1));
tkn_next();
}
while (!addresses.empty()) {
emmit(OP_STL);
emmit_dw(addresses.top());
addresses.pop();
}
tkn_next();
if (tkn_get_token() == TOKEN_AS) {
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");
function_set_type(type_num);
tkn_next();
}
parse_statements();
scope_close_local();
EXPECT(TOKEN_END, "Expected statement or 'end'");
tkn_next();
}
/*static void parse_dim() {
EXPECT(TOKEN_IDENTIFIER, "Expected variable");
char varname[40];
@@ -703,12 +748,19 @@ static void parse_gosub() {
tkn_next();
}*/
/*
static void parse_return() {
// TODO [RZC 27/04/2021] Falta afegir paràmetre de retorn
const int return_type = function_get_type();
if (return_type != -1) {
if (return_type == 0) {
parse_expression();
} else if (return_type == 1) {
// TODO [RZC 04/05/2021] Falta gestionar tipus string
}
}
emmit(OP_RET);
}
*/
// XXX [RZC 27/04/2021] No hi ha labels
/*static void parse_label() {
@@ -737,21 +789,16 @@ static void parse_call() {
}
}
}
*/
static void parse_statements() {
while (!parser_finished) {
current_line = tkn_get_line();
switch (tkn_get_token()) {
case TOKEN_CONST:
tkn_next(); parse_const(); break;
case TOKEN_DIM:
tkn_next(); parse_dim(); break;
case TOKEN_LET:
tkn_next(); parse_let(); break;
case TOKEN_INC:
tkn_next(); parse_inc(); break;
case TOKEN_DEC:
tkn_next(); parse_dec(); break;
case TOKEN_VAR:
tkn_next(); parse_var(); break;
/*
case TOKEN_IF:
tkn_next(); parse_if(); break;
case TOKEN_FOR:
@@ -760,23 +807,25 @@ static void parse_statements() {
tkn_next(); parse_break(); break;
case TOKEN_CONTINUE:
tkn_next(); parse_continue(); break;
*/
case TOKEN_RETURN:
tkn_next(); parse_return(); break;
case TOKEN_REM:
tkn_next(); break;
/*
case TOKEN_IDENTIFIER:
for (int i = 0; i < num_external_functions; i++) {
if (strcmp(external_functions[i].name, tkn_get_string()) == 0) { parse_call(); break; }
}
parse_let(); break;
*/
default:
return;
}
}
}
*/
static void parse_global_statements() {
while (!parser_finished) {
current_line = tkn_get_line();
@@ -787,8 +836,8 @@ static void parse_global_statements() {
tkn_next(); parse_var(); break;
case TOKEN_STRUCT:
tkn_next(); parse_struct(); break;
/*case TOKEN_FUNCTION:
tkn_next(); parse_function(); break;*/
case TOKEN_FUNCTION:
tkn_next(); parse_function(); break;
case TOKEN_REM:
tkn_next(); break;
case TOKEN_ENDFILE: