Exemplo n.º 1
0
static Value* parseToken(const char** expr, parser_cb* cb) {
	Value* ret;
	
	char* token = nextToken(expr);
	if(token == NULL) {
		return ValErr(badChar(**expr));
	}
	
	trimSpaces(expr);
	if(**expr == '(') {
		(*expr)++;
		ArgList* arglist = ArgList_parse(expr, ',', ')', cb);
		if(arglist == NULL) {
			/* Parse error occurred and has already been raised */
			free(token);
			return ValErr(ignoreError());
		}
		
		ret = ValCall(FuncCall_create(token, arglist));
	}
	else {
		ret = ValVar(token);
	}
	
	free(token);
	return ret;
}
Exemplo n.º 2
0
static Value* eval_map(Context* ctx, ArgList* arglist) {
	if(arglist->count != 2) {
		return ValErr(builtinArgs("map", 2, arglist->count));
	}
	
	Value* func = Value_copy(arglist->args[0]);
	if(func->type != VAL_VAR) {
		Value* val = Value_eval(func, ctx);
		Value_free(func);
		
		if(val->type == VAL_ERR)
			return val;
		
		if(val->type != VAL_VAR) {
			Value_free(val);
			return ValErr(typeError("Builtin 'map' expects a callable as its first argument."));
		}
		
		func = val;
	}
	
	Value* vec = Value_eval(arglist->args[1], ctx);
	if(vec->type == VAL_ERR) {
		Value_free(func);
		return vec;
	}
	
	if(func->type != VAL_VAR) {
		Value_free(func);
		Value_free(vec);
		return ValErr(typeError("Builtin 'map' expects a callable as its first argument."));
	}
	
	if(vec->type != VAL_VEC) {
		Value_free(func);
		Value_free(vec);
		return ValErr(typeError("Builtin 'map' expects a vector as its second argument."));
	}
	
	ArgList* mapping = ArgList_new(vec->vec->vals->count);
	
	/* Don't evaluate the call now. Let Builtin_eval do this for us */
	unsigned i;
	for(i = 0; i < mapping->count; i++) {
		ArgList* arg = ArgList_create(1, Value_copy(vec->vec->vals->args[i]));
		Value* call = ValCall(FuncCall_new(func->name, arg));
		
		mapping->args[i] = call;
	}
	
	Value_free(func);
	Value_free(vec);
	
	return ValVec(Vector_new(mapping));
}
Exemplo n.º 3
0
Value* Value_copy(const Value* val) {
	Value* ret;
	
	switch(val->type) {
		case VAL_INT:
			ret = ValInt(val->ival);
			break;
		
		case VAL_REAL:
			ret = ValReal(val->rval);
			break;
		
		case VAL_FRAC:
			ret = ValFrac(Fraction_copy(val->frac));
			break;
		
		case VAL_EXPR:
			ret = ValExpr(BinOp_copy(val->expr));
			break;
		
		case VAL_CALL:
			ret = ValCall(FuncCall_copy(val->call));
			break;
		
		case VAL_UNARY:
			ret = ValUnary(UnOp_copy(val->term));
			break;
		
		case VAL_VAR:
			ret = ValVar(val->name);
			break;
		
		case VAL_VEC:
			ret = ValVec(Vector_copy(val->vec));
			break;
		
		case VAL_NEG:
			/* Shouldn't be reached, but so easy to code */
			ret = ValNeg();
			break;
		
		case VAL_ERR:
			ret = ValErr(Error_copy(val->err));
			break;
		
		default:
			typeError("Unknown value type: %d.", val->type);
			ret = NULL;
			break;
	}
	
	return ret;
}
Exemplo n.º 4
0
static Value* callFunc(Value* val, const char** expr, parser_cb* cb) {
	/* Ugly, but parses better. Only variables and the results of calls can be funcs */
	if(val->type != VAL_VAR && val->type != VAL_CALL && val->type != VAL_PLACE) {
		return val;
	}
	
	/* Move past the opening parenthesis */
	(*expr)++;
	
	ArgList* args = ArgList_parse(expr, ',', ')', cb);
	if(args == NULL) {
		Value_free(val);
		return ValErr(ignoreError());
	}
	
	return ValCall(FuncCall_new(val, args));
}