Skip to content
This repository was archived by the owner on Oct 5, 2024. It is now read-only.

parser lexer #112

Draft
wants to merge 103 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
a216421
lex any elm program!
harrysarson Aug 4, 2020
1dacf19
add some operator tests
harrysarson Aug 5, 2020
39d0527
drop the Binary from BinaryOperator
harrysarson Aug 5, 2020
1e09457
sketch of contextualising
harrysarson Sep 24, 2020
664bc01
prefix constructors with custom type name
harrysarson Sep 24, 2020
f926996
we can parse "type alias Model = List Int"!
harrysarson Sep 24, 2020
ec5ca01
add visualiser
harrysarson Sep 24, 2020
d9c7650
refactor function layout
harrysarson Sep 24, 2020
cced4b7
use explicit parse result type
harrysarson Sep 24, 2020
b4b00ae
add automatic parser/test test generation
harrysarson Sep 24, 2020
00a8ebe
add extra parser/lexer test cases
harrysarson Sep 25, 2020
5b72af1
improve test case formatting
harrysarson Sep 25, 2020
abda9e1
remove current state from errors
harrysarson Sep 25, 2020
370eeeb
add type alias test cases with brackets
harrysarson Sep 25, 2020
55e6b04
error in regenerate on panic
harrysarson Sep 25, 2020
cd97b4c
reject multiline types with no indentation
harrysarson Sep 25, 2020
7322d79
rework nesting
harrysarson Sep 25, 2020
2be359c
fix meaning of type does not take args error
harrysarson Sep 25, 2020
b57721f
rework handling of complete type aliases
harrysarson Sep 25, 2020
fbdc055
collect things together better
harrysarson Sep 25, 2020
01ce21a
lay groundwork for record types
harrysarson Sep 25, 2020
2dad110
extract argument adding logic to function
harrysarson Sep 25, 2020
7bfb032
unify adding functions for tokens and types
harrysarson Sep 25, 2020
0b341b4
further unicode type expr parsing
harrysarson Sep 26, 2020
e851497
correctly parse recording in type aliases!
harrysarson Sep 26, 2020
d02f75d
fix nesting
harrysarson Sep 26, 2020
59c7ecb
deduplicate bracketstack handling code
harrysarson Sep 26, 2020
cf139f3
change arg order to simply adding to types
harrysarson Sep 26, 2020
340c030
deduplicate adding thigns to records
harrysarson Sep 26, 2020
7ff6e4a
correctly parse empty records
harrysarson Sep 26, 2020
c6a5fae
specify whether test snippets should parse or not
harrysarson Sep 26, 2020
316ec0e
unnest case-of expresions in parser
harrysarson Sep 26, 2020
c528a0e
prepare to use nestingStack for records
harrysarson Sep 26, 2020
25c923c
use nesting stack for records
harrysarson Sep 26, 2020
b205c53
parse tuples
harrysarson Sep 26, 2020
725fd1c
fix test cases
harrysarson Sep 26, 2020
f8ca5d3
fix list ordering of collectList
harrysarson Sep 28, 2020
11109bf
add three key record test snippet
harrysarson Sep 28, 2020
d1d0922
use list for record entries
harrysarson Sep 28, 2020
cd69bac
add bracket in record test case
harrysarson Sep 30, 2020
277570f
wip: use nesting stack for type with args
harrysarson Oct 3, 2020
e83034f
test the correct cases
harrysarson Oct 3, 2020
5c554b1
correctly lex -> items
harrysarson Oct 3, 2020
da88025
include failing item in error
harrysarson Oct 4, 2020
d98c20d
first attempt at parsing function types
harrysarson Oct 5, 2020
a5a86a8
split parseTypeExpr in two for first lex item
harrysarson Oct 5, 2020
8b996be
add curried function type expression
harrysarson Oct 5, 2020
8a2b911
fix: binding of curried function types
harrysarson Oct 5, 2020
a0c7d37
move some logic out of main type parser
harrysarson Oct 5, 2020
f05c2e4
move some more logic out of main type parser
harrysarson Oct 5, 2020
95139d6
start deduplicating code
harrysarson Oct 5, 2020
5c504a0
move record closing into new function
harrysarson Oct 5, 2020
0b05330
improve bad bracket errors
harrysarson Oct 5, 2020
52da3ce
handle nested function types correctly
harrysarson Oct 5, 2020
cd5edb0
add generic args to trype alias AST
harrysarson Oct 5, 2020
3779ea5
parse generic type args in type alias
harrysarson Oct 5, 2020
29cc96a
drop unused custom type variant
harrysarson Oct 5, 2020
96fb398
propagate lex locations further
harrysarson Oct 5, 2020
7438f2d
parse expressions (wip)
harrysarson Oct 5, 2020
a881c56
hack test case generation to avoid name clashes
harrysarson Oct 6, 2020
161a849
fix test cases that use a number instead of a type
harrysarson Oct 6, 2020
41c88ef
change field order in test cases
harrysarson Oct 6, 2020
4da8eee
delete unused functions
harrysarson Oct 6, 2020
263c9c2
share partial results between types and exprs
harrysarson Oct 6, 2020
270d8fb
add type annotations
harrysarson Oct 6, 2020
10c68be
Revert "add type annotations"
harrysarson Oct 6, 2020
bd0596e
extract operators from parsing stage
harrysarson Oct 6, 2020
564eaf3
start to implement operators
harrysarson Oct 6, 2020
400c40e
use operator in AST
harrysarson Oct 6, 2020
08a337a
parse operators
harrysarson Oct 6, 2020
43ebf77
add multiply/divide test case
harrysarson Oct 6, 2020
ca7c5f7
format code
harrysarson Oct 6, 2020
08a388b
add pretty printed AST to test cases
harrysarson Oct 7, 2020
12df300
proper comparison of operator precedence
harrysarson Oct 7, 2020
ca09eed
proper collapsing of operators
harrysarson Oct 7, 2020
a5c948b
parse operators with different precedence
harrysarson Oct 7, 2020
878d58d
add locations to operators
harrysarson Oct 18, 2020
a6ee783
lex X.Y.z as single items
harrysarson Oct 19, 2020
b062737
lex .thing as a record accessor literal or function.
harrysarson Oct 19, 2020
a355184
restructure lexer
harrysarson Oct 19, 2020
1d9c0e1
make newlines a top level lex thing
harrysarson Oct 19, 2020
3c04019
apply intellij suggestions
harrysarson Oct 19, 2020
4090dd0
fix printy printing
harrysarson Oct 19, 2020
fe884e8
stop not using value
harrysarson Oct 19, 2020
9d47040
remove "Partial" from TypeExpression
harrysarson Oct 19, 2020
ad3d8a0
use parent struct from TypeExpressions
harrysarson Oct 19, 2020
790b3c5
wip: case sensitive lexing
harrysarson Oct 22, 2020
f02c872
do not stop parsing on first error
harrysarson Oct 22, 2020
f16d3c3
we do not need partial results
harrysarson Oct 22, 2020
776ebcf
use normal results in more places
harrysarson Oct 23, 2020
33a7a7e
more sane results in return types
harrysarson Oct 23, 2020
a572cae
undo elm format for block
harrysarson Oct 23, 2020
05428f0
inline collapseNesting calls
harrysarson Oct 23, 2020
d2489a5
do not call a type partial when it is not
harrysarson Oct 23, 2020
0564e9c
make impossible states impossible
harrysarson Oct 23, 2020
49f6497
separate collapsing functions
harrysarson Oct 23, 2020
4b91f1d
allow qualified type names at top level
harrysarson Oct 25, 2020
5e48cd3
move post processing out of fn
harrysarson Oct 25, 2020
14537f3
tidy parseLowercaseArgsOrAssignment
harrysarson Oct 25, 2020
96c3269
Include the (partial) type arg in Error_TypeDoesNotTakeArgs
harrysarson Oct 25, 2020
626b543
tidy leaf to parent (slightly)
harrysarson Oct 25, 2020
df9e3cf
rename functions
harrysarson Oct 25, 2020
4eaf664
more type trickery to avoid callbacks
harrysarson Oct 26, 2020
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
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ FORMAT_DIRS = \
cli \
example-library-usages \
src \
tests
tests \
parser-tests \

.PHONY: run
run: build
Expand Down Expand Up @@ -35,6 +36,15 @@ test: build
npx elm-test
npx ava

.PHONY: regenerate
regenerate:
cd parser-tests \
&& npx elm make Update.elm --output elm.js \
&& node --unhandled-rejections=strict update \
; CODE=$$? \
; elm-format ../tests/ParserLexerTestCases.elm --yes \
; exit $$CODE

.PHONY: format
format:
npx elm-format $(FORMAT_DIRS) --yes
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/cli/non-zero-exit-error/test.test.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ Generated by [AVA](https://avajs.dev).
`---------------------------␊
-- STARTING THE COMPILER --␊
---------------------------␊
Main.main: Value { expression = Plus (Int 1) (Var { name = "y", qualifiedness = PossiblyQualified Nothing }), typeAnnotation = Nothing }␊
Main.main: Value { expression = Operator Add (Int 1) (Var { name = "y", qualifiedness = PossiblyQualified Nothing }), typeAnnotation = Nothing }␊
`
Binary file modified integration-tests/cli/non-zero-exit-error/test.test.js.snap
Binary file not shown.
2 changes: 1 addition & 1 deletion integration-tests/cli/two-source/test.test.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Generated by [AVA](https://avajs.dev).
`---------------------------␊
-- STARTING THE COMPILER --␊
---------------------------␊
Main.main: Value { expression = Plus (Int 1) (Var { name = "x", qualifiedness = PossiblyQualified (Just "Lib") }), typeAnnotation = Nothing }␊
Main.main: Value { expression = Operator Add (Int 1) (Var { name = "x", qualifiedness = PossiblyQualified (Just "Lib") }), typeAnnotation = Nothing }␊
Lib.x: Value { expression = Int 4, typeAnnotation = Nothing }␊
Compilation finished, writing output to `out.js`.␊
---------------------------␊
Expand Down
Binary file modified integration-tests/cli/two-source/test.test.js.snap
Binary file not shown.
2 changes: 1 addition & 1 deletion integration-tests/desugar/import/test.test.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Generated by [AVA](https://avajs.dev).
`---------------------------␊
-- STARTING THE COMPILER --␊
---------------------------␊
Main.main: Value { expression = Plus (Int 1) (Var { name = "x", qualifiedness = PossiblyQualified (Just "Lib") }), typeAnnotation = Nothing }␊
Main.main: Value { expression = Operator Add (Int 1) (Var { name = "x", qualifiedness = PossiblyQualified (Just "Lib") }), typeAnnotation = Nothing }␊
Lib.x: Value { expression = Int 4, typeAnnotation = Nothing }␊
Compilation finished, writing output to `out.js`.␊
---------------------------␊
Expand Down
Binary file modified integration-tests/desugar/import/test.test.js.snap
Binary file not shown.
4 changes: 2 additions & 2 deletions integration-tests/parser/add-5/test.test.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ Generated by [AVA](https://avajs.dev).
`---------------------------␊
-- STARTING THE COMPILER --␊
---------------------------␊
Main.main: Value { expression = Plus (Int 7) (Int 6), typeAnnotation = Nothing }␊
Main.f: Value { expression = Lambda { arguments = ["x"], body = Plus (Int 5) (Argument "x") }, typeAnnotation = Nothing }␊
Main.main: Value { expression = Operator Add (Int 7) (Int 6), typeAnnotation = Nothing }␊
Main.f: Value { expression = Lambda { arguments = ["x"], body = Operator Add (Int 5) (Argument "x") }, typeAnnotation = Nothing }␊
Compilation finished, writing output to `out.js`.␊
---------------------------␊
-- WRITING TO FS ----------␊
Expand Down
Binary file modified integration-tests/parser/add-5/test.test.js.snap
Binary file not shown.
2 changes: 1 addition & 1 deletion integration-tests/parser/if-then-else/test.test.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Generated by [AVA](https://avajs.dev).
`---------------------------␊
-- STARTING THE COMPILER --␊
---------------------------␊
Main.main: Value { expression = Plus (Call { argument = Bool True, fn = Var { name = "f", qualifiedness = PossiblyQualified Nothing } }) (Call { argument = Bool False, fn = Var { name = "f", qualifiedness = PossiblyQualified Nothing } }), typeAnnotation = Nothing }␊
Main.main: Value { expression = Operator Add (Call { argument = Bool True, fn = Var { name = "f", qualifiedness = PossiblyQualified Nothing } }) (Call { argument = Bool False, fn = Var { name = "f", qualifiedness = PossiblyQualified Nothing } }), typeAnnotation = Nothing }␊
Main.f: Value { expression = Lambda { arguments = ["x"], body = If { else_ = Int 2, test = Argument "x", then_ = Int 18 } }, typeAnnotation = Nothing }␊
Compilation finished, writing output to `out.js`.␊
---------------------------␊
Expand Down
Binary file modified integration-tests/parser/if-then-else/test.test.js.snap
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Generated by [AVA](https://avajs.dev).
`---------------------------␊
-- STARTING THE COMPILER --␊
---------------------------␊
Main.main: Value { expression = Let { bindings = [{ body = Plus (Int 1) (Int 2), name = "x" }], body = Argument "x" }, typeAnnotation = Nothing }␊
Main.main: Value { expression = Let { bindings = [{ body = Operator Add (Int 1) (Int 2), name = "x" }], body = Argument "x" }, typeAnnotation = Nothing }␊
Compilation finished, writing output to `out.js`.␊
---------------------------␊
-- WRITING TO FS ----------␊
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Generated by [AVA](https://avajs.dev).
`---------------------------␊
-- STARTING THE COMPILER --␊
---------------------------␊
Main.main: Value { expression = Let { bindings = [{ body = Int 2, name = "x" }], body = Plus (Int 1) (Argument "x") }, typeAnnotation = Nothing }␊
Main.main: Value { expression = Let { bindings = [{ body = Int 2, name = "x" }], body = Operator Add (Int 1) (Argument "x") }, typeAnnotation = Nothing }␊
Compilation finished, writing output to `out.js`.␊
---------------------------␊
-- WRITING TO FS ----------␊
Expand Down
Binary file not shown.
1 change: 1 addition & 0 deletions parser-tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/elm.js
159 changes: 159 additions & 0 deletions parser-tests/Live.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
module Live exposing (main)

import Browser
import Elm.Data.Located as Located
import Html exposing (Html)
import Html.Attributes as Attributes
import Html.Events as Events
import Parser.Advanced as P
import Stage.Parse.Contextualize as Contextualize
import Stage.Parse.Lexer as Lexer
import Stage.Parse.Pretty as Pretty


{-| We're essentially a Node.JS app (until we get self-hosting :P ).
So, `Platform.worker` is the only option for us.
-}
main : Program () String Msg
main =
Browser.element
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}


{-| `Compiling` is the state we'll be most of the time. The other two are
mostly useless; they do effectively stop `subscriptions` and `update` though.
-}
type alias Model =
String


type Msg
= NewString String


subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none


init : () -> ( Model, Cmd never )
init () =
( """type alias Model = { h: (""", Cmd.none )


view : Model -> Html Msg
view model =
let
source =
model

lexed =
P.run Lexer.parser source
in
Html.div
[ Attributes.style "display" "flex"
, Attributes.style "flex-direction" "row"
]
[ Html.div
[]
[ Html.textarea
[ Events.onInput <| NewString
, Attributes.value source
, Attributes.rows 20
, Attributes.cols 80
]
[]
, Html.div
[ Attributes.style "font-family" "monospace" ]
-- [ Attributes.style "w" ]
(case lexed of
Ok lexItems ->
lexItems
|> List.map
(\item ->
let
{ start, end } =
Located.getRegion item
in
Html.div
[ Attributes.style "white-space" "pre-wrap" ]
[ Html.text
("("
++ String.padLeft 3 '0' (String.fromInt start.row)
++ ", "
++ String.padLeft 3 '0' (String.fromInt start.col)
++ ") - ("
++ String.padLeft 3 '0' (String.fromInt end.row)
++ ", "
++ String.padLeft 3 '0' (String.fromInt end.col)
++ "): \""
++ (item |> Located.unwrap |> Lexer.toString |> String.replace " " "·")
++ "\" "
++ (item |> Located.unwrap |> Debug.toString)
)
]
)

Err e ->
[ Html.text (Debug.toString e) ]
)
]
, Html.div
[ Attributes.style "font-family" "monospace" ]
-- [ Attributes.style "w" ]
(case lexed of
Ok lexItems ->
let
contextualized =
Contextualize.run lexItems
in
[ Html.div
[ Attributes.style "white-space" "pre-wrap" ]
[ Html.div
[]
[ Html.text
(Debug.toString (Debug.log "parsed" <| contextualized))
]
, Html.div
[]
[ Html.text
(Pretty.printWithIndentationOf 0
(Pretty.listWith
(\rBlock ->
case rBlock of
Ok block ->
Pretty.Many
[ Pretty.Atom "Ok"
, Pretty.block block
]

Err e ->
Pretty.Many
[ Pretty.Atom "Err"
, Pretty.Many
[ Pretty.pair "state" (Pretty.state e.state)
]
]
)
contextualized
)
)
]
]
]

Err e ->
[]
)
]


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NewString string ->
( string, Cmd.none )
Loading