diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index ee2702f..017b93a 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -48,38 +48,6 @@ jobs: if: steps.filter.outputs.docs == 'true' || steps.filter.outputs.docs2 == 'true' || steps.filter.outputs.workflow == 'true' || github.ref == 'refs/heads/main' run: mdbook build - - name: Install Haskell - uses: haskell-actions/setup@v2 - with: - enable-stack: true - stack-version: 'latest' - - - name: Compil - if: steps.filter.outputs.docs == 'true' || steps.filter.outputs.docs2 == 'true' || steps.filter.outputs.workflow == 'true' || github.ref == 'refs/heads/main' - run: | - if ! stack build; then - exit 0 - fi - - - name: Tests - if: steps.filter.outputs.docs == 'true' || steps.filter.outputs.docs2 == 'true' || steps.filter.outputs.workflow == 'true' || github.ref == 'refs/heads/main' - run: | - if ! stack test --test-arguments "--html book/Tests.html"; then - exit 0 - fi - - - name: Coverage - if: steps.filter.outputs.docs == 'true' || steps.filter.outputs.docs2 == 'true' || steps.filter.outputs.workflow == 'true' || github.ref == 'refs/heads/main' - run: | - if ! make tests-coverage; then - exit 0 - else - PATH_HTML=$(make tests-coverage-html-path) - cp -r "$PATH_HTML/koaky" book/ - cp -r "$PATH_HTML/combined" book/ - cp "$PATH_HTML/index.html" book/Coverage.html - fi - - name: Setup Pages if: github.ref == 'refs/heads/main' uses: actions/configure-pages@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index df632a1..86779f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,14 +59,22 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - gh release upload ${{ needs.release-create.outputs.release }} "./koaky-exe.exe#koaky-windows.exe" + gh release upload ${{ needs.release-create.outputs.release }} "./lvtc/lvtc-exe.exe#lvtc-windows.exe" + gh release upload ${{ needs.release-create.outputs.release }} "./lvtrun/lvtrun-exe.exe#lvtrun-windows.exe" - - name: Upload To Artifact + - name: Upload To Artifact lvtc if: github.ref != 'refs/heads/main' uses: actions/upload-artifact@v3 with: - name: koaky.exe - path: ./koaky.exe + name: lvtc-windows.exe + path: ./lvtc/lvtc-exe.exe + + - name: Upload To Artifact lvtrun + if: github.ref != 'refs/heads/main' + uses: actions/upload-artifact@v3 + with: + name: lvtrun-windows.exe + path: ./lvtrun/lvtrun-exe.exe release-linux: runs-on: ubuntu-latest @@ -89,21 +97,31 @@ jobs: run: make - name: Rename - run: mv koaky-exe koaky-linux + run: | + mv lvtc/lvtc-exe lvtc-linux + mv lvtrun/lvtrun-exe lvtrun-linux - name: Upload To Release if: github.ref == 'refs/heads/main' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - gh release upload ${{ needs.release-create.outputs.release }} "./koaky-linux" + gh release upload ${{ needs.release-create.outputs.release }} "./lvtc-linux" + gh release upload ${{ needs.release-create.outputs.release }} "./lvtrun-linux" + + - name: Upload To Artifact lvtc + if: github.ref != 'refs/heads/main' + uses: actions/upload-artifact@v3 + with: + name: lvtc-linux + path: ./lvtc-linux - - name: Upload To Artifact + - name: Upload To Artifact lvtrun if: github.ref != 'refs/heads/main' uses: actions/upload-artifact@v3 with: - name: koaky-linux - path: ./koaky-linux + name: lvtrun-linux + path: ./lvtrun-linux release-macos: runs-on: macos-latest @@ -126,18 +144,28 @@ jobs: run: make - name: Rename - run: mv koaky-exe koaky-macos + run: | + mv lvtc/lvtc-exe lvtc-macos + mv lvtrun/lvtrun-exe lvtrun-macos - name: Upload To Release if: github.ref == 'refs/heads/main' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - gh release upload ${{ needs.release-create.outputs.release }} "./koaky-macos" + gh release upload ${{ needs.release-create.outputs.release }} "./lvtc-macos" + gh release upload ${{ needs.release-create.outputs.release }} "./lvtrun-macos" + + - name: Upload To Artifact lvtc + if: github.ref != 'refs/heads/main' + uses: actions/upload-artifact@v3 + with: + name: lvtc-macos + path: ./lvtc-macos - - name: Upload To Artifact + - name: Upload To Artifact lvtrun if: github.ref != 'refs/heads/main' uses: actions/upload-artifact@v3 with: - name: koaky-macos - path: ./koaky-macos + name: lvtrun-macos + path: ./lvtrun-macos diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index dd66015..93b97d4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -58,7 +58,7 @@ jobs: - name: Tests id: failedTest run: | - if ! stack test &> tests.log; then + if ! make tests &> tests.log; then echo "failedTest=true" >> $GITHUB_OUTPUT else echo "failedTest=false" >> $GITHUB_OUTPUT diff --git a/.gitignore b/.gitignore index ac73cc9..f61f7ff 100644 --- a/.gitignore +++ b/.gitignore @@ -169,6 +169,9 @@ tags /koaky-exe /glados +lvtc-exe +lvtrun-exe + *.log *.exe diff --git a/Makefile b/Makefile index 294c12a..24566f5 100644 --- a/Makefile +++ b/Makefile @@ -5,41 +5,39 @@ ## makefile that stack ## -TARGET = koaky -MARVIN_TARGET = glados +TARGET = leviator -CP = cp -RM = rm -rf - -ifeq ($(OS),Windows_NT) - BIN_STACK = $(TARGET)-exe.exe -else - BIN_STACK = $(TARGET)-exe -endif - -all: $(TARGET) +LVT_COMPILER = lvtc +LVT_RUNER = lvtrun $(TARGET): - stack build --copy-bins --local-bin-path . - $(CP) "$(BIN_STACK)" "$(MARVIN_TARGET)" + "$(MAKE)" -C "$(LVT_COMPILER)" + "$(MAKE)" -C "$(LVT_RUNER)" + +debug: + "$(MAKE)" -C "$(LVT_COMPILER)" debug + "$(MAKE)" -C "$(LVT_RUNER)" debug clean: - stack clean + "$(MAKE)" -C "$(LVT_COMPILER)" clean + "$(MAKE)" -C "$(LVT_RUNER)" clean fclean: clean - stack purge - $(RM) "$(BIN_STACK)" - $(RM) "$(MARVIN_TARGET)" + "$(MAKE)" -C "$(LVT_COMPILER)" fclean + "$(MAKE)" -C "$(LVT_RUNER)" fclean re: fclean $(TARGET) tests: - stack test + "$(MAKE)" -C "$(LVT_COMPILER)" tests + "$(MAKE)" -C "$(LVT_RUNER)" tests tests-coverage: - stack test --coverage + "$(MAKE)" -C "$(LVT_COMPILER)" tests-coverage + "$(MAKE)" -C "$(LVT_RUNER)" tests-coverage tests-coverage-html-path: - @stack path --local-hpc-root + @"$(MAKE)" -C "$(LVT_COMPILER)" tests-coverage-html-path + @"$(MAKE)" -C "$(LVT_RUNER)" tests-coverage-html-path .PHONY: $(TARGET) fclean re clean all diff --git a/README.md b/README.md index 58adbed..970bfad 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,26 @@ ## Documentation --- **Comentary** +- **Comentary** ```c // This is a comment ``` --- **Variables Declaration** +- **Alias** + +``` +alias A = Int; +``` + +- **Variables Declaration** ```hs @Int a = 1; -@String b = "hello"; +@StringView b = "hello"; ``` --- **Variables Assignment** +- **Variables Assignment** ```hs a = 1; @@ -33,17 +39,11 @@ b = "hello"; @Bool a = True; @Bool b = False; @Int c = 1; -@List[Int] d = [1, 2, 3]; @Char e = 'a'; -@String f = "hello"; -@List[Char] g = ['a', 'b', 'c']; +@StringView f = "hello"; ``` -- **Built-in Global Variables** - -```c -@List[String] ARGS = ["programfilepath", "arg1", "arg2"]; -``` +There is a `Void` type that can be used to return nothing. - **Function Declaration** @@ -53,6 +53,11 @@ fn add(a: Int, b: Int) -> Int // the next line is the `return` <- a + b; }; + +export fn sub(a: Int, b: Int) -> Int +{ + <- a - b; +}; ``` - **Function Call** @@ -80,38 +85,6 @@ fn add(a: Int, b: Int, c: Int) -> Int }; ``` -- **Built-in Functions** - -```c -// print to stdout -print("hello"); -// print to stderr -printErr("hello"); -// get a line from stdin -getLine(); -// transform a type to a string -str(1); -// get the type of a value in string format -type(a); -// call a function with string -call("add", [1, 2]); -``` - -- **Generic Functions** - -```rust -fn add[A](a: A, b: A) -> A -{ - <- a + b; -}; -``` - -- **Generic Functions Call** - -```rust -add[Int](1, 2); -``` - - **Conditions** ```c @@ -141,29 +114,11 @@ while (i < 10) }; ``` -```c -@List[Int] lst = [1, 2, 3]; -foreach (a in lst) -{ - if (a == 2) - { - break; - }; -}; -``` - -- **Imports** - -```c -// Circular imports are not allowed -import "path/to/file.lvt" -``` - - **Entrypoint** ```rust // If you don't have this function, the program will not be run -fn start() -> Int +export fn start() -> Int { <- 0; }; @@ -178,22 +133,8 @@ a * b a / b a == b a != b -``` - -- **Structs** - -```c -struct Point -{ - a: Int, -}; -``` - -- **Generic Structs** - -```c -struct Rect[A] -{ - a: A, -}; +a < b +a <= b +a > b +a >= b ``` diff --git a/docs/BNF.md b/docs/BNF.md new file mode 100644 index 0000000..1434673 --- /dev/null +++ b/docs/BNF.md @@ -0,0 +1,61 @@ +# Leviator BNF + +```bnf + ::= * + + ::= | | + + ::= "alias " " " ";\n" + ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | + "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | + "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | + "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | + "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | + "t" | "u" | "v" | "w" | "x" | "y" | "z" | "0" | "1" | + "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "_" | + "." | "-" | ":" | "!" | "@" | "#" | "$" | "%" | "^" | + "&" | "*" | "(" | ")" | "[" | "]" | "{" | "}" | "|" | + "\\" | "+" | "=" | ";" | "<" | ">" | "?" | "/" | "`" | + "~" + ::= + + ::= "//" * "\n" + + ::= "fn " "(" * ") -> " "\n{\n" * "}\n" + ::= + ::= "," + ::= ": " + ::= + ::= ";\n" + ::= | | | | + ::= "@" " " " = " + ::= " = " + ::= "(" * ")" + ::= "," + ::= "<- " + ::= | | + ::= | | | + ::= | + ::= + ::= "if (" ")\n{\n" * "}\n" + ::= "else\n{\n" * "}\n" + + ::= "'" "'" + ::= "True" | "False" + ::= "\"" * "\"" + + ::= | | + ::= | "" | " " | + ::= | | | + ::= "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | + "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | + "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" + ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | + "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | + "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" + ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + ::= "_" + ::= | "!" | "@" | "#" | "$" | "%" | "^" | "&" | + "*" | "(" | ")" | "[" | "]" | "{" | "}" | "|" | "\\" | + "+" | "=" | ";" | "<" | ">" | "?" | "/" | "`" | "~" +``` diff --git a/docs/ByteCodeSpec.md b/docs/ByteCodeSpec.md new file mode 100644 index 0000000..e9807b0 --- /dev/null +++ b/docs/ByteCodeSpec.md @@ -0,0 +1,225 @@ +# Spec for ByteCode + +:: All value starting with `0x` are hexadecimal + +## Header + +1. The file starts with: + +``` +0x00 0x61 0x73 0x6D +0x01 0x00 0x00 0x00 +``` + +## Type Section + +``` +0x01 +``` + +### Function Type + +``` +0x60 +``` + +#### Number of Parameters + +- for 2 parameters + ``` + 0x02 + ``` + +#### Parameters Type + +``` +0x7F: i32 +0x7D: f32 +``` + +#### Return Type + +``` +0x7F: i32 +0x7D: f32 +0x00: void +``` + +## Function Section + +``` +0x03 +``` + +## Export Section + +``` +0x07 +``` + +Instructions +------------ + +## Instructions + +### Stack + +#### local + +##### local.get + +``` +0x20 +``` + +Get a local variable by its index and add it to the stack. + +##### local.set + +``` +0x21 +``` + +Get the top of the stack and set a local variable by its index. + +#### global + +##### global.get + +``` +0x23 +``` + +Get a global variable by its index and add it to the stack. + +##### global.set + +``` +0x24 +``` + +Get the top of the stack and set a global variable by its index. + +#### i32 + +##### i32.const + +``` +0x41 +``` + +Push an `Int32` to the stack. + +### Memory + +#### i32 + +##### i32.store + +``` +0x36 +``` + +Take the top of the stack. This will be the value stored in memory. +Take the top of the stack. This will be the index in memory. + +Store the value in memory at the index. + +##### i32.load + +``` +0x28 +``` + +Take the top of the stack. This will be the index in memory. + +Push an `Int32` to the stack with the value at address in memory. + +### Condition + +#### i32 + +##### i32.gt_s + +``` +0x4a +``` + +Compare the 2 values on the top of the stack. + +If the first value is greater than the second value, push `1` to the stack. +else, push `0` + +##### i32.eq + +``` +0x46 +``` + +Compare the 2 values on the top of the stack. + +If the first value is equal to the second value, push `1` to the stack. +else, push `0` + +#### control + +##### if...else...end + +- if + + ``` + 0x04 + ``` + + Enter in the first branch if the top of the stack is 1. + +- else + + ``` + 0x05 + ``` + + Enter in the second branch if the top of the stack is 0. + +- end + + ``` + 0x0b + ``` + + Exit from the if/else block. + +##### loop