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_END = 9
|
||||||
OP_LIST_LITERAL = 10
|
OP_LIST_LITERAL = 10
|
||||||
OP_OTHER = 11
|
OP_OTHER = 11
|
||||||
|
OP_RET = 12
|
||||||
|
|
||||||
_OP_STR_TO_INT = {
|
_OP_STR_TO_INT = {
|
||||||
"word": OP_WORD,
|
"word": OP_WORD,
|
||||||
@@ -357,6 +358,7 @@ _OP_STR_TO_INT = {
|
|||||||
"list_begin": OP_LIST_BEGIN,
|
"list_begin": OP_LIST_BEGIN,
|
||||||
"list_end": OP_LIST_END,
|
"list_end": OP_LIST_END,
|
||||||
"list_literal": OP_LIST_LITERAL,
|
"list_literal": OP_LIST_LITERAL,
|
||||||
|
"ret": OP_RET,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1012,13 +1014,13 @@ class Parser:
|
|||||||
_KW_PY = 6
|
_KW_PY = 6
|
||||||
_KW_EXTERN = 7
|
_KW_EXTERN = 7
|
||||||
_KW_PRIORITY = 8
|
_KW_PRIORITY = 8
|
||||||
|
_KW_RET = 9
|
||||||
_keyword_dispatch = {
|
_keyword_dispatch = {
|
||||||
"[": _KW_LIST_BEGIN, "]": _KW_LIST_END, "word": _KW_WORD,
|
"[": _KW_LIST_BEGIN, "]": _KW_LIST_END, "word": _KW_WORD,
|
||||||
"end": _KW_END, ":asm": _KW_ASM, ":py": _KW_PY,
|
"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
|
_kw_get = _keyword_dispatch.get
|
||||||
|
|
||||||
_tokens = self.tokens
|
_tokens = self.tokens
|
||||||
try:
|
try:
|
||||||
while self.pos < len(_tokens):
|
while self.pos < len(_tokens):
|
||||||
@@ -1065,6 +1067,8 @@ class Parser:
|
|||||||
self._parse_extern(token)
|
self._parse_extern(token)
|
||||||
elif kw == _KW_PRIORITY:
|
elif kw == _KW_PRIORITY:
|
||||||
self._parse_priority_directive(token)
|
self._parse_priority_directive(token)
|
||||||
|
elif kw == _KW_RET:
|
||||||
|
self._handle_ret(token)
|
||||||
continue
|
continue
|
||||||
if self._try_handle_builtin_control(token):
|
if self._try_handle_builtin_control(token):
|
||||||
continue
|
continue
|
||||||
@@ -1297,6 +1301,9 @@ class Parser:
|
|||||||
self._pending_priority = None
|
self._pending_priority = None
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def _handle_ret(self, token: Token) -> None:
|
||||||
|
self._append_op(_make_op("ret", loc=token))
|
||||||
|
|
||||||
# Internal helpers ---------------------------------------------------------
|
# Internal helpers ---------------------------------------------------------
|
||||||
|
|
||||||
def _parse_extern(self, token: Token) -> None:
|
def _parse_extern(self, token: Token) -> None:
|
||||||
@@ -3998,6 +4005,7 @@ class CompileTimeVM:
|
|||||||
_OP_JUMP = OP_JUMP
|
_OP_JUMP = OP_JUMP
|
||||||
_OP_LABEL = OP_LABEL
|
_OP_LABEL = OP_LABEL
|
||||||
_OP_LIST_BEGIN = OP_LIST_BEGIN
|
_OP_LIST_BEGIN = OP_LIST_BEGIN
|
||||||
|
_OP_RET = OP_RET
|
||||||
_OP_LIST_END = OP_LIST_END
|
_OP_LIST_END = OP_LIST_END
|
||||||
_OP_LIST_LITERAL = OP_LIST_LITERAL
|
_OP_LIST_LITERAL = OP_LIST_LITERAL
|
||||||
try:
|
try:
|
||||||
@@ -4301,6 +4309,9 @@ class CompileTimeVM:
|
|||||||
ip += 1
|
ip += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if kind == _OP_RET:
|
||||||
|
return
|
||||||
|
|
||||||
self.current_location = _node.loc
|
self.current_location = _node.loc
|
||||||
raise ParseError(f"unsupported compile-time op (opcode={kind})")
|
raise ParseError(f"unsupported compile-time op (opcode={kind})")
|
||||||
finally:
|
finally:
|
||||||
@@ -4474,6 +4485,9 @@ class FunctionEmitter:
|
|||||||
_a(f" mov {register}, [r12]")
|
_a(f" mov {register}, [r12]")
|
||||||
_a(" add r12, 8")
|
_a(" add r12, 8")
|
||||||
|
|
||||||
|
def ret(self) -> None:
|
||||||
|
self.text.append(" ret")
|
||||||
|
|
||||||
|
|
||||||
def _int_trunc_div(lhs: int, rhs: int) -> int:
|
def _int_trunc_div(lhs: int, rhs: int) -> int:
|
||||||
if rhs == 0:
|
if rhs == 0:
|
||||||
@@ -6554,6 +6568,10 @@ class Assembler:
|
|||||||
builder.emit(" mov [r12], rax")
|
builder.emit(" mov [r12], rax")
|
||||||
return
|
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}")
|
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:
|
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)"
|
" 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",
|
"name": "exit",
|
||||||
"category": "System",
|
"category": "System",
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
|
||||||
#strcmp [*, addr, len, addr | len] -> [*, addr, len, addr, len | bool]
|
#strcmp [*, addr, len, addr | len] -> [* | bool]
|
||||||
word strcmp
|
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
|
end
|
||||||
|
|
||||||
#strconcat [*, addr, len, addr | len] -> [*, addr | len]
|
#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
|
1
|
||||||
g
|
0
|
||||||
g
|
|
||||||
hello world hello world hello world hello world hello world
|
hello world hello world hello world hello world hello world
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import stdlib.sl
|
import stdlib.sl
|
||||||
|
|
||||||
word main
|
word main
|
||||||
"g" "g"
|
"ggggggggh" "ggggggggh"
|
||||||
|
strcmp
|
||||||
|
puti cr
|
||||||
|
|
||||||
|
"ggggggggh" "ggggggggd"
|
||||||
strcmp
|
strcmp
|
||||||
puti cr
|
puti cr
|
||||||
puts
|
|
||||||
puts
|
|
||||||
|
|
||||||
"hello world hello world hello " "world hello world hello world"
|
"hello world hello world hello " "world hello world hello world"
|
||||||
strconcat
|
strconcat
|
||||||
|
|||||||
Reference in New Issue
Block a user