From 981a6688d4bf55da216733ec5fac95d4aa77954a Mon Sep 17 00:00:00 2001 From: Teridax Date: Mon, 2 Jan 2023 12:56:53 +0100 Subject: [PATCH] fixed runtime stack missalignment --- README.md | 62 +++++++++++++++++++++++++++++++++++------------- prog.vsasm | 61 ++++++++++++++++++++++++++--------------------- src/token/mod.rs | 2 +- src/vmrt/mod.rs | 3 ++- test.erpn | 58 +++++++++++++++++++++++++------------------- test.yard | 32 +++++++++++-------------- 6 files changed, 129 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index fc4f6d3..a1a7225 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,63 @@ ## Yard 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. -It contains features such as: +Its a functional language, having no concept of classes or inheritance. Types are static and must be known at compile time. -1. a COMEFROM keyword (inverse goto) -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 -4. three spaces start a single line comment -5. many ways of making comments: `// comment`, `:REM: comment`, `# comment`, `-- comment --` cuz we can +### Primitve data types  + +The language has 4 primitive data types: + +* `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 -
SyntaxDescriptionExample
UnlessInverted if. Only executes the following block if the expression is false
unless 3 > 4 {
+
SyntaxDescriptionExample
despiteInverted if. Only executes the following block if the expression is false
despite 3 > 4 {
     // code block
-}
LoopWhile(true)-Loop. Loops forever until either yield, ret, break are used.
Loop take no boolean expression.
loop {
+}
loopWhile(true)-Loop. Loops forever until either yield, ret, break are used.
Loop take no boolean expression.
loop {
     // code block
-}
contShort form for “continue”. Jumps to the next iteration of a loop 
breakExits a loop immediately 
yieldReturns from a function with an argument as return value
foo() = int {
+}
contShort form for “continue”. Jumps to the next iteration of a loop
loop {
+    cont;
+}
breakExits a loop immediately
loop {
+    break;
+}
yieldReturns from a function with an argument as return value
foo() = int {
     yield 4
-}
retShort 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. 
pleaseDecides on runtime wether a block should be executed or not.
please {
-	// code
-}
+}
retShort 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.
foo() {
+    ret    // exit function
+}
pleaseDecides on runtime wether a block should be executed or not.
please {
+    // code
+}
unlessWorks like a while loop except inverted. it will only run if the condition is false.
unless x > 5 {
+    // code
+}
gotojumps to a specified label
'label
+// code
+goto label;
### Example code ```plaintext -foo(bar: int, abc:int) = int { - bar + abc +-- compute the factorial +-- in a recursive and functional way +fac(x:int) = int { + despite x != 1 { + yield 1; + } + + yield fac(x - 1) * x } -main { - foo(4, 5) +number = rat 34 # this is a function without arguments and a braceless body + +// main function +main = int { + + result = fac(number); + + println("The Factorial of " .. number .. " is: " .. result); + + yield 0; } ``` \ No newline at end of file diff --git a/prog.vsasm b/prog.vsasm index feec742..a2b20b7 100644 --- a/prog.vsasm +++ b/prog.vsasm @@ -1,39 +1,46 @@ section[text] +0xa2b0391a480300b: + push float 12 + +extern builtin 0x80b0eba54530cdc3 + +extern builtin 0xcd262c6e6c32473d + 0xc8c7a99bb88e156b: - push int 0x0 + call 0xa2b0391a480300b + call 0x80b0eba54530cdc3 + call 0x967b65e0e8f1394 store 0x0 - load 0x0 - push int 0x9 - cmp gt int - 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 "" + push string "The Factorial of " + call 0xa2b0391a480300b + push string " is: " load 0x0 cat - call 0xa451e518c3d4dbea - call 0x396ceaf58c7ab783 - load 0x0 + cat + cat + 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 add int - store 0x0 - jump 0x2 - jump 0x1b - jump 0x2 + store 0x1 + jump 0xe push int 0x0 ret -extern builtin 0x396ceaf58c7ab783 +extern builtin 0xe2e27e92bf406d33 -extern builtin 0x608aa48c89877fc5 +extern builtin 0x8207427514e5a880 0x967b65e0e8f1394: load 0x0 @@ -50,8 +57,8 @@ extern builtin 0x608aa48c89877fc5 mul int ret -extern builtin 0xdcd0c37eed9c3ddf +extern builtin 0x3e6a3810b5f0c581 -extern builtin 0x6d3c1164316ec324 +extern builtin 0x443bc4709cf7af32 -extern builtin 0xa451e518c3d4dbea +extern builtin 0x23a9f04bf6903826 diff --git a/src/token/mod.rs b/src/token/mod.rs index 6f9db60..f759f49 100644 --- a/src/token/mod.rs +++ b/src/token/mod.rs @@ -596,7 +596,7 @@ const TOKEN_REGEX_SRC: &'static str = concat!( r"|'([a-zA-Z0-9_]+)", // labels: 'example r"|(goto\s+[a-zA-Z0-9_]+", // goto example 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"|([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 diff --git a/src/vmrt/mod.rs b/src/vmrt/mod.rs index 30a5a0c..9995443 100644 --- a/src/vmrt/mod.rs +++ b/src/vmrt/mod.rs @@ -368,9 +368,10 @@ fn parse_term<'a>( if decl.name.as_ref().unwrap() == name { code.push(Instr::Call(decl.uuid())); + ct.stacksize -= decl.args.as_ref().unwrap_or(&Vec::new()).len(); + if decl.results { ct.stacksize += 1; - ct.stacksize -= decl.args.as_ref().unwrap_or(&Vec::new()).len(); } } } diff --git a/test.erpn b/test.erpn index 1e05c63..c5f1886 100644 --- a/test.erpn +++ b/test.erpn @@ -4,9 +4,13 @@ extern function print 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: Load Arg x @@ -23,33 +27,37 @@ fac: Mul Int Yield +number: + Load Rat 12.0 + 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 Store Int x - Loop - Loopstart + Loopstart + Load Var x + Load Int 9 + Gt Int + While + Load String "" Load Var x - Load Int 9 - Gt Int - 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 Var x - Cat Str - Call println - Load Var x - Load Int 1 - Add Int - Store Int x - Break + Cat Str + Call println + Load Var x + Load Int 1 + Add Int + Store Int x Load Int 0 Yield diff --git a/test.yard b/test.yard index 82f9984..c1f455c 100644 --- a/test.yard +++ b/test.yard @@ -1,8 +1,9 @@ -@feature(io) +@feature(io, conv) @version(100) @author(Sven Vogel) -// recursion! +-- compute the factorial +-- in a recursive and functional way fac(x:int) = int { despite x != 1 { yield 1; @@ -11,25 +12,20 @@ fac(x:int) = int { yield fac(x - 1) * x } -main() = int { - - x = 0 - loop { +number = rat 12.0 # this is a function without arguments and a braceless body - until x > 9 { - despite x != 5 { - x = x + 1 - cont - } +// main function +main = int { - println(""..x); - x = x + 1 - } + result = fac(to_int(number)); - break + println("The Factorial of " .. number() .. " is: " .. result); + + x:int = 0; + until x > 9 { + println("" .. x); + x = x + 1 } - println(""..fract(456.3928)); - - yield 0 + yield 0; } \ No newline at end of file