blob: 0b61c141872c797fa601e0674c9de82433dbaed2 [file] [log] [blame]
swissChilica107a02021-04-14 12:07:30 -07001#pragma once
2
3#include "lisp.h"
swissChilif3e7f182021-04-20 13:57:22 -07004#include <dasm_proto.h>
swissChilica107a02021-04-14 12:07:30 -07005#include <stdbool.h>
swissChilib3ca4fb2021-04-20 10:33:00 -07006#include <stdint.h>
swissChilica107a02021-04-14 12:07:30 -07007
swissChili2999dd12021-07-02 14:19:53 -07008enum namespace
9{
10 NS_FUNCTION,
11 NS_MACRO,
12};
13
swissChilica107a02021-04-14 12:07:30 -070014struct function
15{
16 char *name;
17 int nargs; // number of arguments
swissChili2999dd12021-07-02 14:19:53 -070018 enum namespace namespace;
swissChilica107a02021-04-14 12:07:30 -070019
swissChili2999dd12021-07-02 14:19:53 -070020 union
21 {
swissChili53472e82021-05-08 16:06:32 -070022 value_t (*def0)();
23 value_t (*def1)(value_t);
24 value_t (*def2)(value_t, value_t);
25 value_t (*def3)(value_t, value_t, value_t);
swissChilica107a02021-04-14 12:07:30 -070026 void *code_ptr;
swissChilif3e7f182021-04-20 13:57:22 -070027 uintptr_t code_addr;
swissChilica107a02021-04-14 12:07:30 -070028 };
29
30 struct function *prev;
31};
32
33struct environment
34{
35 struct function *first;
36};
37
swissChili923b5362021-05-09 20:31:43 -070038enum var_type
39{
40 V_BOUND, // Bound local variable
41 V_ARGUMENT, // Bound function argument
42 V_GLOBAL, // Global variable
43 V_FREE // Free (lexical) variable
44};
45
swissChilica107a02021-04-14 12:07:30 -070046struct variable
47{
48 char *name;
swissChili923b5362021-05-09 20:31:43 -070049 uintptr_t number;
50 enum var_type type;
swissChilica107a02021-04-14 12:07:30 -070051 struct variable *prev;
52};
53
swissChilif1ba8c12021-07-02 18:45:38 -070054/// Local environment
swissChilica107a02021-04-14 12:07:30 -070055struct local
56{
swissChilif1ba8c12021-07-02 18:45:38 -070057 /// Parent environment, NULL if none (root).
58 struct local *parent;
59
swissChilica107a02021-04-14 12:07:30 -070060 int num_vars;
swissChilif1ba8c12021-07-02 18:45:38 -070061 /// Most recently defined variable
swissChilica107a02021-04-14 12:07:30 -070062 struct variable *first;
swissChili53472e82021-05-08 16:06:32 -070063 int npc;
64 int nextpc;
swissChili67bdf282021-06-06 18:46:08 -070065 bool *stack_slots;
66 int num_stack_slots, num_stack_entries;
swissChilica107a02021-04-14 12:07:30 -070067};
68
swissChili53472e82021-05-08 16:06:32 -070069void compile_expression(struct environment *env, struct local *local,
70 value_t val, dasm_State **Dst);
swissChili6b47b6d2021-06-30 22:08:55 -070071
72/**
73 * Compile a backquoted expression
74 */
75void compile_backquote(struct environment *env, struct local *local,
76 value_t val, dasm_State **Dst);
77
swissChili53472e82021-05-08 16:06:32 -070078void compile_expr_to_func(struct environment *env, char *name, value_t val,
79 dasm_State **Dst);
swissChili6b47b6d2021-06-30 22:08:55 -070080
swissChili53472e82021-05-08 16:06:32 -070081int nextpc(struct local *local, dasm_State **Dst);
swissChili67bdf282021-06-06 18:46:08 -070082
83// Local utilities
84unsigned int local_alloc(struct local *local);
85void local_free(struct local *local, unsigned int slot);
86
swissChilif1ba8c12021-07-02 18:45:38 -070087/**
88 * Walk `body` and reserve space in `local` for any variable declarations.
89 */
swissChili67bdf282021-06-06 18:46:08 -070090void walk_and_alloc(struct local *local, value_t body);
swissChili8fc5e2f2021-04-22 13:45:10 -070091// Compile top-level declaration
swissChili53472e82021-05-08 16:06:32 -070092void compile_tl(value_t val, struct environment *env);
93struct environment compile_all(struct istream *is);
94struct function *find_function(struct environment *env, char *name);
swissChili923b5362021-05-09 20:31:43 -070095struct variable *add_variable(struct local *local, enum var_type type,
96 char *name, int number);
97// Might return null
98struct variable *find_variable(struct local *local, char *name);
99void destroy_local(struct local *local);
swissChili2999dd12021-07-02 14:19:53 -0700100
101/**
102 * Like `apply` in lisp, calls func with list args and returns the result.
103 */
104value_t call_list(struct function *func, value_t list);