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> ")"
|
* <paren_expr> ::= "(" <expr> ")"
|
||||||
* <expr> ::= <test> | <id> "=" <expr>
|
* <expr> ::= <test> | <id> "=" <expr>
|
||||||
* <test> ::= <sum> | <sum> "<" <sum>
|
* <test> ::= <sum> | <sum> "<" <sum> | <sum> ">" <sum>
|
||||||
* <sum> ::= <term> | <sum> "+" <term> | <sum> "-" <term>
|
* <sum> ::= <term> | <sum> "+" <term> | <sum> "-" <term>
|
||||||
* <term> ::= <id> | <int> | <paren_expr>
|
* <term> ::= <id> | <int> | <paren_expr>
|
||||||
* <id> ::= "a" | "b" | "c" | "d" | ... | "z"
|
* <id> ::= "a" | "b" | "c" | "d" | ... | "z"
|
||||||
@ -58,7 +58,7 @@
|
|||||||
/* Lexer. */
|
/* Lexer. */
|
||||||
|
|
||||||
enum { DO_SYM, ELSE_SYM, IF_SYM, WHILE_SYM, LBRA, RBRA, LPAR, RPAR,
|
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 };
|
char *words[] = { "do", "else", "if", "while", NULL };
|
||||||
|
|
||||||
@ -82,6 +82,7 @@ void next_sym()
|
|||||||
case '+': next_ch(); sym = PLUS; break;
|
case '+': next_ch(); sym = PLUS; break;
|
||||||
case '-': next_ch(); sym = MINUS; break;
|
case '-': next_ch(); sym = MINUS; break;
|
||||||
case '<': next_ch(); sym = LESS; break;
|
case '<': next_ch(); sym = LESS; break;
|
||||||
|
case '>': next_ch(); sym = MORE; break;
|
||||||
case ';': next_ch(); sym = SEMI; break;
|
case ';': next_ch(); sym = SEMI; break;
|
||||||
case '=': next_ch(); sym = EQUAL; break;
|
case '=': next_ch(); sym = EQUAL; break;
|
||||||
default:
|
default:
|
||||||
@ -115,7 +116,7 @@ void next_sym()
|
|||||||
|
|
||||||
/* Parser. */
|
/* Parser. */
|
||||||
|
|
||||||
enum { VAR, CST, ADD, SUB, LT, SET,
|
enum { VAR, CST, ADD, SUB, LT, MT, SET,
|
||||||
IF1, IF2, WHILE, DO, EMPTY, SEQ, EXPR, PROG };
|
IF1, IF2, WHILE, DO, EMPTY, SEQ, EXPR, PROG };
|
||||||
|
|
||||||
struct node { int kind; struct node *o1, *o2, *o3; int val; };
|
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;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
node *test() /* <test> ::= <sum> | <sum> "<" <sum> */
|
node *test() /* <test> ::= <sum> | <sum> "<" <sum> | <sum> ">" <sum> */
|
||||||
{ node *t, *x = sum();
|
{ node *t, *x = sum();
|
||||||
if (sym == LESS)
|
if (sym == LESS)
|
||||||
{ t=x; x=new_node(LT); next_sym(); x->o1=t; x->o2=sum(); }
|
{ 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;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +222,7 @@ node *program() /* <program> ::= <statement> */
|
|||||||
|
|
||||||
/* Code generator. */
|
/* 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;
|
typedef char code;
|
||||||
code object[1000], *here = object;
|
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 ADD : c(x->o1); c(x->o2); g(IADD); break;
|
||||||
case SUB : c(x->o1); c(x->o2); g(ISUB); break;
|
case SUB : c(x->o1); c(x->o2); g(ISUB); break;
|
||||||
case LT : c(x->o1); c(x->o2); g(ILT); 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 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 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();
|
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 IADD : sp[-2] = sp[-2] + sp[-1]; --sp; goto again;
|
||||||
case ISUB : 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 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 JMP : pc += *pc; goto again;
|
||||||
case JZ : if (*--sp == 0) pc += *pc; else 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;
|
case JNZ : if (*--sp != 0) pc += *pc; else pc++; goto again;
|
||||||
@ -278,16 +283,24 @@ void run()
|
|||||||
/* Main program. */
|
/* Main program. */
|
||||||
|
|
||||||
int func_tiny()
|
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++)
|
for (i = 0; i < 26; i++)
|
||||||
globals[i] = 0;
|
globals[i] = 0;
|
||||||
run();
|
run();
|
||||||
for (i=0; i<26; i++)
|
for (i = 0; i < 26; i++)
|
||||||
if (globals[i] != 0)
|
if (globals[i] != 0)
|
||||||
printf("%c = %d\n", 'a'+i, globals[i]);
|
printf("%c = %d\n", 'a' + i, globals[i]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user