shithub: lpa

ref: a062a0574fa9bbff7f3cb62251b41d42a441440f
dir: /util.c/

View raw version
#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;
		default:
			print("???");
			return;
		}
	}
	print("\n");
}

char *
funcname(Function *f)
{
	if(f->ast)
		return f->ast->funcname->name;
	else
		return primsymb(f->prim);
}