Roadmap.md file, fixed main frame memory leak
This commit is contained in:
parent
fcdbc8e6a9
commit
22394b2d6e
2 changed files with 81 additions and 43 deletions
17
Roadmap.md
Normal file
17
Roadmap.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Features
|
||||||
|
- Strings
|
||||||
|
- Listen
|
||||||
|
- Müllabfuhr
|
||||||
|
- Innere Funktionsdefinition
|
||||||
|
- Semikolon am Ende der Datei
|
||||||
|
- at Annotations
|
||||||
|
- Datentypen
|
||||||
|
- Kommentare
|
||||||
|
- Native Functions
|
||||||
|
- Kontrollstrukturen
|
||||||
|
- goto
|
||||||
|
- variablen
|
||||||
|
|
||||||
|
## builtins
|
||||||
|
- I/O (print, readline, read\*, write\*)
|
||||||
|
- always, never, otherwise
|
|
@ -473,42 +473,6 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token)
|
||||||
return BuiltinFunction_Equality(top_frame);
|
return BuiltinFunction_Equality(top_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
case TOKENTYPE_PIPE:
|
|
||||||
case TOKENTYPE_SEMICOLON:
|
|
||||||
{
|
|
||||||
// return from function body
|
|
||||||
if (StringView_Equal(top_frame->self_function->return_type, StringView_FromString("void"))) {
|
|
||||||
DynamicArray_Remove(&self->call_frames, frame_count - 1);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
CallFrame* parent_frame = DynamicArray_GetPointer(&self->call_frames, frame_count - 2);
|
|
||||||
Value return_value;
|
|
||||||
if (CallFrame_StackPop(top_frame, &return_value)) {
|
|
||||||
// TODO: Error message
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
char function_name[top_frame->self_function->name.length + 1];
|
|
||||||
memset(function_name, 0, sizeof(function_name));
|
|
||||||
StringView_Paste(function_name, top_frame->self_function->name);
|
|
||||||
|
|
||||||
if (! _are_types_compatible(return_value.type, top_frame->self_function->return_type)) {
|
|
||||||
// TODO: Error message
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CallFrame_Destroy(top_frame);
|
|
||||||
DynamicArray_Remove(&self->call_frames, frame_count - 1);
|
|
||||||
if (CallFrame_StackPush(parent_frame, &return_value)) {
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TOKENTYPE_LEFT_BRACE:
|
|
||||||
case TOKENTYPE_RIGHT_BRACE:
|
|
||||||
case TOKENTYPE_AMPERSAND:
|
|
||||||
case TOKENTYPE_PLUS:
|
case TOKENTYPE_PLUS:
|
||||||
{
|
{
|
||||||
BuiltinFunction_Plus(top_frame);
|
BuiltinFunction_Plus(top_frame);
|
||||||
|
@ -519,6 +483,12 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token)
|
||||||
BuiltinFunction_Minus(top_frame);
|
BuiltinFunction_Minus(top_frame);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TOKENTYPE_PIPE:
|
||||||
|
case TOKENTYPE_SEMICOLON:
|
||||||
|
case TOKENTYPE_LEFT_BRACE:
|
||||||
|
case TOKENTYPE_RIGHT_BRACE:
|
||||||
|
case TOKENTYPE_AMPERSAND:
|
||||||
case TOKENTYPE_MULTIPLY:
|
case TOKENTYPE_MULTIPLY:
|
||||||
case TOKENTYPE_DIVIDE:
|
case TOKENTYPE_DIVIDE:
|
||||||
case TOKENTYPE_ARROW:
|
case TOKENTYPE_ARROW:
|
||||||
|
@ -553,15 +523,33 @@ bool Value_IsTruthy(Value* v)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool CallFrame_IsExecutingCondition(CallFrame* frame)
|
||||||
|
{
|
||||||
|
return frame->instruction_pointer >= frame->alternative->condition_token_start
|
||||||
|
&& frame->instruction_pointer <= frame->alternative->condition_token_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CallFrame_IsSelectingCondition(CallFrame* frame)
|
||||||
|
{
|
||||||
|
return frame->instruction_pointer == frame->alternative->condition_token_end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CallFrame_IsExecutingBody(CallFrame* frame)
|
||||||
|
{
|
||||||
|
return frame->instruction_pointer < frame->alternative->body_token_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CallFrame_IsReturningBody(CallFrame* frame)
|
||||||
|
{
|
||||||
|
return frame->instruction_pointer == frame->alternative->body_token_end;
|
||||||
|
}
|
||||||
|
|
||||||
#define RPN(a,b,c) a c b
|
#define RPN(a,b,c) a c b
|
||||||
int Interpreter_RunFrame(Interpreter* self)
|
int Interpreter_RunFrame(Interpreter* self)
|
||||||
{
|
{
|
||||||
size_t frame_count = DynamicArray_GetLength(&self->call_frames);
|
size_t frame_count = DynamicArray_GetLength(&self->call_frames);
|
||||||
CallFrame* top_frame = DynamicArray_GetPointer(&self->call_frames, frame_count - 1);
|
CallFrame* top_frame = DynamicArray_GetPointer(&self->call_frames, frame_count - 1);
|
||||||
if (
|
if (CallFrame_IsExecutingCondition(top_frame)) {
|
||||||
top_frame->instruction_pointer >= top_frame->alternative->condition_token_start
|
|
||||||
&& top_frame->instruction_pointer <= top_frame->alternative->condition_token_end
|
|
||||||
) {
|
|
||||||
// alternative executing
|
// alternative executing
|
||||||
while (top_frame->instruction_pointer <= top_frame->alternative->condition_token_end) {
|
while (top_frame->instruction_pointer <= top_frame->alternative->condition_token_end) {
|
||||||
int execute_code = Interpreter_ExecuteNext(self, top_frame->alternative->condition_token_end);
|
int execute_code = Interpreter_ExecuteNext(self, top_frame->alternative->condition_token_end);
|
||||||
|
@ -573,7 +561,7 @@ int Interpreter_RunFrame(Interpreter* self)
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (top_frame->instruction_pointer == top_frame->alternative->condition_token_end + 1) {
|
} else if (CallFrame_IsSelectingCondition(top_frame)) {
|
||||||
// alternative evaluation done
|
// alternative evaluation done
|
||||||
Value alternative_success;
|
Value alternative_success;
|
||||||
if (CallFrame_StackPop(top_frame, &alternative_success) != EXIT_SUCCESS) {
|
if (CallFrame_StackPop(top_frame, &alternative_success) != EXIT_SUCCESS) {
|
||||||
|
@ -596,9 +584,9 @@ int Interpreter_RunFrame(Interpreter* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
} else {
|
} else if (CallFrame_IsExecutingBody(top_frame)) {
|
||||||
// function executing
|
// function executing
|
||||||
while (top_frame->instruction_pointer <= top_frame->alternative->body_token_end) {
|
do {
|
||||||
int execute_code = Interpreter_ExecuteNext(self, top_frame->alternative->body_token_end);
|
int execute_code = Interpreter_ExecuteNext(self, top_frame->alternative->body_token_end);
|
||||||
if (execute_code != EXIT_SUCCESS) {
|
if (execute_code != EXIT_SUCCESS) {
|
||||||
return execute_code;
|
return execute_code;
|
||||||
|
@ -607,7 +595,40 @@ int Interpreter_RunFrame(Interpreter* self)
|
||||||
if (RPN(frame_count, DynamicArray_GetLength(&self->call_frames), !=)) {
|
if (RPN(frame_count, DynamicArray_GetLength(&self->call_frames), !=)) {
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
} while (top_frame->instruction_pointer < top_frame->alternative->body_token_end);
|
||||||
|
} else if (CallFrame_IsReturningBody(top_frame)) {
|
||||||
|
// Function return
|
||||||
|
if (StringView_Equal(top_frame->self_function->return_type, StringView_FromString("void"))) {
|
||||||
|
CallFrame_Destroy(top_frame);
|
||||||
|
DynamicArray_Remove(&self->call_frames, frame_count - 1);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CallFrame* parent_frame = DynamicArray_GetPointer(&self->call_frames, frame_count - 2);
|
||||||
|
Value return_value;
|
||||||
|
if (CallFrame_StackPop(top_frame, &return_value)) {
|
||||||
|
// TODO: Error message
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// char function_name[top_frame->self_function->name.length + 1];
|
||||||
|
// memset(function_name, 0, sizeof(function_name));
|
||||||
|
// StringView_Paste(function_name, top_frame->self_function->name);
|
||||||
|
|
||||||
|
if (! _are_types_compatible(return_value.type, top_frame->self_function->return_type)) {
|
||||||
|
// TODO: Error message
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CallFrame_Destroy(top_frame);
|
||||||
|
DynamicArray_Remove(&self->call_frames, frame_count - 1);
|
||||||
|
if (CallFrame_StackPush(parent_frame, &return_value)) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Invalid instruction pointer
|
||||||
|
// TODO: Error message
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
Loading…
Reference in a new issue