From 6580bb08ba4e5e14045e5b914a9bd1f5ef9d22db Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Tue, 21 Mar 2023 23:18:47 +0100 Subject: [PATCH] tinyc : add > support Also can be run several time --- userspace/tiny.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/userspace/tiny.c b/userspace/tiny.c index 2263595..e475780 100644 --- a/userspace/tiny.c +++ b/userspace/tiny.c @@ -23,7 +23,7 @@ * ";" * ::= "(" ")" * ::= | "=" - * ::= | "<" + * ::= | "<" | ">" * ::= | "+" | "-" * ::= | | * ::= "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() /* ::= | "+" | "-" */ return x; } -node *test() /* ::= | "<" */ +node *test() /* ::= | "<" | ">" */ { 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() /* ::= */ /* 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; }