diff --git a/README.md b/README.md index b078218..8a2ef8c 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ ToDo List: - [ ] add inclusive operators like '!=', '>=', '<=' - [ ] add input_number() std function - [ ] add type() std function +- [ ] add ceil() and floor() std functions - [X] base of the CLI - [ ] evaluate expression from stdin - [X] read a file diff --git a/examples/fibo.ltor b/examples/fibo.ltor index 489a5a3..20419da 100644 --- a/examples/fibo.ltor +++ b/examples/fibo.ltor @@ -1,9 +1,13 @@ -set a to 1 +# print the 20 first fibonacci numbers +set n to 20 +set a to 0 set b to 1 +print_number(a) set i to 0 -while i < 10 do - set c to a +while i < (n-1) do + set _a to a set a to a+b - set b to c - print_number a + set b to _a + print_number(a) + set i to i+1 end diff --git a/examples/hello_world.ltor b/examples/hello_world.ltor new file mode 100644 index 0000000..8f8e85e --- /dev/null +++ b/examples/hello_world.ltor @@ -0,0 +1,15 @@ +# print hello world using asci value (not very practical) +print_ascii(72) +print_ascii(101) +print_ascii(108) +print_ascii(108) +print_ascii(111) +print_ascii(44) +print_ascii(32) +print_ascii(119) +print_ascii(111) +print_ascii(114) +print_ascii(108) +print_ascii(100) +print_ascii(33) +print_newline() diff --git a/examples/while_demo.ltor b/examples/while_demo.ltor new file mode 100644 index 0000000..5861502 --- /dev/null +++ b/examples/while_demo.ltor @@ -0,0 +1,7 @@ +set i to 0 +while 1 do + if i > 10 then + break + end + set i to i+1 +end diff --git a/sandbox.c b/sandbox.c index 899af0c..e755b64 100644 --- a/sandbox.c +++ b/sandbox.c @@ -10,6 +10,9 @@ #include int main () { + struct VariableStore* store = var_store_init(); + printf("%d", var_store_hash_name(store, "var")); + return 0; // struct List l1; // short val = 17; diff --git a/src/evaluator.c b/src/evaluator.c index 85375c3..5f1796c 100644 --- a/src/evaluator.c +++ b/src/evaluator.c @@ -81,6 +81,7 @@ int evaluator_reduce_minus_pattern(struct List* evalList) { if ( ((i >= 1 && !is_type_number(list_get_type(evalList, i-1))) || (i == 0)) && ((i >= 1 && list_get_type(evalList, i-1) != TYPE_CLOSE_PARENTHESIS) || (i == 0)) && + ((i >= 1 && list_get_type(evalList, i-1) != TYPE_VAR_NAME) || (i == 0)) && list_get_type(evalList, i) == TYPE_OPERATOR && is_type_number(list_get_type(evalList, i+1)) ) { @@ -201,11 +202,13 @@ int evaluator_reduce_var(struct StateContainer* state, struct List* evalList) { } } if (patternPos == -1) return -1; - + int varKey; list_get(evalList, patternPos, &varKey); byte type = var_store_get_type_from_key(state->varStore, varKey); + + if (EVALUATOR_DEBUG_LEVEL >= 2) printf("Going to reduce var key %d at pos %d\n", patternPos); byte varVal[get_size_of_type(type)]; var_store_copy_from_key(state->varStore, varKey, &varVal); @@ -566,10 +569,10 @@ int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsig // check the content of this thing if (EVALUATOR_DEBUG_LEVEL >= 2) { list_print(&evalList); - printf("Now going to actually evaluate \n"); + printf("Now going to actually evaluate...\n"); } - while (evalList.num_elements > 1) { + while (evalList.num_elements > 1 || !is_type_number(list_get_type(&evalList, 0))) { if (EVALUATOR_DEBUG_LEVEL >= 2) list_print(&evalList); // int reduceVarOpStat = evaluator_reduce_var(state, &evalList); @@ -583,7 +586,13 @@ int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsig byte didReduced = 0; for (int m = 0; m < 6; m++) { short stat = 0; - if (m == 0) stat = evaluator_reduce_var(state, &evalList); + if (m == 0) { + stat = evaluator_reduce_var(state, &evalList); + if (stat == 0) { + didReduced = 1; + break; + } + } if (m == 1) stat = evaluator_reduce_function_call(&evalList, 0); if (m == 2) stat = evaluator_reduce_minus_pattern(&evalList); if (m == 3) stat = evaluator_reduce_not_pattern(&evalList); @@ -596,9 +605,7 @@ int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsig list_print(&evalList); } } - if (stat == 0) { - didReduced = 1; - } + if (stat == 0) didReduced = 1; } if (!didReduced) { diff --git a/src/funcs.c b/src/funcs.c index 67f0d52..d998e34 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -30,21 +30,54 @@ int abs_impl(int* res, unsigned char* resType, unsigned char* types, int* args) int print_number_impl(int* res, unsigned char* resType, unsigned char* types, int* args) { + *resType = TYPE_INT; + if (!is_type_number(types[0])) { + *res = 0; + return 1; + } + if (G_DEBUG_LEVEL >= 1) { + printf("REAL_PRINT: "); + } if (types[0] == TYPE_INT) { int val = args[0]; - printf("REAL_PRINT: %d\n", val); + printf("%d\n", val); } if (types[0] == TYPE_FLOAT) { float val = get_float_from_int_rep(args[0]); - printf("REAL_PRINT: %f\n", val); + printf("%f\n", val); } - if (is_type_number(types[0])) { - *res = 1; - *resType = TYPE_INT; + *res = 1; + return 0; +} - return 0; +int print_ascii_impl(int* res, unsigned char* resType, unsigned char* types, int* args) +{ + *resType = TYPE_INT; + if (!is_type_number(types[0])) { + *res = 0; + return 1; } - return 1; + + int charVal = 0; + if (types[0] == TYPE_INT) { + charVal = args[0]; + } + if (types[0] == TYPE_FLOAT) { + charVal = (int) get_float_from_int_rep(args[0]); + } + + printf("%c", *((char*) &charVal)); + *res = 1; + return 0; +} + +int print_newline_impl(int* res, unsigned char* resType, unsigned char* types, int* args) +{ + *resType = TYPE_INT; + *res = 1; + printf("\n"); + + return 0; } int simple_float_func(float (*func)(float), int* res, unsigned char* resType, unsigned char* types, int* args) @@ -217,6 +250,8 @@ struct FuncIntro intros[] = { {"get_pi", &get_pi_impl, 0}, {"print_number", &print_number_impl, 1}, + {"print_ascii", &print_ascii_impl, 1}, + {"print_newline", &print_newline_impl, 0}, {"", 0, 0} }; diff --git a/src/types.c b/src/types.c index 7187dea..dcc9096 100644 --- a/src/types.c +++ b/src/types.c @@ -50,7 +50,7 @@ char* get_repr(byte type, void* valPtr) return res; } - sprintf(res, "UNKNOWN(%d)", type); + sprintf(res, "UNKNOWN type=%d", type); return res; } diff --git a/src/utils.c b/src/utils.c index 9c9a5d9..86d3056 100644 --- a/src/utils.c +++ b/src/utils.c @@ -88,7 +88,6 @@ float m_float_modulus(float a, float b) { // find the remainder float t = a; - float res = 0; int i = 0; while (i < 1000) { t = t - b; diff --git a/tests/test_evaluation.c b/tests/test_evaluation.c index bd0bbfb..3ba3067 100644 --- a/tests/test_evaluation.c +++ b/tests/test_evaluation.c @@ -141,4 +141,26 @@ void test_evaluation() evaluate(state, "5.3 % 10", &resVal, &resType); assert(resType == TYPE_FLOAT); assert(float_almost_equal(5.3, get_float_from_int_rep(resVal))); + + int ex = 43; + var_store_set(state->varStore, "var", TYPE_INT, (void*) &ex); + evaluate(state, "var", &resVal, &resType); + assert(resType == TYPE_INT); + assert(43 == resVal); + + evaluate(state, "var < 52", &resVal, &resType); + assert(resType == TYPE_INT); + assert(1 == resVal); + + evaluate(state, "var < (52-2)", &resVal, &resType); + assert(resType == TYPE_INT); + assert(1 == resVal); + + int ex2 = 3; + var_store_set(state->varStore, "var2", TYPE_INT, (void*) &ex2); + + evaluate(state, "abs((var2^2)-((var-41)^2))+2", &resVal, &resType); + assert(resType == TYPE_INT); + printf("actually got: %d \n", resVal); + assert(7 == resVal); }