added compile time intrinsics that allow for modification of the prelude and bss section

This commit is contained in:
IgorCielniak
2026-01-09 12:22:00 +01:00
parent 0acf5555a8
commit c3490a37ae
4 changed files with 95 additions and 2 deletions

57
main.py
View File

@@ -217,6 +217,8 @@ class AsmDefinition:
class Module: class Module:
forms: List[Any] forms: List[Any]
variables: Dict[str, str] = field(default_factory=dict) variables: Dict[str, str] = field(default_factory=dict)
prelude: Optional[List[str]] = None
bss: Optional[List[str]] = None
@dataclass @dataclass
@@ -351,6 +353,8 @@ class Parser:
self.variable_words: Dict[str, str] = {} self.variable_words: Dict[str, str] = {}
self.file_spans: List[FileSpan] = [] self.file_spans: List[FileSpan] = []
self.compile_time_vm = CompileTimeVM(self) 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]: def location_for_token(self, token: Token) -> Tuple[str, int, int]:
for span in self.file_spans: for span in self.file_spans:
@@ -440,6 +444,8 @@ class Parser:
self.label_counter = 0 self.label_counter = 0
self.token_hook = None self.token_hook = None
self._last_token = None self._last_token = None
self.custom_prelude = None
self.custom_bss = None
while not self._eof(): while not self._eof():
token = self._consume() token = self._consume()
@@ -505,6 +511,8 @@ class Parser:
if not isinstance(module, Module): # pragma: no cover - defensive if not isinstance(module, Module): # pragma: no cover - defensive
raise ParseError("internal parser state corrupt") raise ParseError("internal parser state corrupt")
module.variables = dict(self.variable_labels) module.variables = dict(self.variable_labels)
module.prelude = self.custom_prelude
module.bss = self.custom_bss
return module return module
def _handle_list_begin(self) -> None: def _handle_list_begin(self) -> None:
@@ -1602,7 +1610,8 @@ class Assembler:
def emit(self, module: Module) -> Emission: def emit(self, module: Module) -> Emission:
emission = Emission() emission = Emission()
self._emit_externs(emission.text) 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._string_literals = {}
self._float_literals = {} self._float_literals = {}
self._data_section = emission.data self._data_section = emission.data
@@ -1636,7 +1645,8 @@ class Assembler:
self._data_section.append("data_start:") self._data_section.append("data_start:")
if not self._data_section or self._data_section[-1] != "data_end:": if not self._data_section or self._data_section[-1] != "data_end:":
self._data_section.append("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 self._data_section = None
return emission return emission
@@ -2432,6 +2442,42 @@ def _ct_list_push_front(vm: CompileTimeVM) -> None:
vm.push(lst) 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: def _ct_list_reverse(vm: CompileTimeVM) -> None:
lst = _ensure_list(vm.pop()) lst = _ensure_list(vm.pop())
lst.reverse() lst.reverse()
@@ -2774,6 +2820,13 @@ def _register_compile_time_primitives(dictionary: Dictionary) -> None:
register("list-last", _ct_list_last, compile_only=True) register("list-last", _ct_list_last, compile_only=True)
register("i", _ct_loop_index, 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-new", _ct_map_new, compile_only=True)
register("map-set", _ct_map_set, compile_only=True) register("map-set", _ct_map_set, compile_only=True)
register("map-get", _ct_map_get, compile_only=True) register("map-get", _ct_map_get, compile_only=True)

View File

@@ -0,0 +1 @@
256

38
tests/bss_override.sl Normal file
View 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
View File

@@ -0,0 +1 @@
python main.py tests/bss_override.sl -o /tmp/bss_override > /dev/null && /tmp/bss_override