fixed runtime stack missalignment
This commit is contained in:
parent
1b62b0fc4e
commit
981a6688d4
58
README.md
58
README.md
|
@ -2,34 +2,62 @@
|
||||||
|
|
||||||
Yard is an funny programming language compiler and interpreter written in pure Rust.
|
Yard is an funny programming language compiler and interpreter written in pure Rust.
|
||||||
Its a functional language, having no concept of classes or inheritance. Types are static and must be known at compile time.
|
Its a functional language, having no concept of classes or inheritance. Types are static and must be known at compile time.
|
||||||
It contains features such as:
|
|
||||||
|
|
||||||
1. a COMEFROM keyword (inverse goto)
|
### Primitve data types
|
||||||
2. a `don't` code block which never executes
|
|
||||||
3. no if. only `unless`, an inverted version of if. Meaning a block gets executed if the expression is false
|
The language has 4 primitive data types:
|
||||||
4. three spaces start a single line comment
|
|
||||||
5. many ways of making comments: `// comment`, `:REM: comment`, `# comment`, `-- comment --` cuz we can
|
* `bool` a 1 byte boolean value which is either true or false. It can also be initalised with a random value at compile time iwht `maybe`
|
||||||
|
* `int` a 8 byte two's complement signed integer with 64-bit of storage space
|
||||||
|
* `rat` a 8 byte IEEE-754 double precision floating point value
|
||||||
|
* `str` a dynamically sized immutable string wich for now can only be used with the concatonation operator `..`
|
||||||
|
|
||||||
|
NOTE: no custom data types such as structs or classes are supported.
|
||||||
|
|
||||||
### Keywords
|
### Keywords
|
||||||
|
|
||||||
<table><tbody><tr><td>Syntax</td><td>Description</td><td>Example</td></tr><tr><td>Unless</td><td>Inverted if. Only executes the following block if the expression is false</td><td><pre><code class="language-plaintext">unless 3 > 4 {
|
<table><tbody><tr><td>Syntax</td><td>Description</td><td>Example</td></tr><tr><td>despite</td><td>Inverted if. Only executes the following block if the expression is false</td><td><pre><code class="language-plaintext">despite 3 > 4 {
|
||||||
// code block
|
// code block
|
||||||
}</code></pre></td></tr><tr><td>Loop</td><td>While(true)-Loop. Loops forever until either yield, ret, break are used.<br>Loop take no boolean expression.</td><td><pre><code class="language-plaintext">loop {
|
}</code></pre></td></tr><tr><td>loop</td><td>While(true)-Loop. Loops forever until either yield, ret, break are used.<br>Loop take no boolean expression.</td><td><pre><code class="language-plaintext">loop {
|
||||||
// code block
|
// code block
|
||||||
}</code></pre></td></tr><tr><td>cont</td><td>Short form for “continue”. Jumps to the next iteration of a loop</td><td> </td></tr><tr><td>break</td><td>Exits a loop immediately</td><td> </td></tr><tr><td>yield</td><td>Returns from a function with an argument as return value</td><td><pre><code class="language-plaintext">foo() = int {
|
}</code></pre></td></tr><tr><td>cont</td><td>Short form for “continue”. Jumps to the next iteration of a loop</td><td><pre><code class="language-plaintext">loop {
|
||||||
|
cont;
|
||||||
|
}</code></pre></td></tr><tr><td>break</td><td>Exits a loop immediately</td><td><pre><code class="language-plaintext">loop {
|
||||||
|
break;
|
||||||
|
}</code></pre></td></tr><tr><td>yield</td><td>Returns from a function with an argument as return value</td><td><pre><code class="language-plaintext">foo() = int {
|
||||||
yield 4
|
yield 4
|
||||||
}</code></pre></td></tr><tr><td>ret</td><td>Short form for “return”. This keyword takes no argument and returns from a function. NOTE: if ret is used in a function with a return type, an error occurs.</td><td> </td></tr><tr><td>please</td><td>Decides on runtime wether a block should be executed or not.</td><td><pre><code class="language-plaintext">please {
|
}</code></pre></td></tr><tr><td>ret</td><td>Short form for “return”. This keyword takes no argument and returns from a function. NOTE: if ret is used in a function with a return type, an error occurs.</td><td><pre><code class="language-plaintext">foo() {
|
||||||
|
ret // exit function
|
||||||
|
}</code></pre></td></tr><tr><td>please</td><td>Decides on runtime wether a block should be executed or not.</td><td><pre><code class="language-plaintext">please {
|
||||||
// code
|
// code
|
||||||
}</code></pre></td></tr></tbody></table>
|
}</code></pre></td></tr><tr><td>unless</td><td>Works like a while loop except inverted. it will only run if the condition is false.</td><td><pre><code class="language-plaintext">unless x > 5 {
|
||||||
|
// code
|
||||||
|
}</code></pre></td></tr><tr><td>goto</td><td>jumps to a specified label</td><td><pre><code class="language-plaintext">'label
|
||||||
|
// code
|
||||||
|
goto label;</code></pre></td></tr></tbody></table>
|
||||||
|
|
||||||
### Example code
|
### Example code
|
||||||
|
|
||||||
```plaintext
|
```plaintext
|
||||||
foo(bar: int, abc:int) = int {
|
-- compute the factorial
|
||||||
bar + abc
|
-- in a recursive and functional way
|
||||||
|
fac(x:int) = int {
|
||||||
|
despite x != 1 {
|
||||||
|
yield 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield fac(x - 1) * x
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
number = rat 34 # this is a function without arguments and a braceless body
|
||||||
foo(4, 5)
|
|
||||||
|
// main function
|
||||||
|
main = int {
|
||||||
|
|
||||||
|
result = fac(number);
|
||||||
|
|
||||||
|
println("The Factorial of " .. number .. " is: " .. result);
|
||||||
|
|
||||||
|
yield 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
61
prog.vsasm
61
prog.vsasm
|
@ -1,39 +1,46 @@
|
||||||
section[text]
|
section[text]
|
||||||
|
|
||||||
|
0xa2b0391a480300b:
|
||||||
|
push float 12
|
||||||
|
|
||||||
|
extern builtin 0x80b0eba54530cdc3
|
||||||
|
|
||||||
|
extern builtin 0xcd262c6e6c32473d
|
||||||
|
|
||||||
0xc8c7a99bb88e156b:
|
0xc8c7a99bb88e156b:
|
||||||
push int 0x0
|
call 0xa2b0391a480300b
|
||||||
|
call 0x80b0eba54530cdc3
|
||||||
|
call 0x967b65e0e8f1394
|
||||||
store 0x0
|
store 0x0
|
||||||
load 0x0
|
push string "The Factorial of "
|
||||||
push int 0x9
|
call 0xa2b0391a480300b
|
||||||
cmp gt int
|
push string " is: "
|
||||||
jump-unless 0x19
|
|
||||||
load 0x0
|
|
||||||
push int 0x5
|
|
||||||
cmp not-eq int
|
|
||||||
jump-unless 0xf
|
|
||||||
load 0x0
|
|
||||||
push int 0x1
|
|
||||||
add int
|
|
||||||
store 0x0
|
|
||||||
jump 0x2
|
|
||||||
push string ""
|
|
||||||
load 0x0
|
load 0x0
|
||||||
cat
|
cat
|
||||||
call 0xa451e518c3d4dbea
|
cat
|
||||||
call 0x396ceaf58c7ab783
|
cat
|
||||||
load 0x0
|
call 0xe2e27e92bf406d33
|
||||||
|
push int 0x0
|
||||||
|
store 0x1
|
||||||
|
load 0x1
|
||||||
|
push int 0x9
|
||||||
|
cmp gt int
|
||||||
|
jump-unless 0x1b
|
||||||
|
push string ""
|
||||||
|
load 0x1
|
||||||
|
cat
|
||||||
|
call 0xe2e27e92bf406d33
|
||||||
|
load 0x1
|
||||||
push int 0x1
|
push int 0x1
|
||||||
add int
|
add int
|
||||||
store 0x0
|
store 0x1
|
||||||
jump 0x2
|
jump 0xe
|
||||||
jump 0x1b
|
|
||||||
jump 0x2
|
|
||||||
push int 0x0
|
push int 0x0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
extern builtin 0x396ceaf58c7ab783
|
extern builtin 0xe2e27e92bf406d33
|
||||||
|
|
||||||
extern builtin 0x608aa48c89877fc5
|
extern builtin 0x8207427514e5a880
|
||||||
|
|
||||||
0x967b65e0e8f1394:
|
0x967b65e0e8f1394:
|
||||||
load 0x0
|
load 0x0
|
||||||
|
@ -50,8 +57,8 @@ extern builtin 0x608aa48c89877fc5
|
||||||
mul int
|
mul int
|
||||||
ret
|
ret
|
||||||
|
|
||||||
extern builtin 0xdcd0c37eed9c3ddf
|
extern builtin 0x3e6a3810b5f0c581
|
||||||
|
|
||||||
extern builtin 0x6d3c1164316ec324
|
extern builtin 0x443bc4709cf7af32
|
||||||
|
|
||||||
extern builtin 0xa451e518c3d4dbea
|
extern builtin 0x23a9f04bf6903826
|
||||||
|
|
|
@ -596,7 +596,7 @@ const TOKEN_REGEX_SRC: &'static str = concat!(
|
||||||
r"|'([a-zA-Z0-9_]+)", // labels: 'example
|
r"|'([a-zA-Z0-9_]+)", // labels: 'example
|
||||||
r"|(goto\s+[a-zA-Z0-9_]+", // goto example
|
r"|(goto\s+[a-zA-Z0-9_]+", // goto example
|
||||||
r"|despite|until|loop|break|cont|ret|yield|please)", // keywords
|
r"|despite|until|loop|break|cont|ret|yield|please)", // keywords
|
||||||
r"|\W(int|rat|bool|str)\W", // raw data types
|
r"|[\W\s]{0,1}(int|rat|bool|str)[\W\s]{0,1}", // raw data types
|
||||||
r"|(true|false|ye|no|maybe)", // boolean values
|
r"|(true|false|ye|no|maybe)", // boolean values
|
||||||
r"|([A-Za-z_]+)\s*(?::\s*([a-zA-Z0-9_]+))?\s*=[^=]", // assignment var:int=
|
r"|([A-Za-z_]+)\s*(?::\s*([a-zA-Z0-9_]+))?\s*=[^=]", // assignment var:int=
|
||||||
r"|([A-Za-z_]+)\s*(?::\s*([a-zA-Z0-9_]+))", // declaration var:int
|
r"|([A-Za-z_]+)\s*(?::\s*([a-zA-Z0-9_]+))", // declaration var:int
|
||||||
|
|
|
@ -368,9 +368,10 @@ fn parse_term<'a>(
|
||||||
if decl.name.as_ref().unwrap() == name {
|
if decl.name.as_ref().unwrap() == name {
|
||||||
code.push(Instr::Call(decl.uuid()));
|
code.push(Instr::Call(decl.uuid()));
|
||||||
|
|
||||||
|
ct.stacksize -= decl.args.as_ref().unwrap_or(&Vec::new()).len();
|
||||||
|
|
||||||
if decl.results {
|
if decl.results {
|
||||||
ct.stacksize += 1;
|
ct.stacksize += 1;
|
||||||
ct.stacksize -= decl.args.as_ref().unwrap_or(&Vec::new()).len();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
34
test.erpn
34
test.erpn
|
@ -4,9 +4,13 @@ extern function print
|
||||||
|
|
||||||
extern function println
|
extern function println
|
||||||
|
|
||||||
extern function print
|
extern function to_rat
|
||||||
|
|
||||||
extern function println
|
extern function to_int
|
||||||
|
|
||||||
|
extern function parse_int
|
||||||
|
|
||||||
|
extern function parse_rat
|
||||||
|
|
||||||
fac:
|
fac:
|
||||||
Load Arg x
|
Load Arg x
|
||||||
|
@ -23,24 +27,29 @@ fac:
|
||||||
Mul Int
|
Mul Int
|
||||||
Yield
|
Yield
|
||||||
|
|
||||||
|
number:
|
||||||
|
Load Rat 12.0
|
||||||
|
|
||||||
main:
|
main:
|
||||||
|
Call number
|
||||||
|
Call to_int
|
||||||
|
Call fac
|
||||||
|
Store Int result
|
||||||
|
Load String "The Factorial of "
|
||||||
|
Call number
|
||||||
|
Load String " is: "
|
||||||
|
Load Var result
|
||||||
|
Cat Str
|
||||||
|
Cat Str
|
||||||
|
Cat Str
|
||||||
|
Call println
|
||||||
Load Int 0
|
Load Int 0
|
||||||
Store Int x
|
Store Int x
|
||||||
Loop
|
|
||||||
Loopstart
|
Loopstart
|
||||||
Load Var x
|
Load Var x
|
||||||
Load Int 9
|
Load Int 9
|
||||||
Gt Int
|
Gt Int
|
||||||
While
|
While
|
||||||
Load Var x
|
|
||||||
Load Int 5
|
|
||||||
NotEq Int
|
|
||||||
Unless
|
|
||||||
Load Var x
|
|
||||||
Load Int 1
|
|
||||||
Add Int
|
|
||||||
Store Int x
|
|
||||||
Continue
|
|
||||||
Load String ""
|
Load String ""
|
||||||
Load Var x
|
Load Var x
|
||||||
Cat Str
|
Cat Str
|
||||||
|
@ -49,7 +58,6 @@ main:
|
||||||
Load Int 1
|
Load Int 1
|
||||||
Add Int
|
Add Int
|
||||||
Store Int x
|
Store Int x
|
||||||
Break
|
|
||||||
Load Int 0
|
Load Int 0
|
||||||
Yield
|
Yield
|
||||||
|
|
||||||
|
|
30
test.yard
30
test.yard
|
@ -1,8 +1,9 @@
|
||||||
@feature(io)
|
@feature(io, conv)
|
||||||
@version(100)
|
@version(100)
|
||||||
@author(Sven Vogel)
|
@author(Sven Vogel)
|
||||||
|
|
||||||
// recursion!
|
-- compute the factorial
|
||||||
|
-- in a recursive and functional way
|
||||||
fac(x:int) = int {
|
fac(x:int) = int {
|
||||||
despite x != 1 {
|
despite x != 1 {
|
||||||
yield 1;
|
yield 1;
|
||||||
|
@ -11,25 +12,20 @@ fac(x:int) = int {
|
||||||
yield fac(x - 1) * x
|
yield fac(x - 1) * x
|
||||||
}
|
}
|
||||||
|
|
||||||
main() = int {
|
number = rat 12.0 # this is a function without arguments and a braceless body
|
||||||
|
|
||||||
x = 0
|
// main function
|
||||||
loop {
|
main = int {
|
||||||
|
|
||||||
|
result = fac(to_int(number));
|
||||||
|
|
||||||
|
println("The Factorial of " .. number() .. " is: " .. result);
|
||||||
|
|
||||||
|
x:int = 0;
|
||||||
until x > 9 {
|
until x > 9 {
|
||||||
despite x != 5 {
|
println("" .. x);
|
||||||
x = x + 1
|
|
||||||
cont
|
|
||||||
}
|
|
||||||
|
|
||||||
println(""..x);
|
|
||||||
x = x + 1
|
x = x + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
yield 0;
|
||||||
}
|
|
||||||
|
|
||||||
println(""..fract(456.3928));
|
|
||||||
|
|
||||||
yield 0
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue