Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feature/link_all_to_vm
Browse files Browse the repository at this point in the history
  • Loading branch information
AldricJourdain committed Jan 14, 2024
2 parents d52f3e4 + 6e190f1 commit e3acbe3
Show file tree
Hide file tree
Showing 35 changed files with 5,376 additions and 11 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/Deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ jobs:
uses: haskell-actions/setup@v2
with:
enable-stack: true
- name: Install documentation
run: sudo apt-get install haskell-platform-doc && sudo apt-get install ghc-doc
- name: Create documentation
run: haddock -ohtml --html LobsterLang/src/*
run: stack haddock --haddock-arguments "-ohtml"
- name: Deploy to GitHub Pages
uses: crazy-max/ghaction-github-pages@v4
with:
target_branch: gh-pages
build_dir: html
build_dir: LobsterLang/html
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
99 changes: 99 additions & 0 deletions BNF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
## The Syntax of Lobsterlang in Backus-Naur Form
```bnf
<declarator> ::= <direct-declarator>
<parameter-type-list> ::= <parameter-list>
| <parameter-list> , ...
<parameter-list> ::= <parameter-declaration>
| <parameter-list> , <parameter-declaration>
<direct-declarator> ::= <identifier>
| ( <declarator> )
| <direct-declarator> ( <parameter-type-list> )
| <direct-declarator> ( {<identifier>}* )
<constant-expression> ::= <conditional-expression>
<logical-combinator-expression> ::= <logical-xor-expression>
| <logical-combinator-expression> || <logical-xor-expression>
<logical-xor-expression> ::= <logical-or-expression>
| <logical-xor-expression> || <logical-or-expression>
<logical-or-expression> ::= <logical-and-expression>
| <logical-or-expression> || <logical-and-expression>
<logical-and-expression> ::= <equality-or-expression>
| <logical-and-expression> && <equality-or-expression>
<equality-expression> ::= <relational-expression>
| <equality-expression> == <relational-expression>
| <equality-expression> != <relational-expression>
<relational-expression> ::= <additive-expression>
| <relational-expression> <= <additive-expression>
| <relational-expression> >= <shift-expression>
| <relational-expression> < <additive-expression>
| <relational-expression> > <additive-expression>
<additive-expression> ::= <multiplicative-expression>
| <additive-expression> + <multiplicative-expression>
| <additive-expression> - <multiplicative-expression>
<multiplicative-expression> ::= <list-expression>
| <multiplicative-expression> * <list-expression>
| <multiplicative-expression> / <list-expression>
| <multiplicative-expression> % <list-expression>
<list-expression> ::= <unary-expression>
| <list-expression> -- <unary-expression>
| <list-expression> ++ <unary-expression>
| <list-expression> !! <unary-expression>
<unary-expression> ::= <postfix-expression>
| <unary-operator> <unary-expression>
<postfix-expression> ::= <primary-expression>
| <postfix-expression> (| {<assignment-expression>}* |)
<primary-expression> ::= <identifier>
| <string>
| (| <expression> |)
<expression> ::= <assignment-expression>
| <expression> , <assignment-expression>
<constant> ::= <integer-constant>
| <character-constant>
<assignment-expression> ::= <conditional-expression>
| <unary-expression> <assignment-operator> <assignment-expression>
<assignment-operator> ::= =
<unary-operator> ::= @
| ~
| !
<expression-statement> ::= {<expression>}?
<init-declarator> ::= <declarator>
| <declarator> = <initializer>
<initializer> ::= <assignment-expression>
| [| <initializer-list> |]
| [| <initializer-list> , |]
<initializer-list> ::= <initializer>
| <initializer-list> , <initializer>
<statement> ::= <expression-statement>
| <selection-statement>
<expression-statement> ::= {<expression>}?
<selection-statement> ::= if (| <expression> |) <statement>
| if (| <expression> |) <statement> else <statement>
```
6 changes: 3 additions & 3 deletions LobsterLang/LobsterLang.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ cabal-version: 2.2
-- see: https://github.com/sol/hpack

name: LobsterLang
version: 0.1.0.0
description: Please see the README on GitHub at <https://github.com/githubuser/LobsterLang#readme>
homepage: https://github.com/githubuser/LobsterLang#readme
version: 1.0
description: Please see the README on GitHub at <https://github.com/AxelHumeau/LobsterLang/blob/main/README.md>
homepage: https://github.com/AxelHumeau/LobsterLang
bug-reports: https://github.com/githubuser/LobsterLang/issues
author: Author name here
maintainer: [email protected]
Expand Down
7 changes: 5 additions & 2 deletions LobsterLang/src/Parse.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ module Parse (
errorParsing,
parseDefineFn,
parseLambda,
parseCond
parseCond,
parseFunctionValue,
parseBracket,
parseComment
) where

import qualified AST
Expand Down Expand Up @@ -422,7 +425,7 @@ parseComment :: Parser Char
parseComment = parseChar '#' *> Parser f
where
f :: Position -> String -> Either String (Char, String, Position)
f (row, col) ('\n':xs) = Right ('\n', xs, (row + 1, col))
f (row, _) ('\n':xs) = Right ('\n', xs, (row + 1, 0))
f (row, col) "" = Right ('\n', "", (row, col + 1))
f (row, col) (_:xs) = f (row, col + 1) xs

Expand Down
78 changes: 78 additions & 0 deletions LobsterLang/test/ParserSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,81 @@ spec = do
runParser parseExpr (0,0) "! *" `shouldBe` Left (errorParsing (0,0))
it "Check parseExpr Unary Operation Failure (missing operator)" $ do
runParser parseExpr (0,0) "error" `shouldBe` Right (AST.Symbol "error" Nothing, "", (0, 5))
it "Check parseCmpString Success" $ do
runParser (parseCmpString "test") (0,0) "test" `shouldBe` Right ("test", "", (0, 4))
it "Check parseCmpString Success with remaining string" $ do
runParser (parseCmpString "test") (0,0) "test abc" `shouldBe` Right ("test", "abc", (0, 5))
it "Check parseCmpString Failure" $ do
runParser (parseCmpString "test") (0,0) "testa abc" `shouldBe` Left (errorParsing (0, 0))
it "Check parseFunctionValue Success" $ do
runParser parseFunctionValue (0,0) "(|a,b|) {| a + b |}" `shouldBe` Right (AST.FunctionValue ["a","b"] (AST.Call "+" [AST.Symbol "a" Nothing, AST.Symbol "b" Nothing]) Nothing,"",(0,19))
it "Check parseFunctionValue Failure missing brackets" $ do
runParser parseFunctionValue (0,0) "(|a,b|) a + b" `shouldBe` Left (errorParsing (0, 8))
it "Check parseFunctionValue Failure parameters" $ do
runParser parseFunctionValue (0,0) "{| a + b |}" `shouldBe` Left (errorParsing (0, 0))
it "Check parseFunctionValue Failure empty brackets" $ do
runParser parseFunctionValue (0,0) "(|a,b|) {||}" `shouldBe` Left (errorParsing (0, 10))
it "Check parseFunctionValue Success no parameter" $ do
runParser parseFunctionValue (0,0) "(||) {|1|}" `shouldBe` Right (AST.FunctionValue [] (AST.Value 1) Nothing, "", (0,10))
it "Check parseBracket Success" $ do
runParser parseBracket (0,0) "{| a + b |}" `shouldBe` Right ((AST.Call "+" [AST.Symbol "a" Nothing, AST.Symbol "b" Nothing]), "", (0, 11))
it "Check parseBracket Failure invalid start bracket" $ do
runParser parseBracket (0,0) "{ a + b |}" `shouldBe` Left (errorParsing (0, 1))
it "Check parseBracket Failure invalid end bracket" $ do
runParser parseBracket (0,0) "{| a + b }" `shouldBe` Left (errorParsing (0, 9))
it "Check parseBracket Failure empty brackets" $ do
runParser parseBracket (0,0) "{||}" `shouldBe` Left (errorParsing (0, 2))
it "Check parseLambda Success" $ do
runParser parseLambda (0,0) "lambda(|a,b|) {| a + b |}" `shouldBe` Right (AST.FunctionValue ["a","b"] (AST.Call "+" [AST.Symbol "a" Nothing, AST.Symbol "b" Nothing]) Nothing,"",(0,25))
it "Check parseLambda Success λ" $ do
runParser parseLambda (0,0) "λ(|a,b|) {| a + b |}" `shouldBe` Right (AST.FunctionValue ["a","b"] (AST.Call "+" [AST.Symbol "a" Nothing, AST.Symbol "b" Nothing]) Nothing,"",(0,20))
it "Check parseLambda Failure missing lambda/λ" $ do
runParser parseLambda (0,0) "(|a,b|) {| a + b |}" `shouldBe` Left (errorParsing (0,0))
it "Check parseLambda Failure invalid keyword" $ do
runParser parseLambda (0,0) "lambdaa(||) {|1|}" `shouldBe` Left (errorParsing (0,0))
it "Check parseLambda Failure word after λ" $ do
runParser parseLambda (0,0) "λ a(||) {|1|}" `shouldBe` Left (errorParsing (0,2))
it "Check parseLambda Failure empty brackets" $ do
runParser parseLambda (0,0) "λ(||) {||}" `shouldBe` Left (errorParsing (0,8))
it "Check parseCond Success single if" $ do
runParser parseCond (0,0) "if a == b {| 1 |}" `shouldBe` Right (AST.Cond (AST.Call "==" [AST.Symbol "a" Nothing, AST.Symbol "b" Nothing]) (AST.Value 1) Nothing,"",(0,17))
it "Check parseCond Success if and else" $ do
runParser parseCond (0,0) "if a == b {| 1 |} else {| 0 |}" `shouldBe` Right ((AST.Cond (AST.Call "==" [AST.Symbol "a" Nothing, AST.Symbol "b" Nothing]) (AST.Value 1) (Just (AST.Value 0))),"",(0,30))
it "Check parseCond Success if, else if and else" $ do
runParser parseCond (0,0) "if a == b {| 1 |} else if a == 2 {| 2 |} else {| 0 |}" `shouldBe` Right (AST.Cond (AST.Call "==" [AST.Symbol "a" Nothing, AST.Symbol "b" Nothing]) (AST.Value 1) (Just (AST.Cond (AST.Call "==" [AST.Symbol "a" Nothing, AST.Value 2]) (AST.Value 2) (Just (Value 0)))),"",(0,53))
it "Check parseCond Failure invalid expr" $ do
runParser parseCond (0,0) "if a *= 2 {|1|}" `shouldBe` Left (errorParsing (0,5))
it "Check parseCond Failure no expr" $ do
runParser parseCond (0,0) "if {|1|}" `shouldBe` Left (errorParsing (0,3))
it "Check parseCond Failure empty brackets" $ do
runParser parseCond (0,0) "if a {||}" `shouldBe` Left (errorParsing (0,7))
it "Check parseCond Failure no if" $ do
runParser parseCond (0,0) "a == b {||}" `shouldBe` Left (errorParsing (0,0))
it "Check parseCond Failure no space between if and expr" $ do
runParser parseCond (0,0) "ifa==b {||}" `shouldBe` Left (errorParsing (0,0))
it "Check parseCond Success ignore error in else" $ do
runParser parseCond (0,0) "if a==b {|1|} else" `shouldBe` Right (AST.Cond (AST.Call "==" [AST.Symbol "a" Nothing, AST.Symbol "b" Nothing]) (AST.Value 1) Nothing, "else", (0, 14))
it "Check parseComment Success" $ do
runParser parseComment (0,0) "#fn test(||) {|1|}" `shouldBe` Right ('\n', "", (0, 19))
it "Check parseComment Failure no #" $ do
runParser parseComment (0,0) "fn test(||) {|1|}" `shouldBe` Left (errorParsing (0,0))
it "Check parseComment Success with new line" $ do
runParser parseComment (0,0) "#fn test(||) {|1|}\ntest=1" `shouldBe` Right ('\n', "test=1", (1, 0))
it "Check parseDefineFn Success" $ do
runParser parseDefineFn (0,0) "fn function(|a|) {|a|}" `shouldBe` Right (AST.Define "function" (AST.FunctionValue ["a"] (AST.Symbol "a" Nothing) Nothing),"",(0,22))
it "Check parseDefineFn Success" $ do
runParser parseDefineFn (0,0) "fn function(|a|) {|a|}" `shouldBe` Right (AST.Define "function" (AST.FunctionValue ["a"] (AST.Symbol "a" Nothing) Nothing),"",(0,22))
it "Check parseDefineFn Failure no fn" $ do
runParser parseDefineFn (0,0) "function(|a|) {|a|}" `shouldBe` Left (errorParsing (0,0))
it "Check parseDefineFn Failure no space after fn" $ do
runParser parseDefineFn (0,0) "fnfunction(|a|) {|a|}" `shouldBe` Left (errorParsing (0,0))
it "Check parseDefineFn Failure no function name" $ do
runParser parseDefineFn (0,0) "fn (|a|) {|a|}" `shouldBe` Left (errorParsing (0,3))
it "Check parseDefineFn Failure no parameter" $ do
runParser parseDefineFn (0,0) "fn function {|a|}" `shouldBe` Left (errorParsing (0,12))
it "Check parseDefineFn Failure no brackets" $ do
runParser parseDefineFn (0,0) "fn function(|a|)" `shouldBe` Left (errorParsing (0,16))
it "Check parseDefineFn Failure invalid parameters" $ do
runParser parseDefineFn (0,0) "fn function(|a,|) {|a|}" `shouldBe` Left (errorParsing (0,15))
it "Check parseDefineFn Failure empty brackets" $ do
runParser parseDefineFn (0,0) "fn function(|a|) {||}" `shouldBe` Left (errorParsing (0,19))
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ COV_PATH_FILE = cov_path

BROWSER = firefox

EXTENSION_NAME = lobsterlang-0.0.1.vsix

MODULE_PATH = extension/node_modules

all:
cd $(PKG_NAME) && stack install $(PKG_NAME) --local-bin-path ..
mv $(PKG_NAME)-exe $(NAME)
Expand All @@ -36,4 +40,10 @@ cov:
$(BROWSER) $$(cat $(PKG_NAME)/$(COV_PATH_FILE) | sed 's/.$$//')
rm $(PKG_NAME)/$(COV_PATH_FILE)

install_extension: $(MODULE_PATH)
cd extension && vsce pack && code --install-extension $(EXTENSION_NAME)

$(MODULE_PATH):
cd extension && npm install

.PHONY: all clean fclean re tests_run
4 changes: 2 additions & 2 deletions exemple/Lambda.lob
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ sqrt = λ (| x |) {| x * x |}

add = λ (| a, b |) {| a + b |}

sqrt(| 5 |)
sqrt(| 5 |) # return 25

add(| 2, 9 |)
add(| 2, 9 |) # return 11

abs = λ (| x |) {|
if x < 0 {|
Expand Down
5 changes: 5 additions & 0 deletions extension/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/**
client/node_modules/**
client/out/**
server/node_modules/**
server/out/**
20 changes: 20 additions & 0 deletions extension/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**@type {import('eslint').Linter.Config} */
// eslint-disable-next-line no-undef
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
'semi': [2, "always"],
'@typescript-eslint/no-unused-vars': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/explicit-module-boundary-types': 0,
'@typescript-eslint/no-non-null-assertion': 0,
}
};
5 changes: 5 additions & 0 deletions extension/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
out
node_modules
client/server
.vscode-test
*.vsix
15 changes: 15 additions & 0 deletions extension/.vscodeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.vscode/**
**/*.ts
**/*.map
.gitignore
**/tsconfig.json
**/tsconfig.base.json
contributing.md
.travis.yml
client/node_modules/**
!client/node_modules/vscode-jsonrpc/**
!client/node_modules/vscode-languageclient/**
!client/node_modules/vscode-languageserver-protocol/**
!client/node_modules/vscode-languageserver-types/**
!client/node_modules/{minimatch,brace-expansion,concat-map,balanced-match}/**
!client/node_modules/{semver,lru-cache,yallist}/**
37 changes: 37 additions & 0 deletions extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# LSP Example

Heavily documented sample code for https://code.visualstudio.com/api/language-extensions/language-server-extension-guide

## Functionality

This Language Server works for plain text file. It has the following language features:
- Completions
- Diagnostics regenerated on each file change or configuration change

It also includes an End-to-End test.

## Structure

```
.
├── client // Language Client
│ ├── src
│ │ ├── test // End to End tests for Language Client / Server
│ │ └── extension.ts // Language Client entry point
├── package.json // The extension manifest.
└── server // Language Server
└── src
└── server.ts // Language Server entry point
```

## Running the Sample

- Run `npm install` in this folder. This installs all necessary npm modules in both the client and server folder
- Open VS Code on this folder.
- Press Ctrl+Shift+B to start compiling the client and server in [watch mode](https://code.visualstudio.com/docs/editor/tasks#:~:text=The%20first%20entry%20executes,the%20HelloWorld.js%20file.).
- Switch to the Run and Debug View in the Sidebar (Ctrl+Shift+D).
- Select `Launch Client` from the drop down (if it is not already).
- Press ▷ to run the launch config (F5).
- In the [Extension Development Host](https://code.visualstudio.com/api/get-started/your-first-extension#:~:text=Then%2C%20inside%20the%20editor%2C%20press%20F5.%20This%20will%20compile%20and%20run%20the%20extension%20in%20a%20new%20Extension%20Development%20Host%20window.) instance of VSCode, open a document in 'plain text' language mode.
- Type `j` or `t` to see `Javascript` and `TypeScript` completion.
- Enter text content such as `AAA aaa BBB`. The extension will emit diagnostics for all words in all-uppercase.
Loading

0 comments on commit e3acbe3

Please sign in to comment.