added compile time intrinsics that allow for modification of the prelude and bss section
This commit is contained in:
57
main.py
57
main.py
@@ -217,6 +217,8 @@ class AsmDefinition:
|
||||
class Module:
|
||||
forms: List[Any]
|
||||
variables: Dict[str, str] = field(default_factory=dict)
|
||||
prelude: Optional[List[str]] = None
|
||||
bss: Optional[List[str]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -351,6 +353,8 @@ class Parser:
|
||||
self.variable_words: Dict[str, str] = {}
|
||||
self.file_spans: List[FileSpan] = []
|
||||
self.compile_time_vm = CompileTimeVM(self)
|
||||
self.custom_prelude: Optional[List[str]] = None
|
||||
self.custom_bss: Optional[List[str]] = None
|
||||
|
||||
def location_for_token(self, token: Token) -> Tuple[str, int, int]:
|
||||
for span in self.file_spans:
|
||||
@@ -440,6 +444,8 @@ class Parser:
|
||||
self.label_counter = 0
|
||||
self.token_hook = None
|
||||
self._last_token = None
|
||||
self.custom_prelude = None
|
||||
self.custom_bss = None
|
||||
|
||||
while not self._eof():
|
||||
token = self._consume()
|
||||
@@ -505,6 +511,8 @@ class Parser:
|
||||
if not isinstance(module, Module): # pragma: no cover - defensive
|
||||
raise ParseError("internal parser state corrupt")
|
||||
module.variables = dict(self.variable_labels)
|
||||
module.prelude = self.custom_prelude
|
||||
module.bss = self.custom_bss
|
||||
return module
|
||||
|
||||
def _handle_list_begin(self) -> None:
|
||||
@@ -1602,7 +1610,8 @@ class Assembler:
|
||||
def emit(self, module: Module) -> Emission:
|
||||
emission = Emission()
|
||||
self._emit_externs(emission.text)
|
||||
emission.text.extend(self._runtime_prelude())
|
||||
prelude_lines = module.prelude if module.prelude is not None else self._runtime_prelude()
|
||||
emission.text.extend(prelude_lines)
|
||||
self._string_literals = {}
|
||||
self._float_literals = {}
|
||||
self._data_section = emission.data
|
||||
@@ -1636,7 +1645,8 @@ class Assembler:
|
||||
self._data_section.append("data_start:")
|
||||
if not self._data_section or self._data_section[-1] != "data_end:":
|
||||
self._data_section.append("data_end:")
|
||||
emission.bss.extend(self._bss_layout())
|
||||
bss_lines = module.bss if module.bss is not None else self._bss_layout()
|
||||
emission.bss.extend(bss_lines)
|
||||
self._data_section = None
|
||||
return emission
|
||||
|
||||
@@ -2432,6 +2442,42 @@ def _ct_list_push_front(vm: CompileTimeVM) -> None:
|
||||
vm.push(lst)
|
||||
|
||||
|
||||
def _ct_prelude_clear(vm: CompileTimeVM) -> None:
|
||||
vm.parser.custom_prelude = []
|
||||
|
||||
|
||||
def _ct_prelude_append(vm: CompileTimeVM) -> None:
|
||||
line = vm.pop_str()
|
||||
if vm.parser.custom_prelude is None:
|
||||
vm.parser.custom_prelude = []
|
||||
vm.parser.custom_prelude.append(line)
|
||||
|
||||
|
||||
def _ct_prelude_set(vm: CompileTimeVM) -> None:
|
||||
lines = _ensure_list(vm.pop())
|
||||
if not all(isinstance(item, str) for item in lines):
|
||||
raise ParseError("prelude-set expects list of strings")
|
||||
vm.parser.custom_prelude = list(lines)
|
||||
|
||||
|
||||
def _ct_bss_clear(vm: CompileTimeVM) -> None:
|
||||
vm.parser.custom_bss = []
|
||||
|
||||
|
||||
def _ct_bss_append(vm: CompileTimeVM) -> None:
|
||||
line = vm.pop_str()
|
||||
if vm.parser.custom_bss is None:
|
||||
vm.parser.custom_bss = []
|
||||
vm.parser.custom_bss.append(line)
|
||||
|
||||
|
||||
def _ct_bss_set(vm: CompileTimeVM) -> None:
|
||||
lines = _ensure_list(vm.pop())
|
||||
if not all(isinstance(item, str) for item in lines):
|
||||
raise ParseError("bss-set expects list of strings")
|
||||
vm.parser.custom_bss = list(lines)
|
||||
|
||||
|
||||
def _ct_list_reverse(vm: CompileTimeVM) -> None:
|
||||
lst = _ensure_list(vm.pop())
|
||||
lst.reverse()
|
||||
@@ -2774,6 +2820,13 @@ def _register_compile_time_primitives(dictionary: Dictionary) -> None:
|
||||
register("list-last", _ct_list_last, compile_only=True)
|
||||
register("i", _ct_loop_index, compile_only=True)
|
||||
|
||||
register("prelude-clear", _ct_prelude_clear, compile_only=True)
|
||||
register("prelude-append", _ct_prelude_append, compile_only=True)
|
||||
register("prelude-set", _ct_prelude_set, compile_only=True)
|
||||
register("bss-clear", _ct_bss_clear, compile_only=True)
|
||||
register("bss-append", _ct_bss_append, compile_only=True)
|
||||
register("bss-set", _ct_bss_set, compile_only=True)
|
||||
|
||||
register("map-new", _ct_map_new, compile_only=True)
|
||||
register("map-set", _ct_map_set, compile_only=True)
|
||||
register("map-get", _ct_map_get, compile_only=True)
|
||||
|
||||
1
tests/bss_override.expected
Normal file
1
tests/bss_override.expected
Normal file
@@ -0,0 +1 @@
|
||||
256
|
||||
38
tests/bss_override.sl
Normal file
38
tests/bss_override.sl
Normal file
@@ -0,0 +1,38 @@
|
||||
import stdlib/stdlib.sl
|
||||
import stdlib/io.sl
|
||||
|
||||
:asm persistent-size {
|
||||
lea rax, [rel persistent_end]
|
||||
lea rbx, [rel persistent]
|
||||
sub rax, rbx
|
||||
sub r12, 8
|
||||
mov [r12], rax
|
||||
}
|
||||
;
|
||||
|
||||
word ss
|
||||
# Override BSS to grow the persistent buffer.
|
||||
bss-clear
|
||||
"align 16" bss-append
|
||||
"dstack: resb DSTK_BYTES" bss-append
|
||||
"dstack_top:" bss-append
|
||||
"align 16" bss-append
|
||||
"rstack: resb RSTK_BYTES" bss-append
|
||||
"rstack_top:" bss-append
|
||||
"align 16" bss-append
|
||||
"print_buf: resb PRINT_BUF_BYTES" bss-append
|
||||
"print_buf_end:" bss-append
|
||||
"align 16" bss-append
|
||||
"persistent: resb 256" bss-append
|
||||
"persistent_end:" bss-append
|
||||
"align 16" bss-append
|
||||
"list_capture_sp: resq 1" bss-append
|
||||
"list_capture_tmp: resq 1" bss-append
|
||||
"list_capture_stack: resq 1024" bss-append
|
||||
end
|
||||
|
||||
word main
|
||||
persistent-size
|
||||
print
|
||||
end
|
||||
compile-time ss
|
||||
1
tests/bss_override.test
Normal file
1
tests/bss_override.test
Normal file
@@ -0,0 +1 @@
|
||||
python main.py tests/bss_override.sl -o /tmp/bss_override > /dev/null && /tmp/bss_override
|
||||
Reference in New Issue
Block a user