shithub: lpa

ref: da6308e5df8ed9cdf8d8f6cad73eef10f31ac4b0
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 int checkexpr(Ast *);

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

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

	TokenList *tokens = scan(buf, errp);
	if(tokens == nil)
		goto end;
	ast = parse(tokens, nil, errp);
	if(ast == nil)
		goto end;
	
	if(!(ast->tag == AstProg && ast->childcount == 1)){
		*errp = "Expected single value or function definition";
		goto end;
	}

	ast = ast->children[0];
	if(checkexpr(ast))
		val = eval(s, ast);
	else
		*errp = "Expected value or function definition";
end:
	return val;
}

static int
checkexpr(Ast *ast)
{
	switch(ast->tag){
	case AstConst:
	case AstFunc:
		return 1;
	case AstStrand:
		for(uvlong i = 0; i < ast->childcount; i++){
			if(!checkexpr(ast->children[i]))
				return 0;
		}
		return 1;
	default:
		return 0;
	}
}
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;
}