4 ;; ------------------------------------------------------------
7 ;; These are lists of maps. The head of the list is the
8 ;; current environment, and CDR points to the outer environment
14 ;; Symbols used for comparison
15 static_symbol env_symbol
, '*env*'
17 ;; Error message strings
19 static env_binds_error_string
, db "Expecting symbol in binds list",10
20 static env_binds_missing_string
, db "Missing expression in bind",10
24 ;; Create a new Environment
26 ;; Input: outer Environment in RSI.
27 ;; - If zero, then nil outer.
28 ;; - If not zero, increments reference count
30 ;; Return a new Environment type in RAX
32 ;; Modifies registers:
36 call map_new
; map in RAX
38 call alloc_cons
; Cons in RAX
41 mov [rax
], BYTE (block_cons
+ container_list
+ content_pointer
)
42 ; CDR type already set to nil in alloc_cons
43 mov [rax
+ Cons.car
], rbx
47 ret ; No outer, just return
49 mov [rax
+ Cons.typecdr
], BYTE content_pointer
50 mov [rax
+ Cons.cdr
], rsi
52 ; increment reference counter of outer
53 mov rbx
, rax
; because incref_object modifies rax
58 ;; Create a new environment using a binding list
60 ;; Input: RSI - Outer environment
61 ;; RDI - Binds, a list of symbols
62 ;; RCX - Exprs, a list of values to bind each symbol to
73 mov r11
, rdi
; binds list in R11
74 mov r12
, rcx
; expr list in R12
77 mov r13
, rax
; New environment in R13
80 ; Check the type in the bind list
84 je .done
; No bindings
86 cmp bl, content_pointer
89 mov rdi
, [r11
+ Cons.car
] ; Symbol object?
91 cmp bl, maltype_symbol
94 ; RDI now contains a symbol
95 ; Check the type in expr
100 cmp bh, content_pointer
103 ; A value. Need to remove the container type
112 ; Restore original type
117 ; A pointer to something, so just pass address to env_set
118 mov rcx
, [r12
+ Cons.car
]
121 ; Fall through to next
123 ; Check if there is a next
124 mov bl, BYTE [r11
+ Cons.typecdr
]
125 cmp bl, content_pointer
129 mov r11
, [r11
+ Cons.cdr
] ; Next symbol
131 ; Check if there's an expression to bind to
132 mov bl, BYTE [r12
+ Cons.typecdr
]
133 cmp bl, content_pointer
134 jne .bind_missing_expr
136 mov r12
, [r12
+ Cons.cdr
] ; Next expression
142 .
bind_not_symbol: ; Expecting a symbol
143 push r11
; Binds list
145 ; Release the environment
149 print_str_mac error_string
; print 'Error: '
151 print_str_mac env_binds_error_string
153 pop rsi
; Throw binds list
157 push r11
; Binds list
159 ; Release the environment
163 print_str_mac error_string
; print 'Error: '
165 print_str_mac env_binds_missing_string
167 pop rsi
; Throw binds list
173 ;; Sets a key-value pair in an environment
175 ;; Inputs: RSI - env [not modified]
176 ;; RDI - key [not modified]
177 ;; RCX - value [not modified]
179 ;; Increments reference counts of key and value
180 ;; if pointers to them are created
182 ;; Modifies registers:
188 ; Get the first CAR, which should be a map
189 mov rsi
, [rsi
+ Cons.car
]
196 ;; Get a value from an environment, incrementing the reference count
197 ;; of the object returned
199 ;; Inputs: RSI - environment
202 ;; Returns: If found, Zero Flag is set and address in RAX
203 ;; If not found, Zero Flag cleared
207 ; Check special variable *env*
209 call compare_char_array
214 ; Env symbol, so return this environment
217 or ah, 64 ; set zero flag
225 mov rsi
, [rsi
+ Cons.car
]
230 ; Not found, so try outer
232 mov al, BYTE [rsi
+ Cons.typecdr
]
233 cmp al, content_pointer
236 mov rsi
, [rsi
+ Cons.cdr
] ; outer
243 and ah, 255-64 ; clear zero flag