| /* -*- mode:c -*- */ |
| |
| #include "compiler.h" |
| |
| #include <dasm_proto.h> |
| #include <dasm_x86.h> |
| |
| #define value_size sizeof (struct value) |
| |
| |.arch x86; |
| |
| |.macro setup, nvars; |
| | push ebp; |
| | mov ebp, esp; |
| | sub esp, (value_size * nvars); |
| |.endmacro; |
| |
| |.macro cleanup; |
| | mov esp, ebp; |
| | pop ebp; |
| | ret; |
| |.endmacro; |
| |
| dasm_State *d; |
| unsigned int npc = 8; |
| |
| struct function *find_function (struct environment *env, char *name) |
| { |
| struct function *f = env->first; |
| |
| while ( strcmp (f->name, name) != 0 ) |
| { |
| if ( f->prev ) |
| f = f->prev; |
| else |
| return NULL; |
| } |
| |
| return f; |
| } |
| |
| void compile (struct istream *is) |
| { |
| |.section code; |
| dasm_init (&d, DASM_MAXSECTION); |
| |
| |.globals lbl_; |
| void *labels[ lbl__MAX ]; |
| dasm_setupglobal (&d, labels, lbl__MAX); |
| |
| |.actionlist lisp_actions; |
| dasm_setup (&d, lisp_actions); |
| |
| dasm_growpc (&d, npc); |
| } |
| |
| void compile_expression (struct environment *env, struct local *local, |
| value_t val, dasm_State **Dst) |
| { |
| if ( integerp (val) || stringp (val) || symbolp (val) ) |
| { |
| | mov eax, val; |
| } |
| else if ( listp (val) ) |
| { |
| value_t func = car (val); |
| if ( !symbolp (func) ) |
| err ("function name must be a symbol"); |
| |
| struct function *func = find_function (env, func ^ SYMBOL_TAG); |
| value_t args = cdr (val); |
| int nargs = length (args); |
| |
| if ( nargs != func->nargs ) |
| err ("wrong number of args"); |
| |
| for ( int i = length (args) - 1; i >= 0; i++ ) |
| { |
| compile_expression (env, local, elt (args, i), Dst); |
| | push eax; |
| } |
| |
| | call (func->code_addr); |
| | add esp, (nargs * 4); |
| // result in eax |
| } |
| } |