blob: eac885ac6c0b37ba5e89a2b688492c30ca421748 [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
swissChili8fc5e2f2021-04-22 13:45:10 -070044void compile_tl (value_t val, struct environment *env)
swissChilica107a02021-04-14 12:07:30 -070045{
swissChili8fc5e2f2021-04-22 13:45:10 -070046 if ( !listp (val) )
47 err ("Top level must be a list");
48
49 value_t form = car (val);
50 value_t args = cdr (val);
swissChilica107a02021-04-14 12:07:30 -070051
swissChili8fc5e2f2021-04-22 13:45:10 -070052 if ( symstreq (form, "defun") )
53 {
54 dasm_State *d;
55 dasm_State **Dst = &d;
swissChilica107a02021-04-14 12:07:30 -070056
swissChili8fc5e2f2021-04-22 13:45:10 -070057 |.section code;
58 dasm_init (&d, DASM_MAXSECTION);
59
60 |.globals lbl_;
61 void *labels[ lbl__MAX ];
62 dasm_setupglobal (&d, labels, lbl__MAX);
63
64 |.actionlist lisp_actions;
65 dasm_setup (&d, lisp_actions);
66
67 dasm_growpc (&d, npc);
swissChilica107a02021-04-14 12:07:30 -070068
swissChili8fc5e2f2021-04-22 13:45:10 -070069 struct local local;
70 local.first = NULL;
71 local.num_vars = 0;
72
73 // Generate code
74
75 | setup 0;
76
77 value_t name = car (args);
78 args = cdr (args);
79 value_t arglist = car (args);
80 value_t body = cdr (args);
swissChilif3e7f182021-04-20 13:57:22 -070081
swissChili8fc5e2f2021-04-22 13:45:10 -070082 if ( (name & HEAP_MASK) != SYMBOL_TAG )
83 err ("function name must be a symbol");
84
85 for ( ; !nilp (body); body = cdr (body) )
86 {
87 compile_expression (env, &local, car (body), Dst);
88 }
89
90 | cleanup;
91
92 add_function (env, (char *) (name ^ SYMBOL_TAG), link (Dst), length (arglist));
93
94 dasm_free (&d);
95 }
96}
97
98struct environment compile_all (struct istream *is)
99{
100 value_t val;
swissChilif3e7f182021-04-20 13:57:22 -0700101 struct environment env;
102 env.first = NULL;
swissChilif3e7f182021-04-20 13:57:22 -0700103 load_std (&env);
swissChili8fc5e2f2021-04-22 13:45:10 -0700104
105 while ( read1 (is, &val) )
106 {
107 compile_tl (val, &env);
108 }
swissChilif3e7f182021-04-20 13:57:22 -0700109
swissChili8fc5e2f2021-04-22 13:45:10 -0700110 return env;
swissChilica107a02021-04-14 12:07:30 -0700111}
swissChilib3ca4fb2021-04-20 10:33:00 -0700112
113void compile_expression (struct environment *env, struct local *local,
114 value_t val, dasm_State **Dst)
115{
116 if ( integerp (val) || stringp (val) || symbolp (val) )
117 {
118 | mov eax, val;
119 }
120 else if ( listp (val) )
121 {
swissChilif3e7f182021-04-20 13:57:22 -0700122 value_t fsym = car (val);
swissChilib3ca4fb2021-04-20 10:33:00 -0700123
swissChilif3e7f182021-04-20 13:57:22 -0700124 if ( !symbolp (fsym) )
125 {
126 err ("function name must be a symbol");
127 }
128
129 struct function *func = find_function (env, (char *) (fsym ^ SYMBOL_TAG));
swissChilib3ca4fb2021-04-20 10:33:00 -0700130 value_t args = cdr (val);
131 int nargs = length (args);
132
133 if ( nargs != func->nargs )
134 err ("wrong number of args");
135
swissChilif3e7f182021-04-20 13:57:22 -0700136 for ( int i = length (args) - 1; i >= 0; i-- )
swissChilib3ca4fb2021-04-20 10:33:00 -0700137 {
138 compile_expression (env, local, elt (args, i), Dst);
139 | push eax;
140 }
141
swissChilif3e7f182021-04-20 13:57:22 -0700142 | mov ebx, (func->code_addr);
143 | call ebx;
swissChilib3ca4fb2021-04-20 10:33:00 -0700144 | add esp, (nargs * 4);
145 // result in eax
146 }
147}
swissChilif3e7f182021-04-20 13:57:22 -0700148
149void compile_expr_to_func (struct environment *env, char *name, value_t val,
150 dasm_State **Dst)
151{
152 | setup 0;
153
154 struct local local;
155 compile_expression (env, &local, val, Dst);
156
157 | cleanup;
158
159 add_function (env, name, link (Dst), 0);
160}