C_TP_Forth/functions.c
2022-12-08 06:11:40 +01:00

76 lines
2.1 KiB
C

#include "functions.h"
#include "definitions.h"
#include "pileInt.h"
#include <stdlib.h>
#include <string.h>
static struct PileInt callStack;
struct FunctionsList {
struct FunctionsList* next;
char* functionName;
programPointer instructionPointer;
};
void initFunctions() {
initPileI(&callStack);
}
void prependFunction(struct State* state) {
int functionNameLength;
struct FunctionsList* aux = state->functions;
state->functions = (struct FunctionsList*) malloc(sizeof(struct FunctionsList));
state->functions->next = aux;
++(state->instructionPointer);
functionNameLength = strlen(getCurrentToken(state)) + 1; // counting the '\0'
state->functions->functionName = (char*)malloc(sizeof(char)*functionNameLength);
strncpy(state->functions->functionName, getCurrentToken(state), functionNameLength);
state->functions->instructionPointer = state->instructionPointer;
state->mode = WAIT_FOR_SEMICOLON;
}
void endFunctions(struct FunctionsList** pfunctions) {
struct FunctionsList* functions = *pfunctions;
struct FunctionsList* aux;
while (functions != NULL) {
aux = functions;
functions = functions->next;
free(aux->functionName);
free(aux);
}
*pfunctions = NULL;
}
int tryCallFunctions(char* func, struct State* state) {
struct FunctionsList* aux = state->functions;
while (aux != NULL) {
if (!strcmp(aux->functionName, func)) {
pushPileI(&callStack, state->instructionPointer);
state->instructionPointer = aux->instructionPointer;
return 1;
}
aux = aux->next;
}
return 0;
}
void returnFromFunction(struct State* state) {
state->instructionPointer = topPileI(&callStack);
popPileI(&callStack);
}
void colonCmd(struct State* state) {
if (state->mode == EXECUTE) {
prependFunction(state);
}
}
void semicolonCmd(struct State* state) {
if (state->mode == WAIT_FOR_SEMICOLON) {
state->mode = EXECUTE;
} else if (state->mode == EXECUTE) {
returnFromFunction(state);
}
}