76 lines
2.1 KiB
C
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);
|
|
}
|
|
}
|