From 77339ce34a79a7b5a1818c1009d1db1252fe8ea6 Mon Sep 17 00:00:00 2001 From: Flavian Kaufmann Date: Tue, 20 May 2025 08:03:20 +0200 Subject: cleanup --- README.md | 2 +- ast.c | 226 +++++++++++++++++++++++++++++++------------------------------- ast.h | 35 +++++----- lexer.l | 4 +- parser.y | 6 +- 5 files changed, 141 insertions(+), 132 deletions(-) diff --git a/README.md b/README.md index b05b025..bbc7b31 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A small interpreter of the IMP programming language. -# Build +## Build - `make all` to build interpreter. - `make run` to interpret "example.imp". diff --git a/ast.c b/ast.c index ab7e1e0..4663cd2 100644 --- a/ast.c +++ b/ast.c @@ -4,13 +4,9 @@ #include "ast.h" static ASTNode *new_node(NodeType type) { - ASTNode *n = malloc(sizeof(ASTNode)); - if (!n) { - fprintf(stderr, "Out of memory\n"); - exit(EXIT_FAILURE); - } - n->type = type; - return n; + ASTNode *node = malloc(sizeof(ASTNode)); + node->type = type; + return node; } ASTNode *ast_skip(void) { @@ -18,142 +14,148 @@ ASTNode *ast_skip(void) { } ASTNode *ast_assign(ASTNode *var, ASTNode *aexp) { - ASTNode *n = new_node(NT_ASSIGN); - n->u.assign.var = var; - n->u.assign.aexp = aexp; - return n; + ASTNode *node = new_node(NT_ASSIGN); + node->u.d_assign.var = var; + node->u.d_assign.aexp = aexp; + return node; } -ASTNode *ast_seq(ASTNode *s1, ASTNode *s2) { - ASTNode *n = new_node(NT_SEQ); - n->u.seq.s1 = s1; - n->u.seq.s2 = s2; - return n; +ASTNode *ast_seq(ASTNode *stm1, ASTNode *stm2) { + ASTNode *node = new_node(NT_SEQ); + node->u.d_seq.stm1 = stm1; + node->u.d_seq.stm2 = stm2; + return node; } -ASTNode *ast_if(ASTNode *bexp, ASTNode *s1, ASTNode *s2) { - ASTNode *n = new_node(NT_IF); - n->u.cond.bexp = bexp; - n->u.cond.s1 = s1; - n->u.cond.s2 = s2; - return n; +ASTNode *ast_if(ASTNode *bexp, ASTNode *stm1, ASTNode *stm2) { + ASTNode *node = new_node(NT_IF); + node->u.d_if.bexp = bexp; + node->u.d_if.stm1 = stm1; + node->u.d_if.stm2 = stm2; + return node; } -ASTNode *ast_while(ASTNode *bexp, ASTNode *s) { - ASTNode *n = new_node(NT_WHILE); - n->u.cond.bexp = bexp; - n->u.cond.s1 = s; - return n; +ASTNode *ast_while(ASTNode *bexp, ASTNode *stm) { + ASTNode *node = new_node(NT_WHILE); + node->u.d_while.bexp = bexp; + node->u.d_while.stm = stm; + return node; } ASTNode *ast_int(int val) { - ASTNode *n = new_node(NT_INT); - n->u.val = val; - return n; + ASTNode *node = new_node(NT_INT); + node->u.d_int.val = val; + return node; } -ASTNode *ast_var(char *var) { - ASTNode *n = new_node(NT_VAR); - n->u.var = strdup(var); - return n; +ASTNode *ast_var(char *name) { + ASTNode *node = new_node(NT_VAR); + node->u.d_var.name = strdup(name); + return node; } -ASTNode *ast_aop(AOp op, ASTNode *aexp1, ASTNode *aexp2) { - ASTNode *n = new_node(NT_AOP); - n->u.bin.exp1 = aexp1; - n->u.bin.exp2 = aexp2; - n->u.bin.op.aop = op; - return n; +ASTNode *ast_aop(AOp aop, ASTNode *aexp1, ASTNode *aexp2) { + ASTNode *node = new_node(NT_AOP); + node->u.d_aop.aexp1 = aexp1; + node->u.d_aop.aexp2 = aexp2; + node->u.d_aop.aop = aop; + return node; } -ASTNode *ast_bop(BOp op, ASTNode *bexp1, ASTNode *bexp2) { - ASTNode *n = new_node(NT_BOP); - n->u.bin.exp1 = bexp1; - n->u.bin.exp2 = bexp2; - n->u.bin.op.bop = op; - return n; +ASTNode *ast_bop(BOp bop, ASTNode *bexp1, ASTNode *bexp2) { + ASTNode *node = new_node(NT_BOP); + node->u.d_bop.bexp1 = bexp1; + node->u.d_bop.bexp2 = bexp2; + node->u.d_bop.bop = bop; + return node; } ASTNode *ast_not(ASTNode *bexp) { - ASTNode *n = new_node(NT_NOT); - n->u.bexp = bexp; - return n; + ASTNode *node = new_node(NT_NOT); + node->u.d_not.bexp = bexp; + return node; } -ASTNode *ast_rop(ROp op, ASTNode *aexp1, ASTNode *aexp2) { - ASTNode *n = new_node(NT_ROP); - n->u.bin.exp1 = aexp1; - n->u.bin.exp2 = aexp2; - n->u.bin.op.rop = op; - return n; +ASTNode *ast_rop(ROp rop, ASTNode *aexp1, ASTNode *aexp2) { + ASTNode *node = new_node(NT_ROP); + node->u.d_rop.aexp1 = aexp1; + node->u.d_rop.aexp2 = aexp2; + node->u.d_rop.rop = rop; + return node; } -void free_ast(ASTNode *n) { - if (!n) return; - switch (n->type) { +void free_ast(ASTNode *node) { + if (!node) return; + switch (node->type) { case NT_SKIP: break; case NT_ASSIGN: - free_ast(n->u.assign.var); - free_ast(n->u.assign.aexp); + free_ast(node->u.d_assign.var); + free_ast(node->u.d_assign.aexp); break; case NT_SEQ: - free_ast(n->u.seq.s1); - free_ast(n->u.seq.s2); + free_ast(node->u.d_seq.stm1); + free_ast(node->u.d_seq.stm2); break; case NT_IF: - free_ast(n->u.cond.bexp); - free_ast(n->u.cond.s1); - free_ast(n->u.cond.s2); + free_ast(node->u.d_if.bexp); + free_ast(node->u.d_if.stm1); + free_ast(node->u.d_if.stm2); break; case NT_WHILE: - free_ast(n->u.cond.bexp); - free_ast(n->u.cond.s1); + free_ast(node->u.d_while.bexp); + free_ast(node->u.d_while.stm); break; case NT_INT: break; case NT_VAR: - free(n->u.var); + free(node->u.d_var.name); break; case NT_AOP: + free_ast(node->u.d_aop.aexp1); + free_ast(node->u.d_aop.aexp2); + break; case NT_BOP: + free_ast(node->u.d_bop.bexp1); + free_ast(node->u.d_bop.bexp2); + break; case NT_ROP: - free_ast(n->u.bin.exp1); - free_ast(n->u.bin.exp2); + free_ast(node->u.d_rop.aexp1); + free_ast(node->u.d_rop.aexp2); break; case NT_NOT: - free_ast(n->u.bexp); + free_ast(node->u.d_not.bexp); break; } - free(n); + free(node); } typedef struct Env { - char *var; + char *name; int val; struct Env *next; } Env; static Env *env = NULL; -static int env_lookup(const char *var) { +static int env_lookup(const char *name) { for (Env *e = env; e; e = e->next) { - if (strcmp(e->var, var) == 0) + if (strcmp(e->name, name) == 0) return e->val; } - fprintf(stderr, "Undefined variable %s\n", var); + fprintf(stderr, "Undefined variable %s\n", name); exit(EXIT_FAILURE); } -static void env_update(const char *var, int val) { +static void env_update(const char *name, int val) { for (Env *e = env; e; e = e->next) { - if (strcmp(e->var, var) == 0) { + if (strcmp(e->name, name) == 0) { e->val = val; return; } } Env *e = malloc(sizeof(Env)); - e->var = strdup(var); + e->name = strdup(name); e->val = val; e->next = env; env = e; @@ -162,47 +164,47 @@ static void env_update(const char *var, int val) { void env_print(void) { Env *current_env = env; while (current_env) { - printf("%s = %d\n", current_env->var, current_env->val); + printf("%s = %d\n", current_env->name, current_env->val); current_env = current_env->next; } } -static int eval_aexpr(ASTNode *n) { - switch (n->type) { - case NT_INT: return n->u.val; - case NT_VAR: return env_lookup(n->u.var); +static int eval_aexpr(ASTNode *node) { + switch (node->type) { + case NT_INT: return node->u.d_int.val; + case NT_VAR: return env_lookup(node->u.d_var.name); case NT_AOP: { - int aexp1 = eval_aexpr(n->u.bin.exp1); - int aexp2 = eval_aexpr(n->u.bin.exp2); - switch (n->u.bin.op.aop) { + int aexp1 = eval_aexpr(node->u.d_aop.aexp1); + int aexp2 = eval_aexpr(node->u.d_aop.aexp2); + switch (node->u.d_aop.aop) { case AOP_ADD: return aexp1 + aexp2; case AOP_SUB: return aexp1 - aexp2; case AOP_MUL: return aexp1 * aexp2; } } default: - fprintf(stderr, "Bad aexpr node %d\n", n->type); + fprintf(stderr, "Bad aexpr node %d\n", node->type); exit(EXIT_FAILURE); } } -static int eval_bexpr(ASTNode *n) { - switch (n->type) { +static int eval_bexpr(ASTNode *node) { + switch (node->type) { case NT_BOP: { - int bexp1 = eval_bexpr(n->u.bin.exp1); - int bexp2 = eval_bexpr(n->u.bin.exp2); - switch (n->u.bin.op.bop) { + int bexp1 = eval_bexpr(node->u.d_bop.bexp1); + int bexp2 = eval_bexpr(node->u.d_bop.bexp2); + switch (node->u.d_bop.bop) { case BOP_AND: return bexp1 && bexp2; case BOP_OR: return bexp1 || bexp2; } } case NT_NOT: - return !eval_bexpr(n->u.bexp); + return !eval_bexpr(node->u.d_not.bexp); case NT_ROP: { - int aexp1 = eval_aexpr(n->u.bin.exp1); - int aexp2 = eval_aexpr(n->u.bin.exp2); - switch (n->u.bin.op.rop) { + int aexp1 = eval_aexpr(node->u.d_rop.aexp1); + int aexp2 = eval_aexpr(node->u.d_rop.aexp2); + switch (node->u.d_rop.rop) { case ROP_EQ: return aexp1 == aexp2; case ROP_NE: return aexp1 != aexp2; case ROP_LT: return aexp1 < aexp2; @@ -212,39 +214,39 @@ static int eval_bexpr(ASTNode *n) { } } default: - fprintf(stderr, "Bad bexpr node %d\n", n->type); + fprintf(stderr, "Bad bexpr node %d\n", node->type); exit(EXIT_FAILURE); } } -void exec_stmt(ASTNode *n) { - while (n) { - switch (n->type) { +void exec_stmt(ASTNode *node) { + while (node) { + switch (node->type) { case NT_SKIP: return; case NT_ASSIGN: { - char *var = n->u.assign.var->u.var; - int val = eval_aexpr(n->u.assign.aexp); + char *var = node->u.d_assign.var->u.d_var.name; + int val = eval_aexpr(node->u.d_assign.aexp); env_update(var, val); return; } case NT_SEQ: - exec_stmt(n->u.seq.s1); - n = n->u.seq.s2; - continue; + exec_stmt(node->u.d_seq.stm1); + exec_stmt(node->u.d_seq.stm2); + return; case NT_IF: - if (eval_bexpr(n->u.cond.bexp)) - exec_stmt(n->u.cond.s1); + if (eval_bexpr(node->u.d_if.bexp)) + exec_stmt(node->u.d_if.stm1); else - exec_stmt(n->u.cond.s2); + exec_stmt(node->u.d_if.stm2); return; case NT_WHILE: - while (eval_bexpr(n->u.cond.bexp)) { - exec_stmt(n->u.cond.s1); + while (eval_bexpr(node->u.d_while.bexp)) { + exec_stmt(node->u.d_while.stm); } return; default: - fprintf(stderr, "Bad stmt node %d\n", n->type); + fprintf(stderr, "Bad stmt node %d\n", node->type); exit(EXIT_FAILURE); } } diff --git a/ast.h b/ast.h index 67d6228..7a58372 100644 --- a/ast.h +++ b/ast.h @@ -13,30 +13,33 @@ typedef enum { ROP_EQ, ROP_NE, ROP_LT, ROP_LE, ROP_GT, ROP_GE } ROp; typedef struct ASTNode { NodeType type; union { - int val; - char *var; - struct { struct ASTNode *var, *aexp; } assign; - struct { struct ASTNode *exp1, *exp2; union { AOp aop; BOp bop; ROp rop; } op;} bin; - struct ASTNode *bexp; - struct { struct ASTNode *bexp, *s1, *s2; } cond; - struct { struct ASTNode *s1, *s2; } seq; + struct { struct ASTNode *var, *aexp; } d_assign; + struct { struct ASTNode *stm1, *stm2; } d_seq; + struct { struct ASTNode *bexp, *stm1, *stm2; } d_if; + struct { struct ASTNode *bexp, *stm; } d_while; + struct { int val; } d_int ; + struct { char *name; } d_var; + struct { AOp aop; struct ASTNode *aexp1, *aexp2; } d_aop; + struct { BOp bop; struct ASTNode *bexp1, *bexp2; } d_bop; + struct { struct ASTNode *bexp; } d_not; + struct { ROp rop; struct ASTNode *aexp1, *aexp2; } d_rop; } u; } ASTNode; ASTNode *ast_skip(void); ASTNode *ast_assign(ASTNode *var, ASTNode *aexp); -ASTNode *ast_seq(ASTNode *s1, ASTNode *s2); -ASTNode *ast_if(ASTNode *bexp, ASTNode *s1, ASTNode *s2); -ASTNode *ast_while(ASTNode *bexp, ASTNode *s); +ASTNode *ast_seq(ASTNode *stm1, ASTNode *stm2); +ASTNode *ast_if(ASTNode *bexp, ASTNode *stm1, ASTNode *stm2); +ASTNode *ast_while(ASTNode *bexp, ASTNode *stm); ASTNode *ast_int(int val); -ASTNode *ast_var(char *var); -ASTNode *ast_aop(AOp, ASTNode *aexp1, ASTNode *aexp2); -ASTNode *ast_bop(BOp, ASTNode *bexp1, ASTNode *bexp2); +ASTNode *ast_var(char *name); +ASTNode *ast_aop(AOp aop, ASTNode *aexp1, ASTNode *aexp2); +ASTNode *ast_bop(BOp bop, ASTNode *bexp1, ASTNode *bexp2); ASTNode *ast_not(ASTNode *bexp); -ASTNode *ast_rop(ROp, ASTNode *aexp1, ASTNode *aexp2); +ASTNode *ast_rop(ROp rop, ASTNode *aexp1, ASTNode *aexp2); -void exec_stmt(ASTNode *n); -void free_ast(ASTNode *n); +void exec_stmt(ASTNode *node); +void free_ast(ASTNode *node); void env_print(void); #endif diff --git a/lexer.l b/lexer.l index 4895b24..c9aaff0 100644 --- a/lexer.l +++ b/lexer.l @@ -6,7 +6,7 @@ DIGIT [0-9] IDENT [A-Za-z][A-Za-z0-9]* -WS [ \t\r\n]+ +WHITESPACE [ \t\r\n]+ %% @@ -41,7 +41,7 @@ WS [ \t\r\n]+ {DIGIT}+ { yylval.num = atoi(yytext); return TOKEN_NUMERAL; } {IDENT} { yylval.id = strdup(yytext); return TOKEN_IDENTIFIER; } -{WS} { } +{WHITESPACE} { } . { fprintf(stderr, "Unknown char: %s\n", yytext); } %% diff --git a/parser.y b/parser.y index 5974b96..9a94480 100644 --- a/parser.y +++ b/parser.y @@ -5,8 +5,12 @@ extern char *yytext; extern int yylineno; extern int yylex(); -void yyerror(const char *s) { fprintf(stderr, "Parse error at token \"%s\", line %d: %s\n", yytext, yylineno, s); } + ASTNode *ast_root; + +void yyerror(const char *s) { + fprintf(stderr, "Parse error at token \"%s\", line %d: %s\n", yytext, yylineno, s); +} %} -- cgit v1.2.3