diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index e61ba10..0836a12 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -11,6 +11,7 @@ jobs: - name: Setup Haskell with Stack uses: haskell-actions/setup@v2 + id: setup with: enable-stack: true stack-version: "latest" @@ -18,7 +19,7 @@ jobs: - name: Cache dependencies uses: actions/cache@v4 with: - path: ~/.stack + path: ${{ steps.setup.outputs.stack-root }} key: pedantic-${{ hashFiles('stack.yaml') }} restore-keys: | pedantic- @@ -45,25 +46,18 @@ jobs: - name: Setup Haskell with Stack uses: haskell-actions/setup@v2 + id: setup with: enable-stack: true stack-version: "latest" - - name: Cache dependencies on Unix-like OS - if: startsWith(runner.os, 'Linux') || startsWith(runner.os, 'macOS') - uses: actions/cache@v4 - with: - path: ~/.stack - key: ${{ runner.os }}-${{ hashFiles('stack.yaml') }} - - - name: Cache dependencies on Windows - if: startsWith(runner.os, 'Windows') + - name: Cache dependencies uses: actions/cache@v4 with: - path: | - ~\AppData\Roaming\stack - ~\AppData\Local\Programs\stack + path: ${{ steps.setup.outputs.stack-root }} key: ${{ runner.os }}-${{ hashFiles('stack.yaml') }} + restore-keys: | + ${{ runner.os }} - name: Install dependencies run: | diff --git a/.vscode/settings.json b/.vscode/settings.json index 74a2012..6434b53 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -35,5 +35,5 @@ "**/*.o-boot": true, "**/*.hi-boot": true }, - "cSpell.words": ["crossreference", "unbundle"] + "cSpell.words": ["crossreference", "unbundle", "Lamagraph"] } diff --git a/lamagraph-compiler/lamagraph-compiler.cabal b/lamagraph-compiler/lamagraph-compiler.cabal index ef20843..2711da0 100644 --- a/lamagraph-compiler/lamagraph-compiler.cabal +++ b/lamagraph-compiler/lamagraph-compiler.cabal @@ -6,7 +6,7 @@ cabal-version: 1.12 name: lamagraph-compiler version: 0.1.0.0 -description: Please see the README on GitHub at +description: Please see the README on GitHub at homepage: https://github.com/Lamagraph/interaction-nets-in-fpga#readme bug-reports: https://github.com/Lamagraph/interaction-nets-in-fpga/issues author: Nikolai Ponomarev @@ -24,6 +24,7 @@ source-repository head library exposed-modules: + Lamagraph.Compiler.Syntax Lib other-modules: Paths_lamagraph_compiler diff --git a/lamagraph-compiler/package.yaml b/lamagraph-compiler/package.yaml index 0b77761..a01d984 100644 --- a/lamagraph-compiler/package.yaml +++ b/lamagraph-compiler/package.yaml @@ -17,7 +17,7 @@ extra-source-files: # To avoid duplicated efforts in documentation and dealing with the # complications of embedding Haddock markup inside cabal files, it is # common to point users to the README.md file. -description: Please see the README on GitHub at +description: Please see the README on GitHub at dependencies: - base >= 4.7 && < 5 diff --git a/lamagraph-compiler/src/Lamagraph/Compiler/Syntax.hs b/lamagraph-compiler/src/Lamagraph/Compiler/Syntax.hs new file mode 100644 index 0000000..4b135c8 --- /dev/null +++ b/lamagraph-compiler/src/Lamagraph/Compiler/Syntax.hs @@ -0,0 +1,317 @@ +{- | + +LamagraphML syntax +-} +module Lamagraph.Compiler.Syntax ( + -- * Grammar rules + -- $rules + + -- * Lexical conventions + + -- ** Blanks + -- $lexing_blanks + + -- ** Comments + -- $lexing_comments + + -- ** Identifiers + -- $lexing_idents + + -- ** Integer literals + -- $lexing_int_lits + + -- ** Character literals + -- $lexing_char_lits + + -- ** String literals + -- $lexing_string_lits + + -- ** Operators + -- $lexing_operators + + -- ** Keywords + -- $lexing_keywords + + -- * Names + -- $names + + -- * Type expressions + -- $types + + -- * Constants + -- $constants + + -- * Patterns + -- $patterns + + -- * Expressions + -- $expressions + + -- * Type definitions + -- $typedefs + + -- * Declarations and Modules + -- $decls + + -- * Missing things + -- $missing +) where + +{- $rules +Grammar rules are written in monospace font. +Italicized words represent @/nonterminals/@. +@Terminals@ are written in upright font. +@( )@ mean grouping, @{ }@ mean zero or more repetitions, @[ ]@ mean optional. +In case of clash between grammar and terminal meaning, terminal symbol will be typeset as @__bold monospace__@. +-} + +{- $lexing_blanks +Spaces, tabs, @\\n@ and @\\r@ are ignored and are used to separate tokens. +-} + +{- $lexing_comments + +Single-line comments use @--@ syntax and consume ALL characters until line break. + +Multiline comments must be enclosed in @(*@ and @*)@. +Nesting is allowed and must be handled. + +Note that the following code won't be treated as a valid multiline comment! + +@ +-- (* +*) +@ +-} + +{- $lexing_idents +@ +/ident/ ::= /letter/ { /letter/ | 0...9 | _ | ' } + +/capitalized-ident/ ::= ( A...Z ) { /letter/ | 0...9 | _ | ' } + +/lowercase-ident/ ::= ( a...z | _ ) { /letter/ | 0...9 | _ | ' } + +/letter/ ::= A...Z | a...z +@ +-} + +{- $lexing_int_lits +@ +/integer-literal/ ::= \[-] ( 0...9 ) { 0...9 | _ } + +/int32-literal/ ::= /integer-literal/ l + +/uint32-literal/ ::= /integer-literal/ ul + +/int64-literal/ ::= /integer-literal/ L + +/uint64-literal/ ::= /integer-literal/ UL +@ +-} + +{- $lexing_char_lits +@ +/char-literal/ ::= ' /regular-char/ ' + | ' /escape-sequence/ ' + +/escape-sequence/ ::= \\ ( __|__ | " | ' | n ) +@ + +@/regular-char/@ must match every printable ASCII character (decimal range: 32-126). +-} + +{- $lexing_string_lits +@ +/string-literal/ ::= " { /string-character/ } " + +/string-character/ ::= /regular-string-character/ + | /escape-sequence/ +@ + +@/regular-string-character/@ must match every printable ASCII character (decimal range: 32-126). +-} + +{- $lexing_operators + +@ +/infix-symbol/ ::= ( = | \< | \> | @ | ^ | __|__ | & | + | - | * | \/ | $ | % ) { /operator-char/ } + +/prefix-symbol/ ::= ! { /operator-char/ } + | ( ? | ~ ) { /operator-char/ }+ + +/operator-char/ ::= ! | $ | % | & | * | + | . | / | : | \< | = | \> | ? | \@ | ^ | __|__ | ~ +@ + +Copypasted from https://askra.de/software/ocaml-doc/4.02/lex.html#sec71, probably too complicated. +-} + +{- $lexing_keywords +Keyword table: + +@ +and asr else false fun if in land let +lor lsl lsr lxor match mod module +of open rec then true type when with + +!= && ' ( ) * + , - -> : :: ; < = > [ ] +_ { | } . +@ +-} + +{- $names +Basic names + +@ +/value-name/ ::= /lowercase-ident/ + | __(__ /operator-name/ __)__ + +/operator-name/ ::= /prefix-symbol/ | /infix-op/ + +/infix-op/ ::= /infix-symbol/ + | * | + | - | = | != | \< | \> | || | && + | mod | land | lor | lxor | lsl | lsr | asr + +/constr-name/ ::= /capitalized-ident/ + +/typeconstr-name/ ::= /lowercase-ident/ + +/module-name/ ::= /capitalized-ident/ +@ + +Qualified names + +@ +/value-path/ ::= [ /module-path/ . ] /value-name/ + +/constr/ ::= [ /module-path/ . ] /constr-name/ + +/typeconstr/ ::= [ /module-path/ . ] /typeconstr-name/ + +/module-path/ ::= /module-name/ { . /module-name/ } +@ +-} + +{- $types +@ +/typexpr/ ::= ' /ident/ + | __(__ /typexpr/ __)__ + | /typexpr/ -> /typexpr/ + | /typexpr/ { * /typexpr/}+ + | /typeconstr/ + | /typexpr/ /typeconstr/ + | __(__ /typexpr/ {, /typexpr/} __)__ /typeconstr/ +@ +-} + +{- $constants +@ +/constant/ ::= /integer-literal/ + | /int32-literal/ + | /uint32-literal/ + | /int64-literal/ + | /uint64-literal/ + | /char-literal/ + | /string-literal/ + | /constr/ + | false + | true + | __()__ + | __[]__ +@ +-} + +{- $patterns +@ +/pattern/ ::= /value-name/ + | _ + | /constant/ + | __(__ /pattern/ __)__ + | __(__ /pattern/ : /typexpr/ __)__ + | /pattern/ __|__ /pattern/ + | /constr/ /pattern/ + | /pattern/ { , /pattern/ } + | __[__ /pattern/ { ; /pattern/ } [;] __]__ + | /pattern/ :: /pattern/ +@ +-} + +{- $expressions + +@ +/expr/ ::= /value-path/ + | /constant/ + | __(__ /expr/ __)__ + | __(__ /expr/ : /typexpr/ __)__ + | /expr/ {, /expr/ } + | /constr/ /expr/ + | /expr/ :: /expr/ + | __[__ /expr/ { ; /expr/ } [;] ] + | /expr/ { /argument/ }+ + | /prefix-symbol/ /expr/ + | - /expr/ + | /expr/ /infix-op/ /expr/ + | if /expr/ then /expr/ else /expr/ + | match /expr/ with /pattern-matching/ + | fun { /parameter/ }+ [ : /typexpr/ ] -> /expr/ + | let [rec] /let-binding/ { and /let-binding/ } in /expr/ + +/argument/ ::= /expr/ + +/pattern-matching/ ::= [ __|__ ] /pattern/ [ when /expr/ ] -> /expr/ { __|__ /pattern/ [ when /expr/ ] -> /expr/ } + +/let-binding/ ::= /pattern/ = /expr/ + | /value-name/ { /parameter/ } [ : /typexpr/ ] = /expr/ + +/parameter/ ::= /pattern/ +@ +-} + +{- $typedefs + +@ +/type-definition/ ::= type /typedef/ { and /typedef/ } + +/typedef/ ::= [ /type-params/ ] /typeconstr-name/ /type-information/ + +/type-information/ ::= [ /type-equation/ ] [ /type-representation/ ] + +/type-equation/ ::= = /typexpr/ + +/type-representation/ ::= = [ __|__ ] /constr-decl/ { __|__ /constr-decl/ } + | = __|__ + +/type-params/ ::= /type-param/ + | __(__ /type-param/ {, /type-param/ } __)__ + +/type-param/ ::= ' /ident/ + +/constr-decl/ ::= ( /constr-name/ | __[]__ | __(__::__)__ ) [ of /constr-args/ ] + +/constr-args/ ::= /typexpr/ { * /typexpr/ } +@ +-} + +{- $decls + +@ +/module-definition/ ::= module /module-path/ + +/open-decl/ ::= open /module-path/ + +/decl/ ::= /expr/ | /type-definition/ | /open-decl/ + +/prog/ ::= [ /module-definition/ ] { /decl/ } +@ +-} + +{- $missing + +For the sake of simplicity this language currently lacks these know to the authors features: + +* Multiline strings +* Less useful escape sequences like @\\t@ +* Records +* Float numbers +* @function@ keyword +-}