tinyc : add > support

Also can be run several time
This commit is contained in:
Mathieu Maret 2023-03-21 23:18:47 +01:00 committed by Mathieu Maret
parent 445fb63134
commit 6580bb08ba

View File

@ -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;
} }