aboutsummaryrefslogtreecommitdiff
path: root/src/interpreter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpreter.c')
-rw-r--r--src/interpreter.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/interpreter.c b/src/interpreter.c
index 8bcc6f4..2de5b63 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -97,6 +97,143 @@ void context_print_proc_table(Context *context) {
hashmap_keys_iter_free(iter);
}
+void ast_print(ASTNode *node, int depth) {
+ int indent = depth * 2;
+ switch (node->type) {
+ case NT_SKIP: {
+ printf("%*sSKIP\n", indent, "");
+ break;
+ }
+ case NT_ASSIGN: {
+ printf("%*sASSIGN %s=%d\n", indent, "",
+ node->u.d_assign.var->u.d_var.name,
+ node->u.d_assign.aexp->u.d_int.val);
+ break;
+ }
+ case NT_SEQ: {
+ ast_print(node->u.d_seq.stm1, depth);
+ printf("%*sSEQ\n", indent, "");
+ ast_print(node->u.d_seq.stm2, depth);
+ break;
+ }
+ case NT_IF: {
+ printf("%*sIF (", indent, "");
+ ast_print(node->u.d_if.bexp, 0);
+ printf(")\n");
+ ast_print(node->u.d_if.stm1, depth + 1);
+ printf("%*sELSE\n", indent, "");
+ ast_print(node->u.d_if.stm2, depth + 1);
+ break;
+ }
+ case NT_WHILE: {
+ printf("%*sWHILE (", indent, "");
+ ast_print(node->u.d_while.bexp, 0);
+ printf(")\n");
+ ast_print(node->u.d_while.stm, depth + 1);
+ break;
+ }
+ case NT_INT: {
+ printf("%d", node->u.d_int.val);
+ break;
+ }
+ case NT_VAR: {
+ printf("%s", node->u.d_var.name);
+ break;
+ }
+ case NT_AOP: {
+ printf("(");
+ ast_print(node->u.d_aop.aexp1, 0);
+ switch (node->u.d_aop.aop) {
+ case AOP_ADD: printf(" + "); break;
+ case AOP_SUB: printf(" - "); break;
+ case AOP_MUL: printf(" * "); break;
+ default: assert(0);
+ }
+ ast_print(node->u.d_aop.aexp2, 0);
+ printf(")");
+ break;
+ }
+ case NT_BOP: {
+ printf("(");
+ ast_print(node->u.d_bop.bexp1, 0);
+ switch (node->u.d_bop.bop) {
+ case BOP_AND: printf(" && "); break;
+ case BOP_OR: printf(" || "); break;
+ default: assert(0);
+ }
+ ast_print(node->u.d_bop.bexp2, 0);
+ printf(")");
+ break;
+ }
+ case NT_NOT: {
+ printf("!");
+ ast_print(node->u.d_not.bexp, 0);
+ break;
+ }
+ case NT_ROP: {
+ printf("(");
+ ast_print(node->u.d_rop.aexp1, 0);
+ switch (node->u.d_rop.rop) {
+ case ROP_EQ: printf(" == "); break;
+ case ROP_NE: printf(" != "); break;
+ case ROP_LT: printf(" < "); break;
+ case ROP_LE: printf(" <= "); break;
+ case ROP_GT: printf(" > "); break;
+ case ROP_GE: printf(" >= "); break;
+ default: assert(0);
+ }
+ ast_print(node->u.d_rop.aexp2, 0);
+ printf(")");
+ break;
+ }
+ case NT_LET: {
+ printf("%*sLET %s = ", indent, "", node->u.d_let.var->u.d_var.name);
+ ast_print(node->u.d_let.aexp, 0);
+ printf("\n");
+ ast_print(node->u.d_let.stm, depth + 1);
+ break;
+ }
+ case NT_PROCDECL: {
+ printf("%*sPROC %s(", indent, "", node->u.d_procdecl.name);
+ ASTNodeList *args = node->u.d_procdecl.args;
+ while (args) {
+ printf("%s", args->node->u.d_var.name);
+ args = args->next;
+ if (args) printf(", ");
+ }
+ printf("; ");
+ ASTNodeList *vargs = node->u.d_procdecl.vargs;
+ while (vargs) {
+ printf("%s", vargs->node->u.d_var.name);
+ vargs = vargs->next;
+ if (vargs) printf(", ");
+ }
+ printf(")\n");
+ ast_print(node->u.d_procdecl.stm, depth + 1);
+ break;
+ }
+ case NT_PROCCALL: {
+ printf("%*sCALL %s(", indent, "", node->u.d_proccall.name);
+ ASTNodeList *args = node->u.d_proccall.args;
+ while (args) {
+ printf("%s", args->node->u.d_var.name);
+ args = args->next;
+ if (args) printf(", ");
+ }
+ printf("; ");
+ ASTNodeList *vargs = node->u.d_proccall.vargs;
+ while (vargs) {
+ printf("%s", vargs->node->u.d_var.name);
+ vargs = vargs->next;
+ if (vargs) printf(", ");
+ }
+ printf(")\n");
+ break;
+ }
+ default: assert(0);
+ }
+}
+
static int eval_aexpr(Context *context, ASTNode *node) {
switch (node->type) {
case NT_INT: return node->u.d_int.val;
@@ -278,4 +415,21 @@ int interp_str (Context *context, const char *str) {
}
yy_delete_buffer(buf);
return 0;
+}
+
+int print_ast_file (const char *path) {
+ yyin = fopen(path, "r");
+ if (!yyin) {
+ return -1;
+ }
+ yyrestart(yyin);
+ if (yyparse()) {
+ ast_free(ast_root);
+ fclose(yyin);
+ return -1;
+ }
+ ast_print(ast_root, 0);
+ ast_free(ast_root);
+ fclose(yyin);
+ return 0;
} \ No newline at end of file