blob: 2594abd21974880c7416a835f807dcc0db02d80a [file] [log] [blame]
swissChili8cfb7c42021-04-18 21:17:58 -07001/* -*- mode:c -*- */
2
swissChilica107a02021-04-14 12:07:30 -07003#include "compiler.h"
swissChilif3e7f182021-04-20 13:57:22 -07004#include "plat/plat.h"
5#include "lib/std.h"
swissChilica107a02021-04-14 12:07:30 -07006
7#include <dasm_proto.h>
8#include <dasm_x86.h>
9
swissChilif3e7f182021-04-20 13:57:22 -070010#define value_size sizeof (value_t)
swissChilica107a02021-04-14 12:07:30 -070011
12|.arch x86;
13
14|.macro setup, nvars;
15| push ebp;
16| mov ebp, esp;
swissChili8cfb7c42021-04-18 21:17:58 -070017| sub esp, (value_size * nvars);
swissChilica107a02021-04-14 12:07:30 -070018|.endmacro;
19
20|.macro cleanup;
21| mov esp, ebp;
22| pop ebp;
23| ret;
24|.endmacro;
25
26dasm_State *d;
27unsigned int npc = 8;
28
29struct function *find_function (struct environment *env, char *name)
30{
31 struct function *f = env->first;
32
33 while ( strcmp (f->name, name) != 0 )
34 {
35 if ( f->prev )
36 f = f->prev;
37 else
38 return NULL;
39 }
40
41 return f;
42}
43
swissChilif3e7f182021-04-20 13:57:22 -070044void compile (value_t val)
swissChilica107a02021-04-14 12:07:30 -070045{
46 |.section code;
47 dasm_init (&d, DASM_MAXSECTION);
48
49 |.globals lbl_;
50 void *labels[ lbl__MAX ];
51 dasm_setupglobal (&d, labels, lbl__MAX);
52
53 |.actionlist lisp_actions;
54 dasm_setup (&d, lisp_actions);
55
56 dasm_growpc (&d, npc);
swissChilif3e7f182021-04-20 13:57:22 -070057
58 struct environment env;
59 env.first = NULL;
60 char *name = "main";
61 load_std (&env);
62
63 printval (val, 0);
64 compile_expr_to_func (&env, name, val, &d);
65
66 value_t (*fun)() = find_function (&env, name)->def0;
67 printval (fun (), 0);
swissChilica107a02021-04-14 12:07:30 -070068}
swissChilib3ca4fb2021-04-20 10:33:00 -070069
70void compile_expression (struct environment *env, struct local *local,
71 value_t val, dasm_State **Dst)
72{
73 if ( integerp (val) || stringp (val) || symbolp (val) )
74 {
75 | mov eax, val;
76 }
77 else if ( listp (val) )
78 {
swissChilif3e7f182021-04-20 13:57:22 -070079 value_t fsym = car (val);
swissChilib3ca4fb2021-04-20 10:33:00 -070080
swissChilif3e7f182021-04-20 13:57:22 -070081 if ( !symbolp (fsym) )
82 {
83 err ("function name must be a symbol");
84 }
85
86 struct function *func = find_function (env, (char *) (fsym ^ SYMBOL_TAG));
swissChilib3ca4fb2021-04-20 10:33:00 -070087 value_t args = cdr (val);
88 int nargs = length (args);
89
90 if ( nargs != func->nargs )
91 err ("wrong number of args");
92
swissChilif3e7f182021-04-20 13:57:22 -070093 for ( int i = length (args) - 1; i >= 0; i-- )
swissChilib3ca4fb2021-04-20 10:33:00 -070094 {
95 compile_expression (env, local, elt (args, i), Dst);
96 | push eax;
97 }
98
swissChilif3e7f182021-04-20 13:57:22 -070099 | mov ebx, (func->code_addr);
100 | call ebx;
swissChilib3ca4fb2021-04-20 10:33:00 -0700101 | add esp, (nargs * 4);
102 // result in eax
103 }
104}
swissChilif3e7f182021-04-20 13:57:22 -0700105
106void compile_expr_to_func (struct environment *env, char *name, value_t val,
107 dasm_State **Dst)
108{
109 | setup 0;
110
111 struct local local;
112 compile_expression (env, &local, val, Dst);
113
114 | cleanup;
115
116 add_function (env, name, link (Dst), 0);
117}