tinyc : add > support
Also can be run several time
This commit is contained in:
parent
445fb63134
commit
6580bb08ba
@ -23,7 +23,7 @@
|
||||
* ";"
|
||||
* <paren_expr> ::= "(" <expr> ")"
|
||||
* <expr> ::= <test> | <id> "=" <expr>
|
||||
* <test> ::= <sum> | <sum> "<" <sum>
|
||||
* <test> ::= <sum> | <sum> "<" <sum> | <sum> ">" <sum>
|
||||
* <sum> ::= <term> | <sum> "+" <term> | <sum> "-" <term>
|
||||
* <term> ::= <id> | <int> | <paren_expr>
|
||||
* <id> ::= "a" | "b" | "c" | "d" | ... | "z"
|
||||
@ -58,7 +58,7 @@
|
||||
/* Lexer. */
|
||||
|
||||
enum { DO_SYM, ELSE_SYM, IF_SYM, WHILE_SYM, LBRA, RBRA, LPAR, RPAR,
|
||||
PLUS, MINUS, LESS, SEMI, EQUAL, INT, ID, EOI };
|
||||
PLUS, MINUS, LESS, MORE, SEMI, EQUAL, INT, ID, EOI };
|
||||
|
||||
char *words[] = { "do", "else", "if", "while", NULL };
|
||||
|
||||
@ -82,6 +82,7 @@ void next_sym()
|
||||
case '+': next_ch(); sym = PLUS; break;
|
||||
case '-': next_ch(); sym = MINUS; break;
|
||||
case '<': next_ch(); sym = LESS; break;
|
||||
case '>': next_ch(); sym = MORE; break;
|
||||
case ';': next_ch(); sym = SEMI; break;
|
||||
case '=': next_ch(); sym = EQUAL; break;
|
||||
default:
|
||||
@ -115,7 +116,7 @@ void next_sym()
|
||||
|
||||
/* Parser. */
|
||||
|
||||
enum { VAR, CST, ADD, SUB, LT, SET,
|
||||
enum { VAR, CST, ADD, SUB, LT, MT, SET,
|
||||
IF1, IF2, WHILE, DO, EMPTY, SEQ, EXPR, PROG };
|
||||
|
||||
struct node { int kind; struct node *o1, *o2, *o3; int val; };
|
||||
@ -141,10 +142,12 @@ node *sum() /* <sum> ::= <term> | <sum> "+" <term> | <sum> "-" <term> */
|
||||
return x;
|
||||
}
|
||||
|
||||
node *test() /* <test> ::= <sum> | <sum> "<" <sum> */
|
||||
node *test() /* <test> ::= <sum> | <sum> "<" <sum> | <sum> ">" <sum> */
|
||||
{ node *t, *x = sum();
|
||||
if (sym == LESS)
|
||||
{ t=x; x=new_node(LT); next_sym(); x->o1=t; x->o2=sum(); }
|
||||
else if (sym == MORE)
|
||||
{ t=x; x=new_node(MT); next_sym(); x->o1=t; x->o2=sum(); }
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -219,7 +222,7 @@ node *program() /* <program> ::= <statement> */
|
||||
|
||||
/* Code generator. */
|
||||
|
||||
enum { IFETCH, ISTORE, IPUSH, IPOP, IADD, ISUB, ILT, JZ, JNZ, JMP, HALT };
|
||||
enum { IFETCH, ISTORE, IPUSH, IPOP, IADD, ISUB, ILT, IMT, JZ, JNZ, JMP, HALT };
|
||||
|
||||
typedef char code;
|
||||
code object[1000], *here = object;
|
||||
@ -236,6 +239,7 @@ void c(node *x)
|
||||
case ADD : c(x->o1); c(x->o2); g(IADD); break;
|
||||
case SUB : c(x->o1); c(x->o2); g(ISUB); break;
|
||||
case LT : c(x->o1); c(x->o2); g(ILT); break;
|
||||
case MT : c(x->o1); c(x->o2); g(IMT); break;
|
||||
case SET : c(x->o2); g(ISTORE); g(x->o1->val); break;
|
||||
case IF1 : c(x->o1); g(JZ); p1=hole(); c(x->o2); fix(p1,here); break;
|
||||
case IF2 : c(x->o1); g(JZ); p1=hole(); c(x->o2); g(JMP); p2=hole();
|
||||
@ -267,6 +271,7 @@ void run()
|
||||
case IADD : sp[-2] = sp[-2] + sp[-1]; --sp; goto again;
|
||||
case ISUB : sp[-2] = sp[-2] - sp[-1]; --sp; goto again;
|
||||
case ILT : sp[-2] = sp[-2] < sp[-1]; --sp; goto again;
|
||||
case IMT : sp[-2] = sp[-2] > sp[-1]; --sp; goto again;
|
||||
case JMP : pc += *pc; goto again;
|
||||
case JZ : if (*--sp == 0) pc += *pc; else pc++; goto again;
|
||||
case JNZ : if (*--sp != 0) pc += *pc; else pc++; goto again;
|
||||
@ -278,17 +283,25 @@ void run()
|
||||
/* Main program. */
|
||||
|
||||
int func_tiny()
|
||||
{ int i;
|
||||
{
|
||||
int i;
|
||||
ch = ' ';
|
||||
sym = 0;
|
||||
int_val = 0;
|
||||
memset(id_name, 0, sizeof(id_name));
|
||||
memset(globals, 0, sizeof(globals));
|
||||
memset(object, 0, sizeof(object));
|
||||
here = object;
|
||||
|
||||
c(program());
|
||||
c(program());
|
||||
|
||||
for (i=0; i<26; i++)
|
||||
globals[i] = 0;
|
||||
run();
|
||||
for (i=0; i<26; i++)
|
||||
if (globals[i] != 0)
|
||||
printf("%c = %d\n", 'a'+i, globals[i]);
|
||||
for (i = 0; i < 26; i++)
|
||||
globals[i] = 0;
|
||||
run();
|
||||
for (i = 0; i < 26; i++)
|
||||
if (globals[i] != 0)
|
||||
printf("%c = %d\n", 'a' + i, globals[i]);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user