shithub: lpa

ref: ecef9816dc8f772ca7f93cfcfe914759065e358f
dir: /value.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>

#include "dat.h"
#include "fns.h"

/* Anything that can have a name in LPA: Arrays, functions, ... */

static Array *evalconstast(Ast *);

char *
printval(void *v)
{
	int tag;
	if(v){
		tag = getalloctag(v);
		switch(tag){
		case DataArray:
			return smprint("%s\n", printarray(v));
		default:
			return smprint("some value of type %d\n", tag);
		}
	}else
		return smprint("no value :(\n");
}

void *
parseval(char *buf, char **errp)
{
	Ast *ast;
	void *val = nil;

	TokenList *tokens = scan(buf, errp);
	if(tokens == nil)
		goto end;
	ast = parse(tokens, errp);
	if(ast == nil)
		goto end;
	debugast(ast, 0);
	/* Check that the ast is either a single function definition,
	 * or a constant (stranding is OK).
	 */
	
	if(!(ast->tag == AstProg && ast->childcount == 1)){
		*errp = "Expected single value or function definition";
		goto end;
	}

	ast = ast->children[0];
	switch(ast->tag){
	case AstConst:
	case AstStrand:
		val = evalconstast(ast);
		if(val == nil)
			*errp = "Expected constant expression";
		break;
	case AstFunc:
		*errp = "Functions not supported yet";
		break;
	default:
		*errp = "Expected constant or function definition";
		break;
	}
end:
	return val;
}

static Array *
evalconstast(Ast *ast)
{
	Array *val;
	switch(ast->tag){
	case AstConst:
		val = ast->val;
		break;
	case AstStrand:
		val = allocarray(TypeArray, 1, ast->childcount);
		setshape(val, 0, ast->childcount);
		for(uvlong i = 0; i < ast->childcount; i++){
			Array *x = evalconstast(ast->children[i]);
			if(x)
				setarray(val, i, x);
			else{
				val = nil; /* abort */
				break;
			}
		}
		if(val)
			val = simplifyarray(val);
		break;
	default:
		val = nil;
	}
	return val;
}