ref: 2b23d05d57743af57385cd42c0fd2d223b11d8c8
dir: /util.c/
#include <u.h> #include <libc.h> #include <thread.h> #include "dat.h" #include "fns.h" Enumeration * allocenum(uvlong count) { Enumeration *e = alloc(DataEnumeration); setroot(e, 1); e->count = count; e->items = allocextra(e, sizeof(void *) * count); return e; } void trim(char *str) { for(int i = strlen(str)-1; i > 0; i--){ if(str[i] != '\n') break; else str[i] = 0; } } static void indent(int depth) { for(int i = 0; i < depth; i++) print(" "); } static void printchild(char *desc, Ast *ast, int depth) { indent(depth); print("%s:\n", desc); indent(depth+1); debugast(ast, depth+1); } void debugast(Ast *ast, int depth) { if(ast == nil){ print("<nil>\n"); return; } int printchildren = 0; switch(ast->tag){ case AstProg: print("prog\n"); printchildren = 1; break; case AstFunc: print("func\n"); depth++; printchild("name", ast->funcname, depth); printchild("result", ast->funcresult, depth); printchild("left arg", ast->funcleftarg, depth); printchild("right arg", ast->funcrightarg, depth); printchild("local vars", ast->funclocals, depth); indent(depth); print("body\n"); printchildren = 1; break; case AstName: print("\"%s\"\n", ast->name); break; case AstLocals: print("locals\n"); printchildren = 1; break; case AstAssign: print("assign\n"); printchild("name", ast->left, depth+1); printchild("value", ast->right, depth+1); break; case AstMonadic: print("monadic call\n"); printchild("func", ast->func, depth+1); printchild("right", ast->right, depth+1); break; case AstDyadic: print("dyadic call\n"); printchild("func", ast->func, depth+1); printchild("left", ast->left, depth+1); printchild("right", ast->right, depth+1); break; case AstConst: print("const:\n"); indent(depth+1); print("%s\n", printarray(ast->val)); break; case AstPrim: print("prim: %d\n", ast->prim); break; case AstStrand: print("strand\n"); printchildren = 1; break; default: print("<ast node %d>\n", ast->tag); break; } if(printchildren){ for(uvlong i = 0; i < ast->childcount; i++){ indent(depth+1); debugast(ast->children[i], depth+1); } } } int getuvlong(u8int *p, uvlong *vp) { int size = sizeof(uvlong); uvlong v = 0; for(int i = 0; i < size; i++){ uvlong x = *p; p++; v |= x << (8*i); } *vp = v; return size; } void debugbc(ByteCode *c) { uvlong o, v; o = 0; while(o < c->count){ int instr = c->instrs[o]; o++; switch(instr){ case IPushConst: o += getuvlong(c->instrs+o, &v); print("CONST %p\n", (void*)v); break; case IPushPrim: o += getuvlong(c->instrs+o, &v); print("PRIM %p\n", v); break; case ILookup: o += getuvlong(c->instrs+o, &v); print("LOOKUP %ulld\n", v); break; case IStrand: o += getuvlong(c->instrs+o, &v); print("STRAND %ulld\n", v); break; case INiladic: print("NILADIC CALL\n"); break; case IMonadic: print("MONADIC CALL\n"); break; case IDyadic: print("DYADIC CALL\n"); break; case IParse: o += getuvlong(c->instrs+o, &v); print("PARSE %ulld\n", v); break; case IReturn: print("RETURN\n"); break; case IAssign: o += getuvlong(c->instrs+o, &v); print("ASSIGN %ulld\n", v); break; case ILocal: o += getuvlong(c->instrs+o, &v); print("LOCAL %ulld\n", v); break; case IPop: print("POP\n"); break; case IDisplay: print("DISPLAY\n"); break; case IPushVar: o += getuvlong(c->instrs+o, &v); print("PUSHVAR %ulld\n", v); break; default: print("???"); return; } } print("\n"); } char * funcname(Function *f) { if(f->ast) return f->ast->funcname->name; else return primsymb(f->prim); }