Implements binding variables (including name shadowing)
This commit is contained in:
parent
8ab0282199
commit
b7f11d1fc2
1 changed files with 134 additions and 4 deletions
|
@ -207,8 +207,12 @@ FlupFunction* Interpreter_FindFunction(Interpreter* self, StringView name)
|
|||
|
||||
bool _are_types_compatible(enum ValueType type, StringView type_name)
|
||||
{
|
||||
const enum ValueType type_mapping[] = {VALUETYPE_INT64, VALUETYPE_DOUBLE};
|
||||
const char* name_mapping[] = {"int", "double"};
|
||||
if (StringView_Equal(type_name, StringView_FromString("any"))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const enum ValueType type_mapping[] = {VALUETYPE_INT64, VALUETYPE_DOUBLE, VALUETYPE_BOOLEAN, VALUETYPE_BOOLEAN};
|
||||
const char* name_mapping[] = {"int", "double", "bool", "boolean"};
|
||||
|
||||
for (size_t i = 0; i < sizeof(name_mapping) / sizeof(name_mapping[0]); i++) {
|
||||
if (1==1
|
||||
|
@ -419,6 +423,27 @@ int BuiltinFunction_Minus(CallFrame* top_frame)
|
|||
return CallFrame_StackPush(top_frame, &result);
|
||||
}
|
||||
|
||||
int Interpreter_GetParenthesizedRange(Interpreter* self, CallFrame* top_frame, size_t* paren_start, size_t* paren_end, size_t stop_token)
|
||||
{
|
||||
size_t open_paren_count = 0;
|
||||
size_t start_paren_index = top_frame->instruction_pointer;
|
||||
do {
|
||||
Token* t = Interpreter_ExpectToken(self, top_frame, stop_token);
|
||||
if (t == NULL) {
|
||||
// TODO: Error message
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
top_frame->instruction_pointer++;
|
||||
open_paren_count += t->type == TOKENTYPE_LEFT_PAREN;
|
||||
open_paren_count -= t->type == TOKENTYPE_RIGHT_PAREN;
|
||||
} while (open_paren_count != 0);
|
||||
size_t stop_paren_index = --top_frame->instruction_pointer;
|
||||
|
||||
if (paren_start != NULL) *paren_start = start_paren_index;
|
||||
if (paren_end != NULL) *paren_end = stop_paren_index;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token)
|
||||
{
|
||||
size_t frame_count = DynamicArray_GetLength(&self->call_frames);
|
||||
|
@ -485,6 +510,113 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token)
|
|||
break;
|
||||
}
|
||||
|
||||
case TOKENTYPE_BIND:
|
||||
{
|
||||
top_frame->instruction_pointer++;
|
||||
Token* identifier_token = Interpreter_ExpectToken(self, top_frame, stop_token);
|
||||
if (identifier_token == NULL) {
|
||||
// TODO: Error message
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// char variable_name[identifier_token->get.identifier.length + 1];
|
||||
// StringView_Paste(variable_name, identifier_token->get.identifier);
|
||||
// variable_name[identifier_token->get.identifier.length] = '\0';
|
||||
// printf("Binding variable with name %s\n", variable_name);
|
||||
|
||||
top_frame->instruction_pointer++;
|
||||
Token* as_token = Interpreter_ExpectToken(self, top_frame, stop_token);
|
||||
if (as_token == NULL) {
|
||||
// TODO: Error message
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
size_t as_token_index = top_frame->instruction_pointer;
|
||||
top_frame->instruction_pointer++;
|
||||
|
||||
size_t paren_start, paren_end;
|
||||
if (Interpreter_GetParenthesizedRange(self, top_frame, &paren_start, &paren_end, stop_token)) {
|
||||
// TODO: Error message
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
top_frame->instruction_pointer = as_token_index;
|
||||
|
||||
FlupFunction* evaluation_function = CallFrame_Reserve(top_frame, sizeof(FlupFunction), alignof(FlupFunction));
|
||||
if (evaluation_function == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
StringView evaluation_name = identifier_token->get.identifier;
|
||||
while (!StringView_StartsWith(evaluation_name, StringView_FromString("bind"))) {
|
||||
evaluation_name = (StringView) {
|
||||
.source = evaluation_name.source - 1,
|
||||
.length = evaluation_name.length + 1,
|
||||
};
|
||||
}
|
||||
evaluation_function->name = evaluation_name;
|
||||
evaluation_function->return_type = StringView_FromString("any");
|
||||
|
||||
FlupFunctionAlternative* evaluation_alternative = CallFrame_Reserve(top_frame, sizeof(FlupFunctionAlternative), alignof(FlupFunctionAlternative));
|
||||
if (evaluation_alternative == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
evaluation_alternative->body_token_start = paren_start + 1;
|
||||
evaluation_alternative->body_token_end = paren_end;
|
||||
evaluation_alternative->next = NULL;
|
||||
|
||||
evaluation_function->alternatives = evaluation_alternative;
|
||||
|
||||
FlupVariable* parent_variables = top_frame->variables;
|
||||
|
||||
CallFrame* evaluation_frame;
|
||||
DynamicArray_AppendEmpty(&self->call_frames, (void**) &evaluation_frame);
|
||||
if (evaluation_frame == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (CallFrame_Create(evaluation_frame, evaluation_function)) {
|
||||
return ENOMEM;
|
||||
}
|
||||
evaluation_frame->instruction_pointer = evaluation_alternative->body_token_start;
|
||||
evaluation_frame->variables = parent_variables;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TOKENTYPE_AS:
|
||||
{
|
||||
Value variable_value;
|
||||
if (CallFrame_StackPop(top_frame, &variable_value)) {
|
||||
// TODO: Error message
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
top_frame->instruction_pointer--;
|
||||
Token* identifier_token = Interpreter_ExpectToken(self, top_frame, stop_token);
|
||||
if (identifier_token == NULL) {
|
||||
// TODO: Error message
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// TODO: Type-check the token
|
||||
StringView variable_name = identifier_token->get.identifier;
|
||||
|
||||
if (CallFrame_DefineVariable(top_frame, variable_name, variable_value)) {
|
||||
// TODO: Error message
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
top_frame->instruction_pointer += 2; // points to opening paren
|
||||
size_t paren_end_index;
|
||||
if (Interpreter_GetParenthesizedRange(self, top_frame, NULL, &paren_end_index, stop_token)) {
|
||||
// TODO: Error message
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
top_frame->instruction_pointer = paren_end_index + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case TOKENTYPE_PIPE:
|
||||
case TOKENTYPE_SEMICOLON:
|
||||
case TOKENTYPE_LEFT_BRACE:
|
||||
|
@ -500,8 +632,6 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token)
|
|||
case TOKENTYPE_GREATERTHAN:
|
||||
case TOKENTYPE_GREATEREQUAL:
|
||||
case TOKENTYPE_COMMA:
|
||||
case TOKENTYPE_BIND:
|
||||
case TOKENTYPE_AS:
|
||||
case TOKENTYPE_LEFT_PAREN:
|
||||
case TOKENTYPE_RIGHT_PAREN:
|
||||
fprintf(stderr, "Unexpected token with type: %s\n, continuing with next token...\n", TokenType_ToString(t->type));
|
||||
|
|
Loading…
Reference in a new issue