unified the block endings
This commit is contained in:
9
aa.sl
Normal file
9
aa.sl
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import stdlib/stdlib.sl
|
||||||
|
import stdlib/io.sl
|
||||||
|
|
||||||
|
: main
|
||||||
|
mem 5 swap !
|
||||||
|
mem 8 + 6 swap !
|
||||||
|
mem @ puti cr
|
||||||
|
mem 8 + @ puti cr
|
||||||
|
;
|
||||||
4
fib.sl
4
fib.sl
@@ -9,7 +9,7 @@ import stdlib/io.sl
|
|||||||
22 dup >r for
|
22 dup >r for
|
||||||
2dup + dup puti cr
|
2dup + dup puti cr
|
||||||
rot
|
rot
|
||||||
next
|
end
|
||||||
"-------" puts
|
"-------" puts
|
||||||
r> 3 + puti
|
r> 3 + puti
|
||||||
" numbers printed from the fibonaci sequence" puts
|
" numbers printed from the fibonaci sequence" puts
|
||||||
@@ -19,6 +19,6 @@ import stdlib/io.sl
|
|||||||
1 2 while over 100 < do
|
1 2 while over 100 < do
|
||||||
over puti cr
|
over puti cr
|
||||||
swap over +
|
swap over +
|
||||||
repeat
|
end
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
80
fn.sl
80
fn.sl
@@ -1,14 +1,14 @@
|
|||||||
: call-syntax-rewrite # ( fnameToken -- handled )
|
: call-syntax-rewrite # ( fnameToken -- handled )
|
||||||
dup token-lexeme identifier? 0 == if drop 0 exit then
|
dup token-lexeme identifier? 0 == if drop 0 exit end
|
||||||
peek-token dup nil? if drop drop 0 exit then
|
peek-token dup nil? if drop drop 0 exit end
|
||||||
dup token-lexeme "(" string= 0 == if drop drop 0 exit then
|
dup token-lexeme "(" string= 0 == if drop drop 0 exit end
|
||||||
swap >r # stash fnameTok
|
swap >r # stash fnameTok
|
||||||
drop # discard peeked '('
|
drop # discard peeked '('
|
||||||
next-token drop # consume '('
|
next-token drop # consume '('
|
||||||
list-new # out
|
list-new # out
|
||||||
list-new # out cur
|
list-new # out cur
|
||||||
begin
|
begin
|
||||||
next-token dup nil? if "unterminated call expression" parse-error then
|
next-token dup nil? if "unterminated call expression" parse-error end
|
||||||
dup token-lexeme ")" string= if
|
dup token-lexeme ")" string= if
|
||||||
drop
|
drop
|
||||||
# flush current arg
|
# flush current arg
|
||||||
@@ -16,13 +16,13 @@ begin
|
|||||||
r> list-append # out''
|
r> list-append # out''
|
||||||
inject-tokens
|
inject-tokens
|
||||||
1 exit
|
1 exit
|
||||||
then
|
end
|
||||||
dup token-lexeme "," string= if
|
dup token-lexeme "," string= if
|
||||||
drop
|
drop
|
||||||
list-extend # out'
|
list-extend # out'
|
||||||
list-new # out' cur
|
list-new # out' cur
|
||||||
continue
|
continue
|
||||||
then
|
end
|
||||||
# default: append tok to cur
|
# default: append tok to cur
|
||||||
list-append
|
list-append
|
||||||
again
|
again
|
||||||
@@ -39,11 +39,11 @@ compile-only
|
|||||||
|
|
||||||
|
|
||||||
: fn-op-prec
|
: fn-op-prec
|
||||||
dup "+" string= if drop 1 exit then
|
dup "+" string= if drop 1 exit end
|
||||||
dup "-" string= if drop 1 exit then
|
dup "-" string= if drop 1 exit end
|
||||||
dup "*" string= if drop 2 exit then
|
dup "*" string= if drop 2 exit end
|
||||||
dup "/" string= if drop 2 exit then
|
dup "/" string= if drop 2 exit end
|
||||||
dup "%" string= if drop 2 exit then
|
dup "%" string= if drop 2 exit end
|
||||||
drop 0
|
drop 0
|
||||||
;
|
;
|
||||||
compile-only
|
compile-only
|
||||||
@@ -59,10 +59,10 @@ compile-only
|
|||||||
begin
|
begin
|
||||||
over list-length swap >= if # params flag
|
over list-length swap >= if # params flag
|
||||||
r> exit
|
r> exit
|
||||||
then
|
end
|
||||||
dup >r # params idx (r: idx name)
|
dup >r # params idx (r: idx name)
|
||||||
over swap list-get # params elem
|
over swap list-get # params elem
|
||||||
1 rpick string= if "duplicate parameter names in fn definition" parse-error then
|
1 rpick string= if "duplicate parameter names in fn definition" parse-error end
|
||||||
drop # drop comparison flag when no error
|
drop # drop comparison flag when no error
|
||||||
r> 1 + # params idx+1
|
r> 1 + # params idx+1
|
||||||
again
|
again
|
||||||
@@ -76,18 +76,18 @@ compile-only
|
|||||||
begin
|
begin
|
||||||
0 rpick lexer-pop token-lexeme # params lex
|
0 rpick lexer-pop token-lexeme # params lex
|
||||||
swap drop # params lex (drop returned lexer)
|
swap drop # params lex (drop returned lexer)
|
||||||
dup ")" string= if drop r> exit then
|
dup ")" string= if drop r> exit end
|
||||||
dup "int" string= 0 == if "only 'int' parameters are supported in fn definitions" parse-error then
|
dup "int" string= 0 == if "only 'int' parameters are supported in fn definitions" parse-error end
|
||||||
drop # params
|
drop # params
|
||||||
0 rpick lexer-pop token-lexeme # params lexer pname
|
0 rpick lexer-pop token-lexeme # params lexer pname
|
||||||
swap drop # params pname
|
swap drop # params pname
|
||||||
dup identifier? 0 == if "invalid parameter name in fn definition" parse-error then
|
dup identifier? 0 == if "invalid parameter name in fn definition" parse-error end
|
||||||
fn-check-dup # params pname
|
fn-check-dup # params pname
|
||||||
list-append # params
|
list-append # params
|
||||||
0 rpick lexer-pop token-lexeme # params lexer sep
|
0 rpick lexer-pop token-lexeme # params lexer sep
|
||||||
swap drop # params sep
|
swap drop # params sep
|
||||||
dup "," string= if drop continue then
|
dup "," string= if drop continue end
|
||||||
dup ")" string= if drop r> exit then
|
dup ")" string= if drop r> exit end
|
||||||
"expected ',' or ')' in parameter list" parse-error
|
"expected ',' or ')' in parameter list" parse-error
|
||||||
again
|
again
|
||||||
;
|
;
|
||||||
@@ -106,7 +106,7 @@ compile-only
|
|||||||
begin
|
begin
|
||||||
0 rpick list-empty? if
|
0 rpick list-empty? if
|
||||||
rdrop exit
|
rdrop exit
|
||||||
then
|
end
|
||||||
0 rpick list-pop-front # acc tokens' first
|
0 rpick list-pop-front # acc tokens' first
|
||||||
rdrop # acc tokens'
|
rdrop # acc tokens'
|
||||||
swap # acc first tokens'
|
swap # acc first tokens'
|
||||||
@@ -118,13 +118,13 @@ again
|
|||||||
compile-only
|
compile-only
|
||||||
|
|
||||||
: fn-validate-body
|
: fn-validate-body
|
||||||
dup list-length 0 == if "empty function body" parse-error then
|
dup list-length 0 == if "empty function body" parse-error end
|
||||||
dup 0 list-get token-lexeme "return" string= 0 == if "function body must start with 'return'" parse-error then
|
dup 0 list-get token-lexeme "return" string= 0 == if "function body must start with 'return'" parse-error end
|
||||||
dup list-last ";" string= 0 == if "function body must terminate with ';'" parse-error then
|
dup list-last ";" string= 0 == if "function body must terminate with ';'" parse-error end
|
||||||
list-clone # body body'
|
list-clone # body body'
|
||||||
list-pop drop # body expr' (trim trailing ';')
|
list-pop drop # body expr' (trim trailing ';')
|
||||||
list-pop-front drop # body expr (trim leading 'return')
|
list-pop-front drop # body expr (trim leading 'return')
|
||||||
dup list-length 0 == if "missing return expression" parse-error then
|
dup list-length 0 == if "missing return expression" parse-error end
|
||||||
;
|
;
|
||||||
compile-only
|
compile-only
|
||||||
|
|
||||||
@@ -135,19 +135,19 @@ begin
|
|||||||
dup list-empty? if
|
dup list-empty? if
|
||||||
drop # out
|
drop # out
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
list-pop-front # out body' tok
|
list-pop-front # out body' tok
|
||||||
swap >r # out tok (r: body')
|
swap >r # out tok (r: body')
|
||||||
dup "return" string= if
|
dup "return" string= if
|
||||||
drop
|
drop
|
||||||
r>
|
r>
|
||||||
continue
|
continue
|
||||||
then
|
end
|
||||||
dup ";" string= if
|
dup ";" string= if
|
||||||
drop
|
drop
|
||||||
r>
|
r>
|
||||||
continue
|
continue
|
||||||
then
|
end
|
||||||
list-append # out'
|
list-append # out'
|
||||||
r> # out' body'
|
r> # out' body'
|
||||||
continue
|
continue
|
||||||
@@ -157,14 +157,14 @@ compile-only
|
|||||||
|
|
||||||
|
|
||||||
: fn-body->tokens # bodyLexemes -- tokens
|
: fn-body->tokens # bodyLexemes -- tokens
|
||||||
dup list-length 0 == if "empty function body" parse-error then
|
dup list-length 0 == if "empty function body" parse-error end
|
||||||
dup 0 list-get token-lexeme "return" string= if
|
dup 0 list-get token-lexeme "return" string= if
|
||||||
fn-validate-body # expr
|
fn-validate-body # expr
|
||||||
shunt # postfix
|
shunt # postfix
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
fn-filter-raw-body
|
fn-filter-raw-body
|
||||||
dup list-length 0 == if "empty function body" parse-error then
|
dup list-length 0 == if "empty function body" parse-error end
|
||||||
;
|
;
|
||||||
compile-only
|
compile-only
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ begin
|
|||||||
">r" list-append # params out'
|
">r" list-append # params out'
|
||||||
r> # params out' n-1
|
r> # params out' n-1
|
||||||
continue
|
continue
|
||||||
then
|
end
|
||||||
drop # params out
|
drop # params out
|
||||||
exit
|
exit
|
||||||
again
|
again
|
||||||
@@ -191,7 +191,7 @@ begin
|
|||||||
1 - >r
|
1 - >r
|
||||||
"rdrop" list-append
|
"rdrop" list-append
|
||||||
continue
|
continue
|
||||||
then
|
end
|
||||||
drop # drop counter
|
drop # drop counter
|
||||||
swap drop # out
|
swap drop # out
|
||||||
exit
|
exit
|
||||||
@@ -204,7 +204,7 @@ compile-only
|
|||||||
1 -
|
1 -
|
||||||
0 rpick ">r" list-append drop
|
0 rpick ">r" list-append drop
|
||||||
fn-translate-prologue-loop
|
fn-translate-prologue-loop
|
||||||
then
|
end
|
||||||
drop
|
drop
|
||||||
;
|
;
|
||||||
compile-only
|
compile-only
|
||||||
@@ -214,7 +214,7 @@ compile-only
|
|||||||
1 -
|
1 -
|
||||||
0 rpick "rdrop" list-append drop
|
0 rpick "rdrop" list-append drop
|
||||||
fn-translate-epilogue-loop
|
fn-translate-epilogue-loop
|
||||||
then
|
end
|
||||||
drop
|
drop
|
||||||
;
|
;
|
||||||
compile-only
|
compile-only
|
||||||
@@ -228,13 +228,13 @@ begin
|
|||||||
drop # params
|
drop # params
|
||||||
r> drop # drop name
|
r> drop # drop name
|
||||||
-1 0 exit # params -1 0
|
-1 0 exit # params -1 0
|
||||||
then # params idx
|
end # params idx
|
||||||
over over list-get # params idx elem
|
over over list-get # params idx elem
|
||||||
0 rpick string= # params idx flag
|
0 rpick string= # params idx flag
|
||||||
if
|
if
|
||||||
r> drop # drop name
|
r> drop # drop name
|
||||||
1 exit # params idx 1
|
1 exit # params idx 1
|
||||||
then
|
end
|
||||||
drop # params idx
|
drop # params idx
|
||||||
1 + # params idx+1
|
1 + # params idx+1
|
||||||
again
|
again
|
||||||
@@ -250,7 +250,7 @@ compile-only
|
|||||||
over swap >= if # params map idx flag
|
over swap >= if # params map idx flag
|
||||||
drop # params map
|
drop # params map
|
||||||
exit
|
exit
|
||||||
then # params map idx
|
end # params map idx
|
||||||
2 pick over list-get # params map idx name
|
2 pick over list-get # params map idx name
|
||||||
swap # params map name idx
|
swap # params map name idx
|
||||||
dup >r # params map name idx (r: idx)
|
dup >r # params map name idx (r: idx)
|
||||||
@@ -274,7 +274,7 @@ compile-only
|
|||||||
list-append # out'
|
list-append # out'
|
||||||
r> # out' map
|
r> # out' map
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
drop # out map tok
|
drop # out map tok
|
||||||
|
|
||||||
# param?
|
# param?
|
||||||
@@ -292,7 +292,7 @@ compile-only
|
|||||||
# drop saved tok
|
# drop saved tok
|
||||||
r> drop # out'' map
|
r> drop # out'' map
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
# not a param: drop idx|nil, append original tok
|
# not a param: drop idx|nil, append original tok
|
||||||
drop # out map
|
drop # out map
|
||||||
r> # out map tok
|
r> # out map tok
|
||||||
@@ -308,7 +308,7 @@ compile-only
|
|||||||
dup list-empty? if
|
dup list-empty? if
|
||||||
drop
|
drop
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
list-pop-front # map out postfix' tok
|
list-pop-front # map out postfix' tok
|
||||||
swap >r # map out tok (r: postfix')
|
swap >r # map out tok (r: postfix')
|
||||||
>r swap r> # out map tok (r: postfix')
|
>r swap r> # out map tok (r: postfix')
|
||||||
@@ -354,7 +354,7 @@ compile-only
|
|||||||
dup lexer-pop # lexer nameTok
|
dup lexer-pop # lexer nameTok
|
||||||
dup >r # save nameTok
|
dup >r # save nameTok
|
||||||
token-lexeme # lexer name
|
token-lexeme # lexer name
|
||||||
dup identifier? 0 == if "invalid function name for 'fn'" parse-error then
|
dup identifier? 0 == if "invalid function name for 'fn'" parse-error end
|
||||||
>r # save name string
|
>r # save name string
|
||||||
drop # leave lexer only for params
|
drop # leave lexer only for params
|
||||||
"(" lexer-expect drop # consume '(' keep lexer
|
"(" lexer-expect drop # consume '(' keep lexer
|
||||||
|
|||||||
61
main.py
61
main.py
@@ -258,7 +258,7 @@ class ForBegin(ASTNode):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ForNext(ASTNode):
|
class ForEnd(ASTNode):
|
||||||
loop_label: str
|
loop_label: str
|
||||||
end_label: str
|
end_label: str
|
||||||
|
|
||||||
@@ -396,6 +396,29 @@ class Parser:
|
|||||||
def most_recent_definition(self) -> Optional[Word]:
|
def most_recent_definition(self) -> Optional[Word]:
|
||||||
return self.last_defined
|
return self.last_defined
|
||||||
|
|
||||||
|
def _handle_end_control(self) -> None:
|
||||||
|
"""Handle unified 'end' for all block types"""
|
||||||
|
if not self.control_stack:
|
||||||
|
raise ParseError("unexpected 'end' without matching block")
|
||||||
|
|
||||||
|
entry = self.control_stack.pop()
|
||||||
|
|
||||||
|
if entry["type"] == "if":
|
||||||
|
# For if without else
|
||||||
|
if "false" in entry:
|
||||||
|
self._append_node(Label(name=entry["false"]))
|
||||||
|
elif entry["type"] == "else":
|
||||||
|
self._append_node(Label(name=entry["end"]))
|
||||||
|
elif entry["type"] == "while":
|
||||||
|
self._append_node(Jump(target=entry["begin"]))
|
||||||
|
self._append_node(Label(name=entry["end"]))
|
||||||
|
elif entry["type"] == "for":
|
||||||
|
# Emit ForEnd node for loop decrement
|
||||||
|
self._append_node(ForEnd(loop_label=entry["loop"], end_label=entry["end"]))
|
||||||
|
elif entry["type"] == "begin":
|
||||||
|
self._append_node(Jump(target=entry["begin"]))
|
||||||
|
self._append_node(Label(name=entry["end"]))
|
||||||
|
|
||||||
# Parsing ------------------------------------------------------------------
|
# Parsing ------------------------------------------------------------------
|
||||||
def parse(self, tokens: Iterable[Token], source: str) -> Module:
|
def parse(self, tokens: Iterable[Token], source: str) -> Module:
|
||||||
self.tokens = []
|
self.tokens = []
|
||||||
@@ -440,23 +463,17 @@ class Parser:
|
|||||||
if lexeme == "else":
|
if lexeme == "else":
|
||||||
self._handle_else_control()
|
self._handle_else_control()
|
||||||
continue
|
continue
|
||||||
if lexeme == "then":
|
|
||||||
self._handle_then_control()
|
|
||||||
continue
|
|
||||||
if lexeme == "for":
|
if lexeme == "for":
|
||||||
self._handle_for_control()
|
self._handle_for_control()
|
||||||
continue
|
continue
|
||||||
if lexeme == "next":
|
|
||||||
self._handle_next_control()
|
|
||||||
continue
|
|
||||||
if lexeme == "while":
|
if lexeme == "while":
|
||||||
self._handle_while_control()
|
self._handle_while_control()
|
||||||
continue
|
continue
|
||||||
if lexeme == "do":
|
if lexeme == "do":
|
||||||
self._handle_do_control()
|
self._handle_do_control()
|
||||||
continue
|
continue
|
||||||
if lexeme == "repeat":
|
if lexeme == "end":
|
||||||
self._handle_repeat_control()
|
self._handle_end_control()
|
||||||
continue
|
continue
|
||||||
if self._maybe_expand_macro(token):
|
if self._maybe_expand_macro(token):
|
||||||
continue
|
continue
|
||||||
@@ -714,23 +731,12 @@ class Parser:
|
|||||||
self._append_node(Label(name=entry["false"]))
|
self._append_node(Label(name=entry["false"]))
|
||||||
self._push_control({"type": "else", "end": end_label})
|
self._push_control({"type": "else", "end": end_label})
|
||||||
|
|
||||||
def _handle_then_control(self) -> None:
|
|
||||||
entry = self._pop_control(("if", "else"))
|
|
||||||
if entry["type"] == "if":
|
|
||||||
self._append_node(Label(name=entry["false"]))
|
|
||||||
else:
|
|
||||||
self._append_node(Label(name=entry["end"]))
|
|
||||||
|
|
||||||
def _handle_for_control(self) -> None:
|
def _handle_for_control(self) -> None:
|
||||||
loop_label = self._new_label("for_loop")
|
loop_label = self._new_label("for_loop")
|
||||||
end_label = self._new_label("for_end")
|
end_label = self._new_label("for_end")
|
||||||
self._append_node(ForBegin(loop_label=loop_label, end_label=end_label))
|
self._append_node(ForBegin(loop_label=loop_label, end_label=end_label))
|
||||||
self._push_control({"type": "for", "loop": loop_label, "end": end_label})
|
self._push_control({"type": "for", "loop": loop_label, "end": end_label})
|
||||||
|
|
||||||
def _handle_next_control(self) -> None:
|
|
||||||
entry = self._pop_control(("for",))
|
|
||||||
self._append_node(ForNext(loop_label=entry["loop"], end_label=entry["end"]))
|
|
||||||
|
|
||||||
def _handle_while_control(self) -> None:
|
def _handle_while_control(self) -> None:
|
||||||
begin_label = self._new_label("begin")
|
begin_label = self._new_label("begin")
|
||||||
end_label = self._new_label("end")
|
end_label = self._new_label("end")
|
||||||
@@ -742,11 +748,6 @@ class Parser:
|
|||||||
self._append_node(BranchZero(target=entry["end"]))
|
self._append_node(BranchZero(target=entry["end"]))
|
||||||
self._push_control(entry)
|
self._push_control(entry)
|
||||||
|
|
||||||
def _handle_repeat_control(self) -> None:
|
|
||||||
entry = self._pop_control(("begin",))
|
|
||||||
self._append_node(Jump(target=entry["begin"]))
|
|
||||||
self._append_node(Label(name=entry["end"]))
|
|
||||||
|
|
||||||
def _begin_definition(self, token: Token) -> None:
|
def _begin_definition(self, token: Token) -> None:
|
||||||
if self._eof():
|
if self._eof():
|
||||||
raise ParseError(f"definition name missing after ':' at {token.line}:{token.column}")
|
raise ParseError(f"definition name missing after ':' at {token.line}:{token.column}")
|
||||||
@@ -1300,7 +1301,7 @@ class CompileTimeVM:
|
|||||||
self.loop_stack.append({"remaining": count, "begin": ip, "initial": count})
|
self.loop_stack.append({"remaining": count, "begin": ip, "initial": count})
|
||||||
ip += 1
|
ip += 1
|
||||||
continue
|
continue
|
||||||
if isinstance(node, ForNext):
|
if isinstance(node, ForEnd):
|
||||||
if not self.loop_stack:
|
if not self.loop_stack:
|
||||||
raise ParseError("'next' without matching 'for'")
|
raise ParseError("'next' without matching 'for'")
|
||||||
frame = self.loop_stack[-1]
|
frame = self.loop_stack[-1]
|
||||||
@@ -1326,7 +1327,7 @@ class CompileTimeVM:
|
|||||||
for idx, node in enumerate(nodes):
|
for idx, node in enumerate(nodes):
|
||||||
if isinstance(node, ForBegin):
|
if isinstance(node, ForBegin):
|
||||||
stack.append(idx)
|
stack.append(idx)
|
||||||
elif isinstance(node, ForNext):
|
elif isinstance(node, ForEnd):
|
||||||
if not stack:
|
if not stack:
|
||||||
raise ParseError("'next' without matching 'for'")
|
raise ParseError("'next' without matching 'for'")
|
||||||
begin_idx = stack.pop()
|
begin_idx = stack.pop()
|
||||||
@@ -1641,7 +1642,7 @@ class Assembler:
|
|||||||
if isinstance(node, ForBegin):
|
if isinstance(node, ForBegin):
|
||||||
self._emit_for_begin(node, builder)
|
self._emit_for_begin(node, builder)
|
||||||
return
|
return
|
||||||
if isinstance(node, ForNext):
|
if isinstance(node, ForEnd):
|
||||||
self._emit_for_next(node, builder)
|
self._emit_for_next(node, builder)
|
||||||
return
|
return
|
||||||
raise CompileError(f"unsupported AST node {node!r}")
|
raise CompileError(f"unsupported AST node {node!r}")
|
||||||
@@ -1737,7 +1738,7 @@ class Assembler:
|
|||||||
builder.emit(" mov [r13], rax")
|
builder.emit(" mov [r13], rax")
|
||||||
builder.emit(f"{node.loop_label}:")
|
builder.emit(f"{node.loop_label}:")
|
||||||
|
|
||||||
def _emit_for_next(self, node: ForNext, builder: FunctionEmitter) -> None:
|
def _emit_for_next(self, node: ForEnd, builder: FunctionEmitter) -> None:
|
||||||
builder.emit(" mov rax, [r13]")
|
builder.emit(" mov rax, [r13]")
|
||||||
builder.emit(" dec rax")
|
builder.emit(" dec rax")
|
||||||
builder.emit(" mov [r13], rax")
|
builder.emit(" mov [r13], rax")
|
||||||
@@ -2463,7 +2464,7 @@ PY_EXEC_GLOBALS: Dict[str, Any] = {
|
|||||||
"Jump": Jump,
|
"Jump": Jump,
|
||||||
"Label": Label,
|
"Label": Label,
|
||||||
"ForBegin": ForBegin,
|
"ForBegin": ForBegin,
|
||||||
"ForNext": ForNext,
|
"ForEnd": ForEnd,
|
||||||
"StructField": StructField,
|
"StructField": StructField,
|
||||||
"Definition": Definition,
|
"Definition": Definition,
|
||||||
"Module": Module,
|
"Module": Module,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
dup pick
|
dup pick
|
||||||
puti cr
|
puti cr
|
||||||
1 +
|
1 +
|
||||||
next
|
end
|
||||||
drop
|
drop
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ import stdlib/io.sl
|
|||||||
c!
|
c!
|
||||||
drop
|
drop
|
||||||
swap
|
swap
|
||||||
next
|
end
|
||||||
swap
|
swap
|
||||||
nip
|
nip
|
||||||
r> dup -rot - swap
|
r> dup -rot - swap
|
||||||
@@ -72,4 +72,4 @@ import stdlib/io.sl
|
|||||||
"hello world hello world hello " "world hello world hello world"
|
"hello world hello world hello " "world hello world hello world"
|
||||||
strconcat
|
strconcat
|
||||||
puts
|
puts
|
||||||
;
|
;
|
||||||
|
|||||||
10
test.sl
10
test.sl
@@ -104,7 +104,7 @@ fn fancy_add(int a, int b){
|
|||||||
111 puti cr
|
111 puti cr
|
||||||
else
|
else
|
||||||
222 puti cr
|
222 puti cr
|
||||||
then
|
end
|
||||||
;
|
;
|
||||||
|
|
||||||
: test-else-if
|
: test-else-if
|
||||||
@@ -116,8 +116,8 @@ fn fancy_add(int a, int b){
|
|||||||
60 puti cr
|
60 puti cr
|
||||||
else
|
else
|
||||||
70 puti cr
|
70 puti cr
|
||||||
then
|
end
|
||||||
then
|
end
|
||||||
drop
|
drop
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ fn fancy_add(int a, int b){
|
|||||||
0
|
0
|
||||||
5 for
|
5 for
|
||||||
1 +
|
1 +
|
||||||
next
|
end
|
||||||
puti cr
|
puti cr
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ fn fancy_add(int a, int b){
|
|||||||
123
|
123
|
||||||
0 for
|
0 for
|
||||||
drop
|
drop
|
||||||
next
|
end
|
||||||
puti cr
|
puti cr
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -8,24 +8,24 @@ import stdlib/io.sl
|
|||||||
write_buf # print file contents (file_len file_addr)
|
write_buf # print file contents (file_len file_addr)
|
||||||
0
|
0
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
dup -2 == if # open() failed
|
dup -2 == if # open() failed
|
||||||
drop
|
drop
|
||||||
"open() failed: errno=" puts
|
"open() failed: errno=" puts
|
||||||
swap puti cr
|
swap puti cr
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
dup -1 == if # fstat() failed
|
dup -1 == if # fstat() failed
|
||||||
drop
|
drop
|
||||||
"fstat() failed: errno=" puts
|
"fstat() failed: errno=" puts
|
||||||
swap puti cr
|
swap puti cr
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
dup -3 == if # mmap() failed
|
dup -3 == if # mmap() failed
|
||||||
drop
|
drop
|
||||||
"mmap() failed" puts
|
"mmap() failed" puts
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
"unknown read_file failure" puts
|
"unknown read_file failure" puts
|
||||||
dup # file_len file_len file_addr
|
dup # file_len file_len file_addr
|
||||||
exit # Exit with returned file_len as the program exit code (debug)
|
exit # Exit with returned file_len as the program exit code (debug)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import stdlib/io.sl
|
|||||||
dup 0 > if
|
dup 0 > if
|
||||||
write_buf
|
write_buf
|
||||||
0 exit
|
0 exit
|
||||||
then
|
end
|
||||||
"read_stdin failed" puts
|
"read_stdin failed" puts
|
||||||
exit
|
exit
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import stdlib/io.sl
|
|||||||
puti cr
|
puti cr
|
||||||
0
|
0
|
||||||
exit
|
exit
|
||||||
then
|
end
|
||||||
"write failed errno=" puts
|
"write failed errno=" puts
|
||||||
puti cr
|
puti cr
|
||||||
exit
|
exit
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ import {ROOT / 'stdlib/io.sl'}
|
|||||||
0
|
0
|
||||||
5 for
|
5 for
|
||||||
1 +
|
1 +
|
||||||
next
|
end
|
||||||
puti cr
|
puti cr
|
||||||
5 5 == puti cr
|
5 5 == puti cr
|
||||||
5 4 == puti cr
|
5 4 == puti cr
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import stdlib/io.sl
|
|||||||
do
|
do
|
||||||
dup puti cr
|
dup puti cr
|
||||||
1 -
|
1 -
|
||||||
repeat
|
end
|
||||||
drop
|
drop
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user