/* parse symbols out of tokens */ int semanter_reduce(list_t *stack, list_t *partial) { size_t funcparams = 0; token_t *op; while ((op = (token_t*)list_pop(stack))) { switch (op->lexcomp) { /* binary operators */ case tokPlus : case tokMinus : case tokTimes : case tokDivide : case tokModulo : case tokPower : case tokUnaryMinus : case tokRShift : case tokLShift : case tokBitAnd : case tokBitOr : case tokBitXor : case tokBitNot : case tokAnd : case tokOr : case tokNot : case tokEq : case tokNe : case tokGt : case tokLt : case tokGe : case tokLe : list_push(partial, symbol_operator(op->lexcomp)); break; case tokNumber: list_push(partial, symbol_number(strtold(op->lexem, NULL))); break; case tokTrue: list_push(partial, symbol_number(1.0)); break; case tokFalse: list_push(partial, symbol_number(0.0)); break; case tokId: list_push(partial, symbol_variable(op->lexem)); break; case tokFunction: list_push(partial, symbol_function(op->lexem, funcparams)); break; /* ignore these, no semantic value */ case tokComma : case tokStackEmpty : case tokNoMatch : case tokCMango : case tokOParen : case tokCParen : case tokAsign : case tokText: break; case tokEMango: funcparams++; break; /* reduction done */ case tokOMango: return 0; } } return 0; }
LISPTR apply(LISPTR f, LISPTR args) { if (symbolp(f)) { // get the function binding of f f = symbol_function(f); if (consp(f)) { // function defined as S-expr if (car(f) == LAMBDA) { LISPTR oldBindings = lexvars; // bind formal arguments to evaluated actual arguments: lexvars = bind_args(cadr(f), args, lexvars); f = progn(cddr(f)); lexvars = oldBindings; } } else if (compiled_function_p(f)) { // call compiled function with args f = call_compiled_fn(f, args); } } return f; }