diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2013-06-08 23:09:52 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2013-06-08 23:09:52 +0200 |
commit | 4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4 (patch) | |
tree | c193acf64ff2db985f6664f161cf586c3caeb684 /src/user/app/kbasic/expr.c | |
parent | eae9997d3c2dbaef53022ddabe61c1800a619499 (diff) | |
download | TCE-4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4.tar.gz TCE-4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4.zip |
All FWIK is deleted. YOSH is now pure C. Not-working KBASIC included.
Diffstat (limited to 'src/user/app/kbasic/expr.c')
-rw-r--r-- | src/user/app/kbasic/expr.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/user/app/kbasic/expr.c b/src/user/app/kbasic/expr.c new file mode 100644 index 0000000..3b8d558 --- /dev/null +++ b/src/user/app/kbasic/expr.c @@ -0,0 +1,153 @@ +#include <stdlib.h> + +#include "basic.h" + +void level2(int*), level3(int*), level4(int*), level5(int*), level6(int*), primitive(int*); +void unary(char, int*), arith(char, int*, int*); + +/* Entry point into parser. */ +void get_exp(int *result) +{ + get_token(); + if(!*token) { + serror(2); + return; + } + level2(result); + putback(); /* return last token read to input stream */ +} + +/* Add or subtract two terms. */ +void level2(int *result) +{ + register char op; + int hold; + + level3(result); + while((op = *token) == '+' || op == '-') { + get_token(); + level3(&hold); + arith(op, result, &hold); + } +} + +/* Multiply or divide two factors. */ +void level3(int *result) +{ + register char op; + int hold; + + level4(result); + while((op = *token) == '*' || op == '/' || op == '%') { + get_token(); + level4(&hold); + arith(op, result, &hold); + } +} + +/* Process integer exponent. */ +void level4(int *result) +{ + int hold; + + level5(result); + if(*token== '^') { + get_token(); + level4(&hold); + arith('^', result, &hold); + } +} + +/* Is a unary + or -. */ +void level5(int *result) +{ + register char op; + + op = 0; + if((token_type==DELIMITER) && (*token=='+' || *token=='-')) { + op = *token; + get_token(); + } + level6(result); + if(op) + unary(op, result); +} + +/* Process parenthesized expression. */ +void level6(int *result) +{ + if((*token == '(') && (token_type == DELIMITER)) { + get_token(); + level2(result); + if(*token != ')') + serror(1); + get_token(); + } + else + primitive(result); +} + +/* Find value of number or variable. */ +void primitive(int *result) +{ + + switch(token_type) { + case VARIABLE: + *result = *find_var(token); + get_token(); + return; + case NUMBER: + *result = atoi(token); + get_token(); + return; + case COMMAND: + switch(tok) { + case RND: + *result = rand(); + get_token(); + return; + } + default: + serror(0); + } +} + +/* Perform the specified arithmetic. */ +void arith(char o, int *r, int *h) +{ + register int t, ex; + + switch(o) { + case '-': + *r = *r-*h; + break; + case '+': + *r = *r+*h; + break; + case '*': + *r = *r * *h; + break; + case '/': + *r = (*r)/(*h); + break; + case '%': + t = (*r)/(*h); + *r = *r-(t*(*h)); + break; + case '^': + ex = *r; + if(*h==0) { + *r = 1; + break; + } + for(t=*h-1; t>0; --t) *r = (*r) * ex; + break; + } +} + +/* Reverse the sign. */ +void unary(char o, int *r) +{ + if(o=='-') *r = -(*r); +} + |