added 'ret' and implemented a proper 'strcmp'
This commit is contained in:
42
main.py
42
main.py
@@ -344,6 +344,7 @@ OP_LIST_BEGIN = 8
|
||||
OP_LIST_END = 9
|
||||
OP_LIST_LITERAL = 10
|
||||
OP_OTHER = 11
|
||||
OP_RET = 12
|
||||
|
||||
_OP_STR_TO_INT = {
|
||||
"word": OP_WORD,
|
||||
@@ -357,6 +358,7 @@ _OP_STR_TO_INT = {
|
||||
"list_begin": OP_LIST_BEGIN,
|
||||
"list_end": OP_LIST_END,
|
||||
"list_literal": OP_LIST_LITERAL,
|
||||
"ret": OP_RET,
|
||||
}
|
||||
|
||||
|
||||
@@ -1012,13 +1014,13 @@ class Parser:
|
||||
_KW_PY = 6
|
||||
_KW_EXTERN = 7
|
||||
_KW_PRIORITY = 8
|
||||
_KW_RET = 9
|
||||
_keyword_dispatch = {
|
||||
"[": _KW_LIST_BEGIN, "]": _KW_LIST_END, "word": _KW_WORD,
|
||||
"end": _KW_END, ":asm": _KW_ASM, ":py": _KW_PY,
|
||||
"extern": _KW_EXTERN, "priority": _KW_PRIORITY,
|
||||
"extern": _KW_EXTERN, "priority": _KW_PRIORITY, "ret": _KW_RET,
|
||||
}
|
||||
_kw_get = _keyword_dispatch.get
|
||||
|
||||
_tokens = self.tokens
|
||||
try:
|
||||
while self.pos < len(_tokens):
|
||||
@@ -1065,6 +1067,8 @@ class Parser:
|
||||
self._parse_extern(token)
|
||||
elif kw == _KW_PRIORITY:
|
||||
self._parse_priority_directive(token)
|
||||
elif kw == _KW_RET:
|
||||
self._handle_ret(token)
|
||||
continue
|
||||
if self._try_handle_builtin_control(token):
|
||||
continue
|
||||
@@ -1297,6 +1301,9 @@ class Parser:
|
||||
self._pending_priority = None
|
||||
return value
|
||||
|
||||
def _handle_ret(self, token: Token) -> None:
|
||||
self._append_op(_make_op("ret", loc=token))
|
||||
|
||||
# Internal helpers ---------------------------------------------------------
|
||||
|
||||
def _parse_extern(self, token: Token) -> None:
|
||||
@@ -3998,6 +4005,7 @@ class CompileTimeVM:
|
||||
_OP_JUMP = OP_JUMP
|
||||
_OP_LABEL = OP_LABEL
|
||||
_OP_LIST_BEGIN = OP_LIST_BEGIN
|
||||
_OP_RET = OP_RET
|
||||
_OP_LIST_END = OP_LIST_END
|
||||
_OP_LIST_LITERAL = OP_LIST_LITERAL
|
||||
try:
|
||||
@@ -4301,6 +4309,9 @@ class CompileTimeVM:
|
||||
ip += 1
|
||||
continue
|
||||
|
||||
if kind == _OP_RET:
|
||||
return
|
||||
|
||||
self.current_location = _node.loc
|
||||
raise ParseError(f"unsupported compile-time op (opcode={kind})")
|
||||
finally:
|
||||
@@ -4474,6 +4485,9 @@ class FunctionEmitter:
|
||||
_a(f" mov {register}, [r12]")
|
||||
_a(" add r12, 8")
|
||||
|
||||
def ret(self) -> None:
|
||||
self.text.append(" ret")
|
||||
|
||||
|
||||
def _int_trunc_div(lhs: int, rhs: int) -> int:
|
||||
if rhs == 0:
|
||||
@@ -6554,6 +6568,10 @@ class Assembler:
|
||||
builder.emit(" mov [r12], rax")
|
||||
return
|
||||
|
||||
if kind == OP_RET:
|
||||
builder.ret()
|
||||
return
|
||||
|
||||
raise CompileError(f"unsupported op {node!r} while emitting '{self._emit_stack[-1]}'" if self._emit_stack else f"unsupported op {node!r}")
|
||||
|
||||
def _emit_mmap_alloc(self, builder: FunctionEmitter, size: int, target_reg: str = "rax") -> None:
|
||||
@@ -10476,6 +10494,26 @@ def _run_docs_tui(
|
||||
" 3 1 syscall # 3 args, nr=1 (write)"
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "ret",
|
||||
"category": "Control Flow",
|
||||
"syntax": "ret",
|
||||
"summary": "Return from a word",
|
||||
"detail": (
|
||||
"Returns from a word.\n\n"
|
||||
"Example:\n"
|
||||
" word a\n"
|
||||
" \"g\" puts\n"
|
||||
" ret\n"
|
||||
" \"g\" puts\n"
|
||||
" end\n\n"
|
||||
" word main\n"
|
||||
" a\n"
|
||||
" end\n"
|
||||
"Output:\n"
|
||||
" g\n"
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "exit",
|
||||
"category": "System",
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
|
||||
#strcmp [*, addr, len, addr | len] -> [*, addr, len, addr, len | bool]
|
||||
#strcmp [*, addr, len, addr | len] -> [* | bool]
|
||||
word strcmp
|
||||
3 pick 2 pick @ swap @ ==
|
||||
>r nip r> for
|
||||
2dup c@ swap c@ != if drop drop 0 ret end
|
||||
1 + swap 1 +
|
||||
end
|
||||
drop drop 1
|
||||
end
|
||||
|
||||
#strconcat [*, addr, len, addr | len] -> [*, addr | len]
|
||||
|
||||
1
tests/ret_test.expected
Normal file
1
tests/ret_test.expected
Normal file
@@ -0,0 +1 @@
|
||||
g
|
||||
11
tests/ret_test.sl
Normal file
11
tests/ret_test.sl
Normal file
@@ -0,0 +1,11 @@
|
||||
import stdlib.sl
|
||||
|
||||
word g
|
||||
"g" puts
|
||||
ret
|
||||
"g" puts
|
||||
end
|
||||
|
||||
word main
|
||||
g
|
||||
end
|
||||
@@ -1,4 +1,3 @@
|
||||
1
|
||||
g
|
||||
g
|
||||
0
|
||||
hello world hello world hello world hello world hello world
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import stdlib.sl
|
||||
|
||||
word main
|
||||
"g" "g"
|
||||
"ggggggggh" "ggggggggh"
|
||||
strcmp
|
||||
puti cr
|
||||
|
||||
"ggggggggh" "ggggggggd"
|
||||
strcmp
|
||||
puti cr
|
||||
puts
|
||||
puts
|
||||
|
||||
"hello world hello world hello " "world hello world hello world"
|
||||
strconcat
|
||||
|
||||
Reference in New Issue
Block a user