adding all the code
This commit is contained in:
parent
a804513a50
commit
017af25717
32 changed files with 1003 additions and 0 deletions
36
Makefile
Normal file
36
Makefile
Normal file
|
@ -0,0 +1,36 @@
|
|||
CC = gcc
|
||||
CFLAGS = -Wall -pedantic -Werror=format-security -Werror=implicit-function-declaration -D_FORTIFY_SOURCE=2 \
|
||||
-O2 -pipe -Wl,-z,defs -Wl,-z,now, -Wl,-z,relro
|
||||
TARGET = main
|
||||
OBJS = $(TARGET).o logic.o pile.o lexer.o exec.o command.o num.o pileInt.o state.o stackops.o calcop.o \
|
||||
cmpop.o functions.o show.o
|
||||
LDFLAGS = -Wall
|
||||
|
||||
default: $(TARGET)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
clean:
|
||||
rm *.o $(TARGET)
|
||||
|
||||
test: $(TARGET)
|
||||
./test.sh
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(OBJS) -o $@ $(LDFLAGS)
|
||||
|
||||
logic.o: logic.h state.h pileInt.h
|
||||
pile.o: pile.h num.h
|
||||
lexer.o: lexer.h
|
||||
exec.o: exec.h state.h command.h pile.h functions.h
|
||||
command.o: command.h state.h functions.h calcop.h cmpop.h stackops.h show.h logic.h
|
||||
state.o: state.h definitions.h pile.h lexer.h
|
||||
num.o: num.h
|
||||
show.o: show.h state.h
|
||||
pileInt.o: pileInt.h definitions.h
|
||||
calcop.o: calcop.h pile.h state.h num.h
|
||||
stackops.o: stackops.h state.h
|
||||
cmpop.o: cmpop.h state.h num.h pile.h
|
||||
functions.o: functions.h definitions.h state.h pileInt.h
|
||||
|
||||
.PHONY: default all clean test
|
78
calcop.c
Normal file
78
calcop.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "calcop.h"
|
||||
|
||||
#include "num.h"
|
||||
#include "pile.h"
|
||||
|
||||
int addi(int i, int j) {
|
||||
return i + j;
|
||||
}
|
||||
float addf(float i, float j) {
|
||||
return i + j;
|
||||
}
|
||||
int subi(int i, int j) {
|
||||
return i - j;
|
||||
}
|
||||
float subf(float i, float j) {
|
||||
return i - j;
|
||||
}
|
||||
int multi(int i, int j) {
|
||||
return i * j;
|
||||
}
|
||||
float multf(float i, float j) {
|
||||
return i * j;
|
||||
}
|
||||
int divi(int i, int j) {
|
||||
return i/j;
|
||||
}
|
||||
float divf(float i, float j) {
|
||||
return i/j;
|
||||
}
|
||||
|
||||
void calcop( int (*opint)(int,int), float (*opfloat)(float,float), struct Pile* pile ) {
|
||||
struct NumContainer res;
|
||||
struct NumContainer num1;
|
||||
struct NumContainer num2;
|
||||
getlastnums(&num1, &num2, pile);
|
||||
|
||||
if ( num1.t == INT ) {
|
||||
if ( num2.t == INT ) {
|
||||
res.t = INT;
|
||||
res.n.vali = opint( num1.n.vali, num2.n.vali );
|
||||
} else {
|
||||
res.t = FLOAT;
|
||||
res.n.valf = opfloat((float)num1.n.vali, num2.n.valf);
|
||||
}
|
||||
} else {
|
||||
res.t = FLOAT;
|
||||
if ( num2.t == INT ) {
|
||||
res.n.valf = opfloat(num1.n.valf, (float)num2.n.vali);
|
||||
} else {
|
||||
res.n.valf = opfloat(num1.n.valf, num2.n.valf);
|
||||
}
|
||||
}
|
||||
push(pile, res);
|
||||
}
|
||||
|
||||
void add(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
calcop(addi, addf, &(state->pile));
|
||||
}
|
||||
}
|
||||
|
||||
void sub(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
calcop(subi, subf, &(state->pile));
|
||||
}
|
||||
}
|
||||
|
||||
void mult(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
calcop(multi, multf, &(state->pile));
|
||||
}
|
||||
}
|
||||
|
||||
void divide(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
calcop(divi, divf, &(state->pile));
|
||||
}
|
||||
}
|
11
calcop.h
Normal file
11
calcop.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef CALCOP_H_
|
||||
#define CALCOP_H_
|
||||
|
||||
#include "state.h"
|
||||
|
||||
void add(struct State* state);
|
||||
void sub(struct State* state);
|
||||
void mult(struct State* state);
|
||||
void divide(struct State* state);
|
||||
|
||||
#endif // CALCOP_H_
|
93
cmpop.c
Normal file
93
cmpop.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include "cmpop.h"
|
||||
|
||||
#include "num.h"
|
||||
#include "pile.h"
|
||||
|
||||
|
||||
int equali(int i, int j) {
|
||||
if ( i == j ) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int equalf(float i, float j) {
|
||||
if ( i == j ) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int lessThani(int i, int j) {
|
||||
if ( i < j ) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int lessThanf(float i, float j) {
|
||||
if ( i < j ) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int greaterThani(int i, int j) {
|
||||
if ( i > j ) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int greaterThanf(float i, float j) {
|
||||
if ( i > j ) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cmpop( int (*opint)(int,int), int (*opfloat)(float,float), struct Pile* pile ) {
|
||||
struct NumContainer res;
|
||||
struct NumContainer num1;
|
||||
struct NumContainer num2;
|
||||
getlastnums(&num1, &num2, pile);
|
||||
push(pile, num1);
|
||||
|
||||
|
||||
/* getlastnums(&num1, &num2, pile); */
|
||||
|
||||
res.t = INT;
|
||||
if ( num1.t == INT ) {
|
||||
if ( num2.t == INT ) {
|
||||
res.n.vali = opint( num1.n.vali, num2.n.vali );
|
||||
} else {
|
||||
res.n.valf = opfloat((float)num1.n.vali, num2.n.valf);
|
||||
}
|
||||
} else {
|
||||
if ( num2.t == INT ) {
|
||||
res.n.valf = opfloat(num1.n.valf, (float)num2.n.vali);
|
||||
} else {
|
||||
res.n.valf = opfloat(num1.n.valf, num2.n.valf);
|
||||
}
|
||||
}
|
||||
push(pile, res);
|
||||
}
|
||||
|
||||
void equal(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
cmpop(equali, equalf, &state->pile);
|
||||
}
|
||||
}
|
||||
|
||||
void less(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
cmpop(lessThani, lessThanf, &state->pile);
|
||||
}
|
||||
}
|
||||
|
||||
void greater(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
cmpop(greaterThani, greaterThanf, &state->pile);
|
||||
}
|
||||
}
|
10
cmpop.h
Normal file
10
cmpop.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef CMPOP_H_
|
||||
#define CMPOP_H_
|
||||
|
||||
#include "state.h"
|
||||
|
||||
void equal(struct State* state);
|
||||
void less(struct State* state);
|
||||
void greater(struct State* state);
|
||||
|
||||
#endif // CMPOP_H_
|
70
command.c
Normal file
70
command.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "command.h"
|
||||
|
||||
#include "functions.h"
|
||||
#include "calcop.h"
|
||||
#include "cmpop.h"
|
||||
#include "stackops.h"
|
||||
#include "show.h"
|
||||
#include "logic.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void initCmds( struct CmdList** cmds ) {
|
||||
initLogic();
|
||||
initFunctions();
|
||||
prependCmd(cmds, "DROP", dropCmd);
|
||||
prependCmd(cmds, "DUP", dupCmd);
|
||||
prependCmd(cmds, "SWAP", swapCmd);
|
||||
prependCmd(cmds, "ROT", rotCmd);
|
||||
prependCmd(cmds, "CR", crCmd);
|
||||
prependCmd(cmds, "IF", ifCmd);
|
||||
prependCmd(cmds, "ELSE", elseCmd);
|
||||
prependCmd(cmds, "THEN", thenCmd);
|
||||
prependCmd(cmds, "BEGIN", beginCmd);
|
||||
prependCmd(cmds, "UNTIL", untilCmd);
|
||||
prependCmd(cmds, ":", colonCmd);
|
||||
prependCmd(cmds, ";", semicolonCmd);
|
||||
prependCmd(cmds, "+", add);
|
||||
prependCmd(cmds, "-", sub);
|
||||
prependCmd(cmds, "*", mult);
|
||||
prependCmd(cmds, "/", divide);
|
||||
prependCmd(cmds, "=", equal);
|
||||
prependCmd(cmds, "<", less);
|
||||
prependCmd(cmds, ">", greater);
|
||||
prependCmd(cmds, ".", point);
|
||||
prependCmd(cmds, ".S", pointS);
|
||||
prependCmd(cmds, ".\"", pointQuote);
|
||||
}
|
||||
|
||||
void prependCmd( struct CmdList** cmds, char* cmdName, void (*func)(struct State*) ) {
|
||||
struct CmdList* aux = *cmds;
|
||||
*cmds = (struct CmdList*)malloc(sizeof(struct CmdList));
|
||||
(*cmds)->next = aux;
|
||||
(*cmds)->func = func;
|
||||
strncpy((*cmds)->cmdName, cmdName, MAX_CMD_NAME_LENGTH);
|
||||
(*cmds)->cmdName[MAX_CMD_NAME_LENGTH-1] = '\0';
|
||||
}
|
||||
|
||||
void endCmds( struct CmdList** pcmds ) {
|
||||
struct CmdList* cmds = *pcmds;
|
||||
struct CmdList* aux;
|
||||
while (cmds != NULL) {
|
||||
aux = cmds;
|
||||
cmds = cmds->next;
|
||||
free(aux);
|
||||
}
|
||||
*pcmds = NULL;
|
||||
}
|
||||
|
||||
int tryCallCmds( struct CmdList* cmds, char* s, struct State* state ) {
|
||||
while (cmds != NULL) {
|
||||
if ( !strcmp(cmds->cmdName, s) ) {
|
||||
cmds->func(state);
|
||||
return 1;
|
||||
}
|
||||
cmds = cmds->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
17
command.h
Normal file
17
command.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef COMMAND_H_
|
||||
#define COMMAND_H_
|
||||
|
||||
#include "state.h"
|
||||
|
||||
struct CmdList {
|
||||
struct CmdList* next;
|
||||
char cmdName[MAX_CMD_NAME_LENGTH];
|
||||
void (*func)(struct State*);
|
||||
};
|
||||
|
||||
void initCmds( struct CmdList** cmds );
|
||||
void prependCmd( struct CmdList** cmds, char* s, void (*func)(struct State*) );
|
||||
void endCmds( struct CmdList** cmds );
|
||||
int tryCallCmds( struct CmdList* cmds, char* s, struct State* state );
|
||||
|
||||
#endif // COMMAND_H_
|
9
definitions.h
Normal file
9
definitions.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef DEFINITIONS_H_
|
||||
#define DEFINITIONS_H_
|
||||
|
||||
typedef unsigned int programPointer;
|
||||
#define MAX_CMD_NAME_LENGTH 6
|
||||
|
||||
struct FunctionsList;
|
||||
|
||||
#endif // DEFINITIONS_H_
|
38
exec.c
Normal file
38
exec.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include "exec.h"
|
||||
|
||||
#include "pile.h"
|
||||
#include "functions.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void execute(struct State *state, struct CmdList* cmds) {
|
||||
struct NumContainer num1;
|
||||
char* instruction;
|
||||
while (state->instructionPointer < (programPointer) state->prog->taille) {
|
||||
instruction = getCurrentToken(state);
|
||||
if (state->mode == EXECUTE) {
|
||||
if ( isdigit(instruction[0]) ) {
|
||||
num1 = readNum(instruction);
|
||||
push(&(state->pile), num1);
|
||||
} else if ( !tryCallCmds( cmds, instruction, state ) ) {
|
||||
if (!tryCallFunctions(instruction, state)) {
|
||||
fprintf(stderr, "%s is not a known symbol\n", instruction);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else if (state->mode == PRINT){
|
||||
if (!strncmp(instruction, "\"", 2)) {
|
||||
state->mode = EXECUTE;
|
||||
} else {
|
||||
printf("%s ", instruction);
|
||||
}
|
||||
} else {
|
||||
tryCallCmds(cmds, instruction, state);
|
||||
}
|
||||
++(state->instructionPointer);
|
||||
}
|
||||
}
|
9
exec.h
Normal file
9
exec.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef EXEC_H_
|
||||
#define EXEC_H_
|
||||
|
||||
#include "state.h"
|
||||
#include "command.h"
|
||||
|
||||
void execute(struct State* state, struct CmdList* cmds);
|
||||
|
||||
#endif // EXEC_H_
|
76
functions.c
Normal file
76
functions.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
#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);
|
||||
}
|
||||
}
|
13
functions.h
Normal file
13
functions.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef FUNCTIONS_H_
|
||||
#define FUNCTIONS_H_
|
||||
|
||||
#include "state.h"
|
||||
|
||||
|
||||
void initFunctions();
|
||||
int tryCallFunctions(char* func, struct State* state);
|
||||
void colonCmd(struct State* state);
|
||||
void semicolonCmd(struct State* state);
|
||||
|
||||
|
||||
#endif // FUNCTIONS_H_
|
33
lexer.c
Normal file
33
lexer.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "lexer.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int numberOfDelimiters(char* string) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < (int)strlen(string); ++i) {
|
||||
if (string[i] == ' ') {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
struct Programm* lexer(char* chaine) {
|
||||
char *token, *str;
|
||||
str = strdup(chaine);
|
||||
int i = 0;
|
||||
int arraysize = numberOfDelimiters(str) + 1;
|
||||
char** programme = (char**)malloc(sizeof(char*)*arraysize);
|
||||
|
||||
while ((token = strsep(&str, " "))) {
|
||||
programme[i] = token;
|
||||
++i;
|
||||
}
|
||||
|
||||
struct Programm* res = (struct Programm*) malloc(sizeof(struct Programm));
|
||||
res->tokens = programme;
|
||||
res->taille = i;
|
||||
return res;
|
||||
}
|
11
lexer.h
Normal file
11
lexer.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef LEXER_H_
|
||||
#define LEXER_H_
|
||||
|
||||
struct Programm {
|
||||
char** tokens;
|
||||
int taille;
|
||||
};
|
||||
|
||||
struct Programm* lexer(char* chaine);
|
||||
|
||||
#endif // LEXER_H_
|
58
logic.c
Normal file
58
logic.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "logic.h"
|
||||
|
||||
#include "pileInt.h"
|
||||
|
||||
static struct PileInt loops;
|
||||
|
||||
void initLogic() {
|
||||
initPileI(&loops);
|
||||
}
|
||||
|
||||
void ifCmd(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
struct NumContainer cond;
|
||||
cond = top(&state->pile);
|
||||
pop(&state->pile);
|
||||
if (cond.t == INT && cond.n.vali == 0) {
|
||||
state->mode = IGNORE;
|
||||
} else if (cond.t == FLOAT && cond.n.valf == 0.0 ) {
|
||||
state->mode = IGNORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void elseCmd(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
state->mode = WAIT_FOR_ENDIF;
|
||||
} else if (state->mode == IGNORE) {
|
||||
state->mode = EXECUTE;
|
||||
}
|
||||
}
|
||||
|
||||
void thenCmd(struct State* state) {
|
||||
if (state->mode == IGNORE || state->mode == WAIT_FOR_ENDIF) {
|
||||
state->mode = EXECUTE;
|
||||
}
|
||||
}
|
||||
|
||||
void beginCmd(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
if (evalasBool(top(&state->pile))) {
|
||||
pushPileI(&loops, state->instructionPointer);
|
||||
} else {
|
||||
state->mode = WAIT_FOR_UNTIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void untilCmd(struct State* state) {
|
||||
if (state->mode == WAIT_FOR_UNTIL) {
|
||||
state->mode = EXECUTE;
|
||||
} else if (state->mode == EXECUTE) {
|
||||
if (evalasBool(top(&state->pile))) {
|
||||
state->instructionPointer = topPileI(&loops);
|
||||
} else {
|
||||
popPileI(&loops);
|
||||
}
|
||||
}
|
||||
}
|
15
logic.h
Normal file
15
logic.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef LOGIC_H_
|
||||
#define LOGIC_H_
|
||||
|
||||
#include "state.h"
|
||||
|
||||
void initLogic();
|
||||
void ifCmd(struct State* state);
|
||||
void elseCmd(struct State* state);
|
||||
void thenCmd(struct State* state);
|
||||
void beginCmd(struct State* state);
|
||||
void untilCmd(struct State* state);
|
||||
|
||||
|
||||
|
||||
#endif // LOGIC_H_
|
18
main.c
Normal file
18
main.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include "main.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
struct State state;
|
||||
struct CmdList* cmds;
|
||||
if ( argc != 2 ) {
|
||||
fprintf(stderr, "Usage: ./main 'instructions'\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
initCmds(&cmds);
|
||||
state.prog = lexer(argv[1]);
|
||||
state.instructionPointer = 0;
|
||||
init(&(state.pile));
|
||||
state.mode = EXECUTE;
|
||||
execute(&state, cmds);
|
||||
endCmds(&cmds);
|
||||
}
|
15
main.h
Normal file
15
main.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef MAIN_H_
|
||||
#define MAIN_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "pile.h"
|
||||
#include "lexer.h"
|
||||
#include "exec.h"
|
||||
|
||||
|
||||
|
||||
#endif // MAIN_H_
|
62
num.c
Normal file
62
num.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
#include "num.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
void printLnNum( struct NumContainer num ) {
|
||||
if ( num.t == INT ) {
|
||||
printf("%d\n", num.n.vali);
|
||||
} else {
|
||||
printf("%f\n", num.n.valf);
|
||||
}
|
||||
}
|
||||
|
||||
void printNum( struct NumContainer num ) {
|
||||
if ( num.t == INT ) {
|
||||
printf("%d ", num.n.vali);
|
||||
} else {
|
||||
printf("%f ", num.n.valf);
|
||||
}
|
||||
}
|
||||
|
||||
char evalasBool( struct NumContainer num ) {
|
||||
if (num.t == INT) {
|
||||
if (num.n.vali == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (num.n.valf == 0.0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct NumContainer readNum(char* s) {
|
||||
char* original = s;
|
||||
int is_int = 1;
|
||||
struct NumContainer res;
|
||||
while (*s != '\0') {
|
||||
if ( !isdigit(*s) ) {
|
||||
if ( *s == '.' && is_int ) {
|
||||
is_int = 0;
|
||||
} else {
|
||||
fprintf(stderr, "'%s' is not a number", original);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
++s;
|
||||
}
|
||||
if (is_int) {
|
||||
res.t = INT;
|
||||
res.n.vali = atoi(original);
|
||||
} else {
|
||||
res.t = FLOAT;
|
||||
res.n.valf = atof(original);
|
||||
}
|
||||
return res;
|
||||
}
|
22
num.h
Normal file
22
num.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef NUM_H_
|
||||
#define NUM_H_
|
||||
|
||||
enum NUMTYPE { INT, FLOAT };
|
||||
|
||||
union Num {
|
||||
int vali;
|
||||
float valf;
|
||||
};
|
||||
|
||||
struct NumContainer {
|
||||
enum NUMTYPE t;
|
||||
union Num n;
|
||||
};
|
||||
|
||||
void printNum( struct NumContainer num );
|
||||
void printLnNum( struct NumContainer num );
|
||||
char evalasBool( struct NumContainer num );
|
||||
struct NumContainer readNum(char* s);
|
||||
|
||||
|
||||
#endif // NUM_H_
|
66
pile.c
Normal file
66
pile.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include "pile.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void init( struct Pile* p ) {
|
||||
p->height = 0;
|
||||
p->l = NULL;
|
||||
}
|
||||
|
||||
void push( struct Pile* p, struct NumContainer i ) {
|
||||
struct List* aux = p->l;
|
||||
|
||||
p->l = (struct List*)malloc(sizeof(struct List));
|
||||
if (p->l == NULL) {
|
||||
fprintf(stderr, "Error: Could not allocate memory for the next cell on the stack\n");
|
||||
return;
|
||||
}
|
||||
|
||||
p->l->next = aux;
|
||||
p->l->i = i;
|
||||
++(p->height);
|
||||
}
|
||||
|
||||
struct NumContainer top( struct Pile* p ) {
|
||||
if ( p->height == 0 ) {
|
||||
fprintf(stderr, "Error: The stack has no element, cannot find top\n");
|
||||
exit(1);
|
||||
}
|
||||
return p->l->i;
|
||||
}
|
||||
|
||||
void print( struct Pile* p ) {
|
||||
struct List* aux = p->l;
|
||||
|
||||
while (aux != NULL) {
|
||||
printNum(aux->i);
|
||||
printf(" ");
|
||||
aux = aux->next;
|
||||
}
|
||||
/* printf("NULL"); */
|
||||
}
|
||||
|
||||
void pop( struct Pile* p ) {
|
||||
struct List* aux;
|
||||
|
||||
if ( p->height != 0 ) {
|
||||
--(p->height);
|
||||
aux = p->l;
|
||||
p->l = p->l->next;
|
||||
free(aux);
|
||||
}
|
||||
}
|
||||
|
||||
void end( struct Pile* p ) {
|
||||
while (p->height != 0) {
|
||||
pop(p);
|
||||
}
|
||||
}
|
||||
|
||||
void getlastnums( struct NumContainer* i, struct NumContainer* j, struct Pile* pile ) {
|
||||
*j = top(pile);
|
||||
pop(pile);
|
||||
*i = top(pile);
|
||||
pop(pile);
|
||||
}
|
27
pile.h
Normal file
27
pile.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef PILE_H_
|
||||
#define PILE_H_
|
||||
|
||||
#include "num.h"
|
||||
|
||||
struct List {
|
||||
struct NumContainer i;
|
||||
struct List* next;
|
||||
};
|
||||
|
||||
struct Pile {
|
||||
struct List* l;
|
||||
unsigned int height;
|
||||
};
|
||||
|
||||
void init( struct Pile* p );
|
||||
void push( struct Pile* p, struct NumContainer i );
|
||||
struct NumContainer top( struct Pile* p );
|
||||
void print( struct Pile* p );
|
||||
void pop( struct Pile* p );
|
||||
void end( struct Pile* p );
|
||||
void getlastnums( struct NumContainer* i, struct NumContainer* j, struct Pile* pile);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // PILE_H_
|
49
pileInt.c
Normal file
49
pileInt.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "pileInt.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void initPileI( struct PileInt* p ) {
|
||||
p->height = 0;
|
||||
p->l = NULL;
|
||||
}
|
||||
|
||||
void pushPileI( struct PileInt* p, programPointer i ) {
|
||||
struct ListInt* aux = p->l;
|
||||
|
||||
p->l = (struct ListInt*)malloc(sizeof(struct ListInt));
|
||||
if (p->l == NULL) {
|
||||
fprintf(stderr, "Error: Could not allocate memory for the next cell on the stack");
|
||||
return;
|
||||
}
|
||||
|
||||
p->l->next = aux;
|
||||
p->l->i = i;
|
||||
++(p->height);
|
||||
}
|
||||
|
||||
int topPileI( struct PileInt* p ) {
|
||||
if ( p->height == 0 ) {
|
||||
fprintf(stderr, "Error: The stack has no element, cannot find top");
|
||||
exit(1);
|
||||
}
|
||||
return p->l->i;
|
||||
}
|
||||
|
||||
void popPileI( struct PileInt* p ) {
|
||||
struct ListInt* aux;
|
||||
|
||||
if ( p->height != 0 ) {
|
||||
--(p->height);
|
||||
aux = p->l;
|
||||
p->l = p->l->next;
|
||||
free(aux);
|
||||
}
|
||||
}
|
||||
|
||||
void endPileI( struct PileInt* p ) {
|
||||
while (p->height != 0) {
|
||||
popPileI(p);
|
||||
}
|
||||
}
|
||||
|
25
pileInt.h
Normal file
25
pileInt.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef PILE_INT_H_
|
||||
#define PILE_INT_H_
|
||||
|
||||
#include "definitions.h"
|
||||
|
||||
struct ListInt {
|
||||
programPointer i;
|
||||
struct ListInt* next;
|
||||
};
|
||||
|
||||
struct PileInt {
|
||||
struct ListInt* l;
|
||||
unsigned int height;
|
||||
};
|
||||
|
||||
void initPileI( struct PileInt* p );
|
||||
void pushPileI( struct PileInt* p, programPointer i );
|
||||
int topPileI( struct PileInt* p );
|
||||
void popPileI( struct PileInt* p );
|
||||
void endPileI( struct PileInt* p );
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // PILE_H_
|
1
prog.forth
Normal file
1
prog.forth
Normal file
|
@ -0,0 +1 @@
|
|||
3 87 +
|
29
show.c
Normal file
29
show.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include "show.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void point(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
struct NumContainer num = top(&state->pile);
|
||||
pop(&state->pile);
|
||||
printNum(num);
|
||||
}
|
||||
}
|
||||
|
||||
void pointS(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
print(&state->pile);
|
||||
}
|
||||
}
|
||||
|
||||
void pointQuote(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
state->mode = PRINT;
|
||||
}
|
||||
}
|
||||
|
||||
void crCmd(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
12
show.h
Normal file
12
show.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef SHOW_H_
|
||||
#define SHOW_H_
|
||||
|
||||
#include "state.h"
|
||||
|
||||
void point(struct State* state);
|
||||
void pointS(struct State* state);
|
||||
void pointQuote(struct State* state);
|
||||
void crCmd(struct State* state);
|
||||
|
||||
|
||||
#endif // SHOW_H_
|
39
stackops.c
Normal file
39
stackops.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include "stackops.h"
|
||||
|
||||
void dropCmd(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
pop(&(state->pile));
|
||||
}
|
||||
}
|
||||
|
||||
void dupCmd(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
push(&(state->pile), top(&(state->pile)));
|
||||
}
|
||||
}
|
||||
|
||||
void swapCmd(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
struct NumContainer num1;
|
||||
struct NumContainer num2;
|
||||
|
||||
getlastnums(&num1, &num2, &(state->pile));
|
||||
push(&(state->pile), num2);
|
||||
push(&(state->pile), num1);
|
||||
}
|
||||
}
|
||||
|
||||
void rotCmd(struct State* state) {
|
||||
if (state->mode == EXECUTE) {
|
||||
struct NumContainer num1;
|
||||
struct NumContainer num2;
|
||||
struct NumContainer num3;
|
||||
|
||||
getlastnums(&num1, &num2, &(state->pile));
|
||||
num3 = top(&(state->pile));
|
||||
pop(&(state->pile));
|
||||
push(&(state->pile), num2);
|
||||
push(&(state->pile), num1);
|
||||
push(&(state->pile), num3);
|
||||
}
|
||||
}
|
11
stackops.h
Normal file
11
stackops.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef STACKOPS_H_
|
||||
#define STACKOPS_H_
|
||||
|
||||
#include "state.h"
|
||||
|
||||
void dropCmd(struct State* state);
|
||||
void dupCmd(struct State* state);
|
||||
void swapCmd(struct State* state);
|
||||
void rotCmd(struct State* state);
|
||||
|
||||
#endif // STACKOPS_H_
|
5
state.c
Normal file
5
state.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "state.h"
|
||||
|
||||
char* getCurrentToken(struct State* state) {
|
||||
return state->prog->tokens[state->instructionPointer];
|
||||
}
|
21
state.h
Normal file
21
state.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef STATE_H_
|
||||
#define STATE_H_
|
||||
|
||||
#include "pile.h"
|
||||
#include "lexer.h"
|
||||
#include "definitions.h"
|
||||
|
||||
enum MODE {EXECUTE, PRINT, IGNORE, WAIT_FOR_ENDIF, WAIT_FOR_UNTIL, WAIT_FOR_SEMICOLON};
|
||||
|
||||
struct State {
|
||||
struct Pile pile;
|
||||
struct Programm* prog;
|
||||
enum MODE mode;
|
||||
programPointer instructionPointer;
|
||||
struct FunctionsList* functions;
|
||||
};
|
||||
|
||||
char* getCurrentToken(struct State* state);
|
||||
|
||||
|
||||
#endif // STATE_H_
|
24
test.sh
Executable file
24
test.sh
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
./main '3 5 + . CR'
|
||||
./main '3 5 + 4 2 - .S CR'
|
||||
./main '3 5 + 4 2 - * . CR'
|
||||
./main '1 +'
|
||||
./main '1 2 + DUP * . CR'
|
||||
./main '1 2 DROP . CR'
|
||||
./main '2 3 SWAP - . CR'
|
||||
./main '3 2 1 ROT .S CR'
|
||||
./main '." Bonjour tout le monde " CR'
|
||||
./main '." hello world 3 DUP pouet " CR'
|
||||
./main '1 2 . . CR'
|
||||
./main '1 2 3 .S CR DROP .S CR DROP .S CR'
|
||||
./main '." le carré de trois est " 3 DUP * . CR'
|
||||
./main '19 DUP 18 < IF ." mineur " ELSE 18 = IF ." 18 ans " ELSE ." majeur " THEN THEN CR'
|
||||
./main '12 DUP 18 < IF ." mineur " ELSE 18 = IF ." 18 ans " ELSE ." majeur " THEN THEN CR'
|
||||
./main '18 DUP 18 < IF ." mineur " ELSE 18 = IF ." 18 ans " ELSE ." majeur " THEN THEN CR'
|
||||
./main '10 DUP BEGIN SWAP DUP BEGIN ." * " 1 - UNTIL DROP CR SWAP 1 - UNTIL'
|
||||
./main ': CARRE DUP * ; : CUBE DUP CARRE * ; ." Le cube de 5 est " 5 CUBE . CR'
|
||||
./main ': MAJEUR DUP 18 < IF ." mineur " ELSE 18 = IF ." 18 ans " ELSE ." majeur " THEN THEN ; 2 MAJEUR CR'
|
||||
./main ': ETOILE ." * " ; : LIGNE DUP BEGIN ETOILE 1 - UNTIL DROP ; : TRIANGLE BEGIN LIGNE 1 - CR UNTIL ; 10 TRIANGLE'
|
||||
set +x
|
Loading…
Reference in a new issue