You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
335 lines
6.7 KiB
335 lines
6.7 KiB
#include "ast.h"
|
|
#include "parser.tab.h"
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
void prlev(sol_state_t *state, int lev, const char *fmt, ...) {
|
|
va_list vl;
|
|
int i;
|
|
|
|
for(i = 0; i < lev; i++) {
|
|
sol_putchar(state, '|');
|
|
sol_putchar(state, ' ');
|
|
}
|
|
va_start(vl, fmt);
|
|
sol_vprintf(state, fmt, vl);
|
|
va_end(vl);
|
|
sol_putchar(state, '\n');
|
|
}
|
|
|
|
void prex( sol_state_t *, expr_node *, int);
|
|
|
|
void prst(sol_state_t *state, stmt_node *node, int lev) {
|
|
if(!node) {
|
|
prlev(state, lev, "<NULL>");
|
|
return;
|
|
}
|
|
switch(node->type) {
|
|
case ST_EXPR:
|
|
prlev(state, lev, "Stmt<Expr>:");
|
|
prex(state, node->expr, lev + 1);
|
|
break;
|
|
|
|
case ST_IFELSE:
|
|
prlev(state, lev, "Stmt<IfElse>:");
|
|
lev++;
|
|
prlev(state, lev, "Cond:");
|
|
prex(state, node->ifelse->cond, lev + 1);
|
|
prlev(state, lev, "IfTrue:");
|
|
prst(state, node->ifelse->iftrue, lev + 1);
|
|
prlev(state, lev, "IfFalse:");
|
|
prst(state, node->ifelse->iffalse, lev + 1);
|
|
break;
|
|
|
|
case ST_LOOP:
|
|
prlev(state, lev, "Stmt<Loop>:");
|
|
lev++;
|
|
prlev(state, lev, "Cond:");
|
|
prex(state, node->loop->cond, lev + 1);
|
|
prlev(state, lev, "Loop:");
|
|
prst(state, node->loop->loop, lev + 1);
|
|
break;
|
|
|
|
case ST_ITER:
|
|
prlev(state, lev, "Stmt<Iter>:");
|
|
lev++;
|
|
prlev(state, lev, "Var: %s", node->iter->var);
|
|
prlev(state, lev, "Iter:");
|
|
prex(state, node->iter->iter, lev + 1);
|
|
prlev(state, lev, "Loop:");
|
|
prst(state, node->iter->loop, lev + 1);
|
|
break;
|
|
|
|
case ST_LIST:
|
|
prlev(state, lev, "Stmt<List>:");
|
|
stmtlist_node *cur = node->stmtlist;
|
|
while(cur && cur->stmt) {
|
|
prst(state, cur->stmt, lev + 1);
|
|
cur = cur->next;
|
|
}
|
|
break;
|
|
|
|
case ST_RET:
|
|
prlev(state, lev, "Stmt<Ret>:");
|
|
prex(state, node->ret->ret, lev + 1);
|
|
break;
|
|
|
|
case ST_CONT:
|
|
prlev(state, lev, "Stmt<Continue>");
|
|
break;
|
|
|
|
case ST_BREAK:
|
|
prlev(state, lev, "Stmt<Break>");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void prex(sol_state_t *state, expr_node *node, int lev) {
|
|
assoclist_node *cura;
|
|
exprlist_node *cure;
|
|
identlist_node *curi;
|
|
if(!node) {
|
|
prlev(state, lev, "<NULL>");
|
|
return;
|
|
}
|
|
switch(node->type) {
|
|
case EX_LIT:
|
|
prlev(state, lev, "Literal:");
|
|
lev++;
|
|
switch(node->lit->type) {
|
|
case LIT_INT:
|
|
prlev(state, lev, "Int: %ld", node->lit->ival);
|
|
break;
|
|
|
|
case LIT_FLOAT:
|
|
prlev(state, lev, "Float: %f", node->lit->fval);
|
|
break;
|
|
|
|
case LIT_STRING:
|
|
prlev(state, lev, "String: %s", node->lit->str);
|
|
break;
|
|
|
|
case LIT_NONE:
|
|
prlev(state, lev, "None");
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case EX_LISTGEN:
|
|
prlev(state, lev, "ListGen:");
|
|
cure = node->listgen->list;
|
|
while(cure && cure->expr) {
|
|
prex(state, cure->expr, lev + 1);
|
|
cure = cure->next;
|
|
}
|
|
break;
|
|
|
|
case EX_MAPGEN:
|
|
prlev(state, lev, "MapGen:");
|
|
lev++;
|
|
cura = node->mapgen->map;
|
|
while(cura && cura->item) {
|
|
prlev(state, lev, "<Key>:");
|
|
prex(state, cura->item->key, lev + 1);
|
|
prlev(state, lev, "<Value>:");
|
|
prex(state, cura->item->value, lev + 1);
|
|
cura = cura->next;
|
|
}
|
|
break;
|
|
|
|
case EX_BINOP:
|
|
prlev(state, lev, "BinOp:");
|
|
lev++;
|
|
switch(node->binop->type) {
|
|
case OP_ADD:
|
|
prlev(state, lev, "Op: +");
|
|
break;
|
|
|
|
case OP_SUB:
|
|
prlev(state, lev, "Op: -");
|
|
break;
|
|
|
|
case OP_MUL:
|
|
prlev(state, lev, "Op: *");
|
|
break;
|
|
|
|
case OP_DIV:
|
|
prlev(state, lev, "Op: /");
|
|
break;
|
|
|
|
case OP_MOD:
|
|
prlev(state, lev, "Op: %");
|
|
break;
|
|
|
|
case OP_POW:
|
|
prlev(state, lev, "Op: **");
|
|
break;
|
|
|
|
case OP_BAND:
|
|
prlev(state, lev, "Op: &");
|
|
break;
|
|
|
|
case OP_BOR:
|
|
prlev(state, lev, "Op: |");
|
|
break;
|
|
|
|
case OP_BXOR:
|
|
prlev(state, lev, "Op: ^");
|
|
break;
|
|
|
|
case OP_LAND:
|
|
prlev(state, lev, "Op: &&");
|
|
break;
|
|
|
|
case OP_LOR:
|
|
prlev(state, lev, "Op: ||");
|
|
break;
|
|
|
|
case OP_EQUAL:
|
|
prlev(state, lev, "Op: ==");
|
|
break;
|
|
|
|
case OP_NEQUAL:
|
|
prlev(state, lev, "Op: !=");
|
|
break;
|
|
|
|
case OP_LESS:
|
|
prlev(state, lev, "Op: <");
|
|
break;
|
|
|
|
case OP_GREATER:
|
|
prlev(state, lev, "Op: >");
|
|
break;
|
|
|
|
case OP_LESSEQ:
|
|
prlev(state, lev, "Op: <=");
|
|
break;
|
|
|
|
case OP_GREATEREQ:
|
|
prlev(state, lev, "Op: >=");
|
|
break;
|
|
|
|
case OP_LSHIFT:
|
|
prlev(state, lev, "Op: <<");
|
|
break;
|
|
|
|
case OP_RSHIFT:
|
|
prlev(state, lev, "Op: >>");
|
|
break;
|
|
}
|
|
prlev(state, lev, "Left:");
|
|
prex(state, node->binop->left, lev + 1);
|
|
prlev(state, lev, "Right:");
|
|
prex(state, node->binop->right, lev + 1);
|
|
break;
|
|
|
|
case EX_UNOP:
|
|
prlev(state, lev, "UnOp:");
|
|
lev++;
|
|
switch(node->unop->type) {
|
|
case OP_NEG:
|
|
prlev(state, lev, "Op: -");
|
|
break;
|
|
|
|
case OP_BNOT:
|
|
prlev(state, lev, "Op: ~");
|
|
break;
|
|
|
|
case OP_LNOT:
|
|
prlev(state, lev, "Op: !");
|
|
break;
|
|
|
|
case OP_LEN:
|
|
prlev(state, lev, "Op: #");
|
|
break;
|
|
}
|
|
prlev(state, lev, "Expr:");
|
|
prex(state, node->unop->expr, lev + 1);
|
|
break;
|
|
|
|
case EX_INDEX:
|
|
prlev(state, lev, "Index:");
|
|
lev++;
|
|
prlev(state, lev, "Expr:");
|
|
prex(state, node->index->expr, lev + 1);
|
|
prlev(state, lev, "Index:");
|
|
prex(state, node->index->index, lev + 1);
|
|
break;
|
|
|
|
case EX_SETINDEX:
|
|
prlev(state, lev, "SetIndex:");
|
|
lev++;
|
|
prlev(state, lev, "Expr:");
|
|
prex(state, node->setindex->expr, lev + 1);
|
|
prlev(state, lev, "Index:");
|
|
prex(state, node->setindex->index, lev + 1);
|
|
prlev(state, lev, "Value:");
|
|
prex(state, node->setindex->value, lev + 1);
|
|
break;
|
|
|
|
case EX_ASSIGN:
|
|
prlev(state, lev, "Assign:");
|
|
lev++;
|
|
prlev(state, lev, "Ident: %s", node->assign->ident);
|
|
prlev(state, lev, "Value:");
|
|
prex(state, node->assign->value, lev + 1);
|
|
break;
|
|
|
|
case EX_REF:
|
|
prlev(state, lev, "Ref: %s", node->ref->ident);
|
|
break;
|
|
|
|
case EX_CALL:
|
|
prlev(state, lev, "Call:");
|
|
lev++;
|
|
prlev(state, lev, "Expr:");
|
|
prex(state, node->call->expr, lev + 1);
|
|
prlev(state, lev, "Args:");
|
|
cure = node->call->args;
|
|
while(cure && cure->expr) {
|
|
prex(state, cure->expr, lev + 1);
|
|
cure = cure->next;
|
|
}
|
|
break;
|
|
|
|
case EX_FUNCDECL:
|
|
prlev(state, lev, "FuncDecl:");
|
|
lev++;
|
|
prlev(state, lev, "Name: %s", node->funcdecl->name);
|
|
prlev(state, lev, "Args:");
|
|
curi = node->funcdecl->args;
|
|
while(curi && curi->ident) {
|
|
prlev(state, lev + 1, curi->ident);
|
|
curi = curi->next;
|
|
}
|
|
prlev(state, lev, "Body:");
|
|
prst(state, node->funcdecl->body, lev + 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void st_print(sol_state_t *state, stmt_node *stmt) {
|
|
prst(state, stmt, 0);
|
|
}
|
|
|
|
void ex_print(sol_state_t *state, expr_node *expr) {
|
|
prex(state, expr, 0);
|
|
}
|
|
|
|
/*int main(int argc, char **argv) {
|
|
stmt_node *program = NULL;
|
|
|
|
if(argc>1) yydebug = 1;
|
|
|
|
if(yyparse(&program)) {
|
|
printf("Syntax error (somewhere)\n");
|
|
printf("Partial tree:\n");
|
|
prst(state, program, 0);
|
|
return 1;
|
|
}
|
|
|
|
prst(state, program, 0);
|
|
return 0;
|
|
}*/
|
|
|