Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
99ee96a
Statement data class
khbminus Nov 16, 2022
67762a5
First attempt of parsers
khbminus Nov 16, 2022
d3cb3d1
Tests
khbminus Nov 16, 2022
c0961f6
Parser is ready
khbminus Nov 17, 2022
f8e3876
It works, but test should be written
khbminus Nov 17, 2022
0de0bdf
Refactor
khbminus Nov 18, 2022
23942c0
Tests
khbminus Nov 18, 2022
c9bf07c
toy write
ozzush Nov 18, 2022
45eba8f
use Context as IO monad
ozzush Nov 18, 2022
3c25195
cleanup
ozzush Nov 18, 2022
f393f50
add tests
ozzush Nov 18, 2022
a2e5a44
Added missing dependency
khbminus Nov 20, 2022
c07b1c4
Added multiline support
khbminus Nov 20, 2022
adc390f
Merge pull request #5 from khbminus/basic-parsing
khbminus Nov 20, 2022
52c35bd
Merge branch 'main' into basic-syntax
khbminus Nov 22, 2022
80b132f
Merge pull request #6 from khbminus/basic-syntax
khbminus Nov 22, 2022
ea9d80b
echo application
ozzush Nov 23, 2022
363bb43
Basic context
khbminus Nov 26, 2022
c85e39d
cabal
ozzush Nov 27, 2022
5bc4753
demo console
ozzush Nov 27, 2022
7fad85e
Get rid of need of Context in parser
khbminus Nov 27, 2022
5b9de72
Fixed tests
khbminus Nov 27, 2022
bdc45da
Removed junk line
khbminus Nov 27, 2022
4195f38
First iteration of run function
khbminus Nov 27, 2022
853266d
Refactor of Context.hs
khbminus Nov 27, 2022
1fc8b6f
Changed run signature to make read work
khbminus Nov 27, 2022
9d37e8c
add interactive mode
ozzush Nov 27, 2022
f08e294
Added Errors support
khbminus Nov 27, 2022
2dfbc59
style fix
ozzush Nov 28, 2022
4fcd710
somehow ot works
ozzush Nov 28, 2022
dce341a
cabal
ozzush Dec 5, 2022
df9cc49
fix style
ozzush Dec 5, 2022
7fb52a4
small style fix
ozzush Dec 5, 2022
b36a31f
CI
khbminus Dec 5, 2022
94954ed
add var context parser test
ozzush Dec 5, 2022
36a7c26
Merge pull request #11 from khbminus/context-with-statet
ozzush Dec 5, 2022
4dbd5ba
More contexty context
khbminus Dec 5, 2022
043cd92
Merge branch 'main' into console-interface
ozzush Dec 5, 2022
557b627
remove duplicated dependency
ozzush Dec 5, 2022
00d00c5
Function without arguments
khbminus Dec 6, 2022
3bcee04
Argument support
khbminus Dec 6, 2022
66fa5cb
Statement support
khbminus Dec 6, 2022
0404ee4
Maybe -> MaybeT
ozzush Dec 6, 2022
0c0cf2d
Merge branch 'main' into ci
khbminus Dec 7, 2022
572cffe
Merge pull request #9 from khbminus/ci
khbminus Dec 8, 2022
73443b0
ExpressionOrStatement parser
khbminus Dec 8, 2022
5a79278
Merge branch 'main' into console-interface
ozzush Dec 8, 2022
64f0db5
Merge branch 'functions' into console-interface
ozzush Dec 8, 2022
276c18f
print expression result in REPL
ozzush Dec 8, 2022
c9927d2
Test fixes
khbminus Dec 8, 2022
6613daf
Merge pull request #10 from khbminus/console-interface
ozzush Dec 9, 2022
d2923f5
refactor and fix REPL
ozzush Dec 11, 2022
1a5339d
revert Context.hs
ozzush Dec 22, 2022
6d85a98
Merge pull request #15 from khbminus/fix-repl
ozzush Dec 22, 2022
0a01db2
tests fixed
ozzush Dec 22, 2022
f953554
fix other functionality
ozzush Dec 22, 2022
be29f83
Merge pull request #17 from khbminus/fix-tests-for-execute
khbminus Dec 23, 2022
e54ea02
Tests for function declaration parser
khbminus Dec 22, 2022
1b289b3
Fun functions tests
khbminus Dec 23, 2022
239f0f5
Merge pull request #18 from khbminus/functions-test
khbminus Dec 26, 2022
7d7ece2
Basic graph transformation. I dunno is this working
khbminus Dec 27, 2022
efcfbbe
some show changes
khbminus Dec 27, 2022
06b4d10
Reformatrd AstToIR, added function support
khbminus Dec 28, 2022
92c326b
fixed FunctionCallStatement IR
khbminus Dec 28, 2022
2141149
I didn't save...
khbminus Dec 28, 2022
3588467
folds
ozzush Dec 29, 2022
783488c
Added an `While` Last option
khbminus Dec 29, 2022
6e381c2
Merge pull request #21 from khbminus/hoopl-graph
khbminus Dec 29, 2022
8ace929
liveness logic
ozzush Dec 29, 2022
6f29081
tests in progress
ozzush Dec 29, 2022
4ce91fe
IrToAst is ready
khbminus Dec 29, 2022
aa041ea
fixme: function returns are lost after IR
ozzush Dec 30, 2022
6c6b90a
fixed return in irToAst
khbminus Dec 30, 2022
d62c740
Merge pull request #24 from khbminus/ir2Ast
khbminus Dec 30, 2022
6c45b06
simple tests
ozzush Dec 30, 2022
fd9c8a6
Added more brackets for consistency
khbminus Dec 30, 2022
1b60565
test fixes
khbminus Dec 30, 2022
def302d
Merge pull request #26 from khbminus/parser-more-brackets
khbminus Dec 30, 2022
d66b1d9
test fix
khbminus Dec 30, 2022
e85fa7a
finish tests for liveness
ozzush Dec 30, 2022
db1707d
Merge branch 'main' into liveness-optimization
ozzush Dec 30, 2022
c3857de
Merge pull request #22 from khbminus/liveness-optimization
ozzush Dec 30, 2022
28db060
refactor and add optimization support in console app
ozzush Dec 30, 2022
9b6301d
basic property-based tests
khbminus Dec 30, 2022
7f80ae4
Merge pull request #29 from khbminus/add-optimization-to-console
khbminus Dec 30, 2022
f08e44b
first sketch of static analysis property testing
khbminus Dec 30, 2022
c7ea111
Merge branch 'main' into property-based
khbminus Dec 30, 2022
5b612de
property-based testing is ready
khbminus Dec 30, 2022
9a7df78
YOU SHALL NOT FAIL
khbminus Dec 30, 2022
442d353
Merge pull request #30 from khbminus/property-based
khbminus Dec 30, 2022
1cc97f2
test fixes
khbminus Dec 30, 2022
550128b
Merge pull request #31 from khbminus/property-based
khbminus Dec 30, 2022
94d8966
README new version
khbminus Dec 30, 2022
415b520
README new version
khbminus Dec 30, 2022
b7f1c46
README update & bug fixes
khbminus Dec 30, 2022
be7c4b0
Fixed multiline bugs & added options to see IR & extended code
khbminus Jan 1, 2023
d7a17e6
error output in & and test fixes
khbminus Jan 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
on: [ push ]
name: Test run

jobs:
runhaskell:
name: Tests
runs-on: ubuntu-latest # or macOS-latest, or windows-latest
steps:
- uses: actions/checkout@v3
- uses: haskell/actions/setup@v2
with:
ghc-version: '8.10.7' # Exact version of ghc to use
# cabal-version: 'latest'. Omitted, but defaults to 'latest'
enable-stack: true
stack-version: 'latest'
- run: stack test
61 changes: 57 additions & 4 deletions L-static-analyzer.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.34.4.
-- This file has been generated from package.yaml by hpack version 0.35.0.
--
-- see: https://github.com/sol/hpack

Expand All @@ -25,14 +25,34 @@ source-repository head

library
exposed-modules:
Lib
Analysis.AstToIr
Analysis.IR
Analysis.IrToAst
Analysis.Live
Analysis.OptSupport
Console
ConsoleParser
Context
Error
Evaluate
Execute
Grammar
Statement
other-modules:
Paths_L_static_analyzer
hs-source-dirs:
src
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints
build-depends:
base >=4.7 && <5
, composition-prelude
, containers
, hoopl
, megaparsec
, mtl
, optparse-applicative
, parser-combinators
, transformers
default-language: Haskell2010

executable L-static-analyzer-exe
Expand All @@ -45,17 +65,50 @@ executable L-static-analyzer-exe
build-depends:
L-static-analyzer
, base >=4.7 && <5
, composition-prelude
, containers
, hoopl
, megaparsec
, mtl
, optparse-applicative
, parser-combinators
, transformers
default-language: Haskell2010

test-suite L-static-analyzer-test
type: exitcode-stdio-1.0
main-is: Spec.hs
main-is: Test.hs
other-modules:
Test.ConsoleParser
Test.Evaluate
Test.Execute
Test.Live
Test.Parsers
Test.PropertyExpr
Test.PropertyOptimizing
Paths_L_static_analyzer
hs-source-dirs:
test
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
build-depends:
L-static-analyzer
HUnit
, HUnit-approx
, L-static-analyzer
, base >=4.7 && <5
, composition-prelude
, containers
, hedgehog
, hoopl
, hspec
, hspec-megaparsec
, megaparsec
, mtl
, parser-combinators
, tasty
, tasty-discover
, tasty-hedgehog
, tasty-hspec
, tasty-hunit
, tasty-quickcheck
, transformers
default-language: Haskell2010
90 changes: 89 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,89 @@
# L programming language & static analyzer
# L programming language & static analyzer

## L Syntax

L is a simple imperative programming language which supports basic statements:

* Variable assignment: `<name> := <expr>`
* `if`:

```text
if a > b then { write a; b := a } else { write b; a := b }
```

That generally is

```text
if <expr> then { <trueBody> } else { <falseBody> }
```

* `while`:

```text
while x > 10 do { write x; x := x - 1 }
```

That generally is

```text
while <expr> do { <body> }
```

* `Skip` -- no-op command
* `Write <expr>` and `Read <variable name>` commands
* Functions:
* where declaration `def <name>(<arg1>, <arg2>,...) { <body> }`
or `def <name>(<arg1>, <arg2>,...) { <body>} return <expr>`
* and call is `<name>(arg1, arg2,...)` where `arg` is an expression. Call also supported in
expressions: `x := 2 + sum(2, 3)`.

Expressions support variable access, function calls and several binary operations
such: `+, -, *, /, %, >, >=, ==, !=, <=, <, &&, ||`.

### Examples

Factorial function:

```text
def f(x) { ans := 1; while (x > 0) do { ans := ans * x; x := x - 1 } } return ans
```

Recursive Fibonacci numbers:

```text
def fib(x) { ans := 1; if (x < 2) then { skip } else { ans := fib(x - 1) + fib(x - 2) } } return ans
```

## Usage of CLI app

### REPL

If you run the application without arguments, you will get a REPL mode.

### File interpretation

If flag `-i <FILE>` is passed, a file will be interpreted. Additionally, you can provide `--liveness-optimization` flag
to enable liveness optimization and provide starting variables and its values.

## Static Analysis

We wrote a static analyzer with liveness optimization that eliminate dead code. It could make code faster in situations
when we compute unused in future code. E.g. in this code we have unnecessary infinity loop:

```text
write 1
def f() { x := 0; while 1 do { x := x + 1} } return 1
def g() { x := f() }
g()
```

This will be optimized into

```text
write 1
def f() { x := 0; while 1 do { x := x + 1} } return 1
def g() { }
g()
```

That is in common not used for optimization, but used for error analysis and highlighting.
36 changes: 33 additions & 3 deletions app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
module Main (main) where
module Main where

import Lib
import Options.Applicative ( (<**>), fullDesc, header, info, progDesc, execParser, helper )
import Console (runLoop, readEvalWriteLoop, printIr, printExtended)
import ConsoleParser (Action(..), Input(..), actionParser, getVarContext)
import Context (Context(vars), newContext)
import Control.Monad.State ( evalStateT )

-- Программа парсит аргументы командной строки при помощи execParser,
-- а потом запускает функцию runAction (логику приложения)
main :: IO ()
main = someFunc
main = do
runAction =<< execParser opts
where
-- Задает парсер аргументов actionParser, сопровождая его автоматической генерацией странички help.
opts = info (actionParser <**> helper)
( fullDesc
<> progDesc "This application executes programms in L"
<> header "L interpreter"
)

runAction :: Action -> IO ()
runAction (Action (FileInput path) live varContext extend ir) = do
i <- readFile path
let context = newContext { Context.vars = [getVarContext varContext]}
case (ir, extend) of
(False, False) -> evalStateT (runLoop live i) context
(False, True) -> evalStateT (printExtended live i) context
(True, False) -> evalStateT (printIr live i) context
(True, True) -> evalStateT (do {printExtended live i; printIr live i}) context

-- выход: q
runAction (Action Interactive _ varContext extend ir) =
if extend || ir then error "can't handle extend or IR option in REPL mode" else
let context = newContext { Context.vars = [getVarContext varContext]} in
evalStateT readEvalWriteLoop context
1 change: 1 addition & 0 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
allow-newer: true
30 changes: 29 additions & 1 deletion package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ description: Please see the README on GitHub at <https://github.com/khbm

dependencies:
- base >= 4.7 && < 5
- containers
- transformers
- composition-prelude
- megaparsec
- parser-combinators
- mtl
- hoopl

ghc-options:
- -Wall
Expand All @@ -35,6 +42,11 @@ ghc-options:

library:
source-dirs: src
dependencies:
- containers
- optparse-applicative
- transformers
- megaparsec

executables:
L-static-analyzer-exe:
Expand All @@ -46,14 +58,30 @@ executables:
- -with-rtsopts=-N
dependencies:
- L-static-analyzer
- optparse-applicative

tests:
L-static-analyzer-test:
main: Spec.hs
main: Test.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- hedgehog
- HUnit
- HUnit-approx
- hspec
- hspec-megaparsec
- tasty
- tasty-hspec
- tasty-hedgehog
- tasty-hunit
- tasty-discover
- tasty-quickcheck
- L-static-analyzer
- HUnit
- tasty-hunit
- tasty
- transformers
Loading