feat: add syntax config constants

fix(VarStore): better hash function
This commit is contained in:
Matthieu Bessat 2022-05-17 10:27:32 +02:00
parent 19d6f6fd70
commit a66bfff424
9 changed files with 125 additions and 56 deletions

View file

@ -0,0 +1,8 @@
definir index comme 0
tant que index < 10 faire
print_number(index)
definir index comme index + 1
fin
print_number(index)

View file

@ -1,3 +0,0 @@
set a to input_number()
print_number(a)

View file

@ -10,13 +10,10 @@
#include <stdlib.h>
int main () {
float ex = 2.00001430511;
printf("as bin %d \n", (int) ex);
struct VariableStore* store = var_store_init();
printf("%d", var_store_hash_name(store, "print_number index"));
return 0;
// struct VariableStore* store = var_store_init();
// printf("%d", var_store_hash_name(store, "var"));
// return 0;
//struct List l1;
// short val = 17;

View file

@ -1,6 +1,47 @@
#ifndef G_CONFIG_H_
#define G_CONFIG_H_
#define PRESET_ENGLISH 0
#define PRESET_FRENCH 1
// 0: no logs; 1: medium debug; 2: full debug
#define G_DEBUG_LEVEL 0
#define SYNTAX_PRESET PRESET_ENGLISH
// Define your own custom syntax here
#if SYNTAX_PRESET == PRESET_ENGLISH
#define SYNTAX_END "end"
#define SYNTAX_SET_START "set"
#define SYNTAX_SET_STOP "to"
#define SYNTAX_IF_START "if"
#define SYNTAX_IF_STOP "then"
#define SYNTAX_WHILE_START "while"
#define SYNTAX_WHILE_STOP "do"
#define SYNTAX_CONTINUE "continue"
#define SYNTAX_BREAK "break"
#endif
#if SYNTAX_PRESET == PRESET_FRENCH
#define SYNTAX_END "fin"
#define SYNTAX_SET_START "definir"
#define SYNTAX_SET_STOP "comme"
#define SYNTAX_IF_START "si"
#define SYNTAX_IF_STOP "alors"
#define SYNTAX_WHILE_START "tant que"
#define SYNTAX_WHILE_STOP "faire"
#define SYNTAX_CONTINUE "continuer"
// JPP
#define SYNTAX_BREAK "casser"
#endif
#endif

View file

@ -471,15 +471,11 @@ int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsig
int startTrimOffset = 0;
int stopTrimOffset = 0;
for (int z = 0; z < len; z++) {
if (inputStr[startPos+z] != ' ') {
break;
}
if (inputStr[startPos+z] != ' ') break;
startTrimOffset++;
}
for (int z = 1; z < len; z++) {
if (inputStr[stopPos-z] != ' ') {
break;
}
if (inputStr[stopPos-z] != ' ') break;
stopTrimOffset++;
}
startPos += startTrimOffset;
@ -500,9 +496,7 @@ int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsig
char dumbValue = (char) 0;
if (buff[0] == '\0') {
continue;
}
if (buff[0] == '\0') continue;
if (len == 1 && buff[0] == '(') {
list_set(&evalList, evalList.num_elements, TYPE_OPEN_PARENTHESIS, &dumbValue);
continue;
@ -546,6 +540,7 @@ int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsig
if (EVALUATOR_DEBUG_LEVEL >= 2) var_store_print(state->varStore);
int varKey = (int) var_store_get_key(state->varStore, buff);
if (EVALUATOR_DEBUG_LEVEL >= 2) printf("got var key '%d' \n", varKey);
if (varKey == -1) {
// did not find the var name

View file

@ -1,3 +1,5 @@
#include "./config.h"
#include "./types.h"
#include "./utils.h"
#include "./line_processing.h"
#include "./stack.h"
@ -32,9 +34,7 @@ int recognize_comment_statement(char* lineStr)
mode = 2;
continue;
}
if (lineStr[i] != ' ') {
break;
}
if (lineStr[i] != ' ') break;
}
i++;
}
@ -76,8 +76,8 @@ int recognize_termination_keyword(char* needle, char* subject, int from)
// recognize "set VAR_NAME to EVALUATION"
int recognize_set_statement(char* lineStr, struct SetStatement* res)
{
static char setStatementStartKeyword[] = "set";
static char setStatementStopKeyword[] = "to";
static char setStatementStartKeyword[] = SYNTAX_SET_START;
static char setStatementStopKeyword[] = SYNTAX_SET_STOP;
int i = 0;
int mode = 1;
@ -155,8 +155,8 @@ int recognize_set_statement(char* lineStr, struct SetStatement* res)
// FIXME: allow for multiline if statement
int recognize_if_statement(char* lineStr, struct IfStatement* res)
{
static char ifStatementStartKeyword[] = "if";
static char ifStatementStopKeyword[] = "then";
static char ifStatementStartKeyword[] = SYNTAX_IF_START;
static char ifStatementStopKeyword[] = SYNTAX_IF_STOP;
size_t len = strlen(lineStr);
if (len < strlen(ifStatementStartKeyword) + 1 + strlen(ifStatementStopKeyword)) return 0;
@ -222,8 +222,8 @@ int recognize_if_statement(char* lineStr, struct IfStatement* res)
// recognize "while EXPRESSION then \n begin (...) \n end"
int recognize_while_statement(char* lineStr, struct WhileStatement* res)
{
static char whileStatementStartKeyword[] = "while";
static char whileStatementStopKeyword[] = "do";
static char whileStatementStartKeyword[] = SYNTAX_WHILE_START;
static char whileStatementStopKeyword[] = SYNTAX_WHILE_STOP;
size_t len = strlen(lineStr);
if (len < strlen(whileStatementStartKeyword) + 1 + strlen(whileStatementStopKeyword)) return 0;
@ -347,7 +347,7 @@ int process_line(struct StateContainer* state, char* str)
return 1;
}
if (recognize_word(str, "end")) {
if (recognize_word(str, SYNTAX_END)) {
byte lastBlockType;
int_stack_pop(state->blockStack, (int*) &lastBlockType); // FIXME: use a stack with size byte instead of int
if (!state->skipping && lastBlockType == BLOCK_WHILE) {
@ -425,10 +425,8 @@ int process_line(struct StateContainer* state, char* str)
int res;
byte resType;
int evalStat = evaluate(state, (char*) &dest, &res, &resType);
if (evalStat != 0) {
printf("Syntax error for line \"%s\"\n", str);
return 0;
}
if (evalStat != 0) return 0;
byte doFollow = convert_to_bool(resType, res);
if (LINE_PROCESSING_DEBUG_LEVEL >= 2) printf("Got %s, doFollow: %d \n", get_repr(resType, &res), doFollow);
@ -450,10 +448,10 @@ int process_line(struct StateContainer* state, char* str)
return 1;
}
if (recognize_word(str, "continue")) {
if (recognize_word(str, SYNTAX_CONTINUE)) {
int lastLoopLine;
if (!int_stack_pop(state->loopStack, &lastLoopLine)) {
printf("Syntax error: unexpected continue, not in a loop \n");
printf("Syntax error: unexpected continue, not in a loop.\n");
return 0;
}
state->linePtr = lastLoopLine;
@ -462,17 +460,18 @@ int process_line(struct StateContainer* state, char* str)
byte lastBlockType;
while (lastBlockType != BLOCK_WHILE) {
if (!int_stack_pop(state->blockStack, &lastBlockType)) {
printf("Syntax error: unexpected continue \n");
printf("Syntax error: unexpected continue.\n");
return 0;
}
}
int_stack_pop(state->blockStack, &lastBlockType);
return 1;
}
if (recognize_word(str, "break")) {
if (recognize_word(str, SYNTAX_BREAK)) {
int lastLoopLine;
if (!int_stack_pop(state->loopStack, &lastLoopLine)) {
printf("Syntax error: unexpected break, not in a loop \n");
printf("Syntax error: unexpected break, not in a loop.\n");
return 0;
}
@ -517,7 +516,7 @@ int process_line(struct StateContainer* state, char* str)
int evalStat = evaluate(state, (char*) &express, &res, &resType);
if (evalStat != 0) {
printf("Syntax error for line \"%s\"\n", str);
printf("Error: could not evaluate the expression associated with the content of the variable to set \"%s\".\n", str);
return 0;
}
@ -533,7 +532,7 @@ int process_line(struct StateContainer* state, char* str)
byte resType;
int evalStat = evaluate(state, str, &res, &resType);
if (evalStat != 0) {
printf("Syntax error for line \"%s\"\n", str);
printf("Error: could not evaluate expression \"%s\".\n", str);
return 0;
}
state->linePtr++;
@ -587,7 +586,7 @@ int process_script(struct StateContainer* state, char* script)
while (state->running && state->linePtr != lineCount) {
if (state->linePtr >= lineCount) {
printf("Invalid line %d \n", state->linePtr);
printf("Error: Invalid line %d \n.", state->linePtr);
break;
}
int lineLen = (lineEnds[state->linePtr] - lineStarts[state->linePtr]);
@ -596,7 +595,7 @@ int process_script(struct StateContainer* state, char* script)
int stat = process_line(state, line);
if (!stat) {
printf("Abnormal end of run at line %d: '%s' \n", state->linePtr, line);
printf("Error: Abnormal end of run at line %d: '%s'.\n", state->linePtr, line);
return 0;
}
}

View file

@ -4,7 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
#define MAX_INTEGER 47797852
#define MAX_INTEGER 2147483647-1
struct VariableStore* var_store_init()
{
@ -39,7 +39,8 @@ int var_store_hash_name(struct VariableStore* store, char* varName)
int hash = 0;
int i = 0;
while (varName[i] != '\0') {
hash += (get_int_rep_from_char(varName[i])*integer_pow(9, i)) % MAX_INTEGER;
int num = get_int_rep_from_char(varName[i])*integer_pow(9, i);
hash = abs(hash + abs(num));
i++;
}
// FIXME: when reallocating, we should copy all variables to their new key
@ -125,20 +126,17 @@ int var_store_get_key(struct VariableStore* store, char* varName)
int originalKey = var_store_hash_name(store, varName);
int key = originalKey;
// handle collision, walk along the array
while (1)
{
while (1) {
//printf("inter key: %d %d \n", key, store->container[key].type);
if (store->container[key].type == 0) {
return -1;
}
if (strcmp(store->container[key].namePtr, varName) == 0) {
// we found the position
return key;
}
if (store->container[key].type == 0) return -1;
// check if we found the position
if (strcmp(store->container[key].namePtr, varName) == 0) return key;
key = (key+1) % store->allocatedLength;
if (key == originalKey) {
return -1;
}
if (key == originalKey) return -1;
}
}

View file

@ -3,6 +3,7 @@
#ifndef VAR_STORE_H_
#define VAR_STORE_H_
#define VAR_STORE_DEBUG_LEVEL (G_DEBUG_LEVEL)
#define VAR_STORE_INITIAL_ALLOC_LENGTH 32
/**

View file

@ -21,6 +21,14 @@ void test_evaluation()
assert(resType == TYPE_INT);
assert(-4 == resVal);
evaluate(state, " - 6 ", &resVal, &resType);
assert(resType == TYPE_INT);
assert(-6 == resVal);
evaluate(state, " 1+ (- 45 ) ", &resVal, &resType);
assert(resType == TYPE_INT);
assert(-44 == resVal);
evaluate(state, "-(4+9)+1", &resVal, &resType);
assert(resType == TYPE_INT);
assert(-12 == resVal);
@ -53,6 +61,8 @@ void test_evaluation()
assert(resType == TYPE_FLOAT);
assert(float_almost_equal(-0.4, get_float_from_int_rep(resVal)));
/* FUNCTIONS */
evaluate(state, "sqrt(2)-1", &resVal, &resType);
assert(resType == TYPE_FLOAT);
assert(float_almost_equal(0.41421, get_float_from_int_rep(resVal)));
@ -89,11 +99,28 @@ void test_evaluation()
assert(resType == TYPE_INT);
assert(4 == resVal);
evaluate(state, "max(25, 4)", &resVal, &resType);
assert(resType == TYPE_INT);
assert(25 == resVal);
evaluate(state, "max(-25, 42)", &resVal, &resType);
assert(resType == TYPE_INT);
assert(42 == resVal);
evaluate(state, "max( (1+1)^(6+1-1) , 4+2)", &resVal, &resType);
assert(resType == TYPE_INT);
assert(64 == resVal);
evaluate(state, "max(floor(exp(1))^(4+1) , -2)", &resVal, &resType);
assert(resType == TYPE_INT);
assert(32 == resVal);
// testing function composition is important
evaluate(state, "abs(abs(-2))", &resVal, &resType);
assert(resType == TYPE_INT);
assert(2 == resVal);
/* COMPARAISON OPERATORS */
evaluate(state, "2 = 2", &resVal, &resType);
assert(resType == TYPE_INT);
assert(1 == resVal);
@ -154,6 +181,7 @@ void test_evaluation()
assert(resType == TYPE_FLOAT);
assert(float_almost_equal(5.3, get_float_from_int_rep(resVal)));
/* VARIABLES */
int ex = 43;
var_store_set(state->varStore, "var", TYPE_INT, (void*) &ex);
evaluate(state, "var", &resVal, &resType);
@ -176,6 +204,7 @@ void test_evaluation()
printf("actually got: %d \n", resVal);
assert(7 == resVal);
/* TYPE FUNCS */
evaluate(state, "is_number(123)", &resVal, &resType);
assert(resType == TYPE_INT);
assert(resVal);
@ -191,4 +220,8 @@ void test_evaluation()
evaluate(state, "is_null(NULL)", &resVal, &resType);
assert(resType == TYPE_INT);
assert(resVal);
evaluate(state, "(is_null(NULL) & is_number(42)) | 0", &resVal, &resType);
assert(resType == TYPE_INT);
assert(resVal);
}