Ejemplo n.º 1
0
void eval_current(void)
{
	int tag;
	next_node();
	tag = tag_of(input);
	switch(tag)
	{
		case TAG_CD:
			eval_cd();
			break;
		case TAG_PRIMITIVE:
			((primitive*)input)->block();
			break;
		case TAG_SYMBOL:
			eval_symbol();
			break;
		case TAG_INT:
		case TAG_ARRAY:
		case TAG_STRING:
		case TAG_NIL:
		case TAG_CONTEXT:
			execute_waiter();
			break;
		case TAG_I_S:
			push(wait_stack,((inp_stub*)input)->func);
			break;
		default:
			printf("evaluated object of unknown tag:%i ",tag);
			break;
	}
	check_gc(0.5 KB);
}
Ejemplo n.º 2
0
VAL_LOC_T eval_dispatch(
    struct AstNode *node,
    struct Runtime *rt,
    struct SymMap *sym_map,
    struct AstLocMap *alm)
{
    /* It is possible that the debugger flag will change during evaluation. */
    bool debug_begin_called = false;

    VAL_LOC_T begin = rt->stack.top;

#if LOG_LEVEL <= LLVL_TRACE
    char *node_string = ast_serialize(node);
    LOG_TRACE("eval_impl BEGIN(%s)", node_string);
    mem_free(node_string);
#endif

    if (rt->debug) {
        dbg_call_begin(&rt->debugger, node);
        debug_begin_called = true;
    }

    switch (node->type) {
    case AST_SYMBOL:
        eval_symbol(node, rt, sym_map, alm);
        break;

    case AST_SPECIAL:
        eval_special(node, rt, sym_map, alm);
        break;

    case AST_FUNCTION_CALL:
        eval_func_call(node, rt, sym_map, alm);
        break;

    case AST_LITERAL_COMPOUND:
        eval_literal_compound(node, rt, sym_map, alm);
        break;

    case AST_LITERAL_ATOMIC:
        eval_literal_atomic(node, rt, sym_map, alm);
        break;
    }

    if (err_state()) {

        VAL_LOC_T ret_val = -1;
        if (debug_begin_called) {
            dbg_call_end(&rt->debugger, rt, ret_val, true);
        }

        err_push_src("EVAL", alm_try_get(alm, node), "Failed evaluating expression");
        LOG_TRACE("eval_impl END(error)");
        return ret_val;

    } else {

        if (debug_begin_called) {
            dbg_call_end(&rt->debugger, rt, begin, false);
        }

        LOG_TRACE("eval_impl END(result=%td)", begin);
        return begin;
    }
}
Ejemplo n.º 3
0
void eval_expression(const char ** source_begin, 
                     const char * source_end,
                     command_stack & command,
                     bool is_sub_expression)
{
    const char * start = *source_begin;
    
    if(is_sub_expression)
    {
        assert(*start == '(');
        start++;
    }
    
    std::size_t call_index = command.push_command();
    
    bool first_argument = true;
    
    for(const char * cursor = start; cursor != source_end; cursor++)
    {
        char c = *cursor;
        expression::token_id token_id = 
            expression::symbols[static_cast<std::size_t>(c)];
        
        switch(token_id)
        {
            case expression::WHITESPACE:
                // Do nothing
                break;
            case expression::END_EXPRESSION:
            {
                *source_begin = cursor;
                if(!is_sub_expression) throw_unexpected(')', "expression");
                command.call(call_index);
                return;
            }
            case expression::END_ROOT_EXPRESSION:
            {
                if(is_sub_expression)
                {
                    if(c == ';') throw_unexpected(';', "expression");
                    break; // Allow new lines in sub expressions
                }
                
                *source_begin = cursor + 1;
                command.call(call_index);
                return;
            }
            case expression::START_EXPRESSION:
            {
                eval_expression(&cursor, source_end, command, true);
                first_argument = false;
                break;
            }
            case expression::START_SYMBOL:
            {
                eval_symbol(&cursor, source_end, command);
                first_argument = false;
                break;
            }
            case expression::START_REFERENCE:
            {
                eval_reference(&cursor, source_end, command);
                first_argument = false;
                break;
            }
            case expression::START_END_STRING:
            {
                eval_string(&cursor, source_end, command);
                first_argument = false;
                break;
            }
            case expression::START_MULTILINE_STRING:
            {
                eval_multiline_string(&cursor, source_end, command);
                first_argument = false;
                break;
            }
            case expression::CHAR:
            {
                if(!first_argument) eval_word(&cursor, source_end, command);
                else eval_reference(&cursor, source_end, command);
                first_argument = false;
                break;
            }
            case expression::START_COMMENT:
            {
                eval_comment(&cursor, source_end, command);
                break;
            }
            case expression::ERROR:
            default:
                *source_begin = cursor;
                throw_unexpected(c, "expression");
        }
    }
    
    throw parse_incomplete();
}
Ejemplo n.º 4
0
obj eval(obj exp){
ev:	assert(!! exp);
    obj rr,lt, rt;
	switch (exp->type) {
	case tInd:
		return doInd(eval(ult(exp)), ul(eval(urt(exp))));
	case LIST:
		return List2v(evalList(ul(exp)));
	case tArray:
		return map_obj(eval, exp);
	case tAnd:
		return prod_eval(ul(exp), mult);
	case MULT:
		return prod_eval(ul(exp), mult);
	case ARITH:
		return prod_eval(ul(exp), add);
	case POW:
		return prod_eval(ul(exp), power);
	case DIVIDE:
		return prod_eval(ul(exp), divide);
	case tRef:
		return retain(uref(exp));
	case tSymbol:
		if( macromode) {
			if(obj rr = search_assoc(car(macro_env), exp)){
				macromode = false;
				// macro lexical scope should be pushed to the stack here
				rr = exec(rr);
				macromode = true;
				return rr;
			}
		}
		return eval_symbol(exp);
	case tMinus:
		lt = eval(uref(exp));
		rr = uMinus(lt);	// releasing
		if(rr) {release(lt); return rr;}
		static obj symumn = Symbol("-");
		rr = udef_op0(symumn, lt);
		if(rr) {release(lt); return rr;}
		error("uMinus: not defined to that type");
	case tReturn:
		if(! uref(exp)) return encap(tSigRet, nil);
		return  encap(tSigRet, eval(uref(exp)));
	case tBreak:
		return retain(exp);
	case CONDITION:
		return evalCond(exp);
	case tOp:
		if(type(ult(exp)) ==tSymbol) {
			lt = search_assoc(curr_interp->types, ult(exp));
			if(lt) return encap((ValueType)vrInt(lt), eval(urt(exp)));}
		lt = eval(ult(exp));
		push(lt);
		switch(lt->type){
		case tCont:
			assert(0);
		case tSpecial:
			rr = ufn(lt)(urt(exp));
			break;
		case tSyntaxLam:
			rr = macro_exec(lt, urt(exp));
			break;
		case tInternalFn:
        case tClosure:
			rt = eval(urt(exp));
			rr = eval_function(lt, rt);
			break;
        default:
			rt = eval(urt(exp));
			rr = call_fn(mult, lt, rt);
			release(rt);
		}
		release(pop(&is));
		return rr;
	case tClosure:
		assert(0);
	case tCurry:
		return eval_curry(exp, em0(exp));
/*		obj vars = Assoc();
		bind_vars(&vars, em0(exp), em2(exp));
		rr = eval_curry(exp, vars);
		release(vars);
		return rr;
*/	case tArrow:
//		return enclose(exp);
/*		if(macromode){
			if(obj rr = search_assoc(car(macro_env), exp)){
			}
		}
*/ 		return render(tClosure, list3(retain(em0(exp)), retain(em1(exp)), retain(env)));
	case tDefine:
		return func_def(em0(exp), em1(exp), em2(exp));
	case tSyntaxDef:
		let(lfind_var(em0(exp)),  render(tSyntaxLam, list3(retain(em1(exp)), retain(em2(exp)), nil)));
		return nil;
	case tExec:
		return exec(exp);
	case tAssign:
		lt = car(exp);
		if(type(lt)==tOp){
			return func_def(ult(lt), urt(lt), cdr(exp));
		} else if(type(lt)==tMinus){
			static obj symumn = Symbol("-");
			return func_def(symumn, uref(lt), cdr(exp));
		} else return do_assign(lt, eval(cdr(exp)));
	case tIf:
		rr = eval(em0(exp));
		if (type(rr) != INT) error("if: Boolean Expected");
		if (vrInt(rr)) {
			rr = em1(exp);
		} else {
			rr = em2(exp);
		}
		return eval(rr);
	case tWhile:
		for(;;) {
			rr = eval(car(exp));
			if (type(rr) != INT) error("while: Boolean expected");
			if(!vrInt(rr)) break;
			rr = exec(cdr(exp));
			if(rr && type(rr)==tSigRet) return rr;
			if(rr && type(rr)==tBreak) {release(rr); break;}
			if(rr) release(rr);
		}
		return nil;
	default:
		return retain(exp);
	}
}