Skip to content
This repository has been archived by the owner on Aug 27, 2024. It is now read-only.

Commit

Permalink
Simplify AST to remove some redundancy (#4)
Browse files Browse the repository at this point in the history
* Copy code to project

* Add parser test

* Fix examples

* Update AST

* Add tests
  • Loading branch information
cakarsubasi authored Jun 17, 2024
1 parent ca7a110 commit c5daa9e
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 48 deletions.
2 changes: 1 addition & 1 deletion examples/isqrt.crn
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ crn = {
}],
step[{
ifLT[{ ld[znext, z] }],
ifGE[{ kd[z, out] }]
ifGE[{ ld[z, out] }]
}]
}
2 changes: 1 addition & 1 deletion examples/pi.crn
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ crn = {
add[divisor2, four, divisor2Next],
sub[factor1, factor2, factor],
add[pi, factor, piNext]
}]
}],
step[{
ld[divisor1Next, divisor1],
ld[divisor2Next, divisor2],
Expand Down
32 changes: 24 additions & 8 deletions src/crncc/AST.fs
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
module CRN.AST

[<RequireQualifiedAccess>]
type SpeciesS = string
type PNumberS = PNumber of float

type ConcS = Conc of SpeciesS * PNumberS
[<RequireQualifiedAccess>]
type PNumberS = float

type ExprS = Expr of list<SpeciesS>
[<RequireQualifiedAccess>]
type ValueS =
| Literal of string
| Number of PNumberS

type ReactionS = Reaction of ExprS * ExprS * PNumberS
[<RequireQualifiedAccess>]
type ConcS = SpeciesS * ValueS

[<RequireQualifiedAccess>]
type ExprS = list<SpeciesS>

[<RequireQualifiedAccess>]
type ReactionS = ExprS * ExprS * PNumberS

[<RequireQualifiedAccess>]
type ModuleS =
| Ld of SpeciesS * SpeciesS
| Add of SpeciesS * SpeciesS * SpeciesS
Expand All @@ -18,6 +30,7 @@ type ModuleS =
| Sqrt of SpeciesS * SpeciesS
| Cmp of SpeciesS * SpeciesS

[<RequireQualifiedAccess>]
type ConditionS =
| Gt of CommandS list
| Ge of CommandS list
Expand All @@ -30,10 +43,13 @@ and CommandS =
| Module of ModuleS
| Condition of ConditionS

type StepS = Step of list<CommandS>

[<RequireQualifiedAccess>]
type RootS =
| Conc of ConcS
| Step of StepS
| Step of CommandS list

[<RequireQualifiedAccess>]
type CrnS = list<RootS>

type CrnS = Crn of list<RootS>
type UntypedAST = CrnS
type TypedAST = CrnS
70 changes: 48 additions & 22 deletions src/crncc/Parser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ let private identifier =
let isChar c = isLetter c || isDigit c || c = '_'
many1Satisfy2L isFirstChar isChar "identifier" .>> ws

let private pspecies = identifier .>> ws |>> SpeciesS
let private pnumber = float_ws |>> PNumber
let private pspecies = identifier |>> SpeciesS
let private pconst = identifier

let private pexpr = sepBy pspecies (str_ws "+") .>> ws |>> Expr
//let private pnumber = float_ws |>> PNumberS
let private pnumber = float_ws

let private pexpr = sepBy pspecies (str_ws "+") .>> ws // |>> AST.ExprS

let private start_bracket bcopen start = str_ws start .>> str_ws bcopen

Expand All @@ -35,22 +38,24 @@ let private brackets2 popen pclose t1 t2 cons =
let private brackets3 popen pclose t1 t2 t3 cons =
pipe3 (popen >>. t1) (comma >>. t2) (comma >>. t3 .>> pclose) (fun v1 v2 v3 -> cons (v1, v2, v3))

let pvalue = choice [pconst |>> ValueS.Literal; pnumber |>> ValueS.Number]

let private pconc =
brackets2 (start_bracket "[" "conc") (end_bracket "]") pspecies pnumber ConcS.Conc
brackets2 (start_bracket "[" "conc") (end_bracket "]") pspecies pvalue ConcS

let private brackets3species name =
brackets3 (start_bracket "[" name) (end_bracket "]") pspecies pspecies pspecies

let private brackets2species name =
brackets2 (start_bracket "[" name) (end_bracket "]") pspecies pspecies

let private pmoduleld = brackets2species "ld" Ld
let private pmoduleadd = brackets3species "add" Add
let private pmodulesub = brackets3species "sub" Sub
let private pmodulemul = brackets3species "mul" Mul
let private pmodulediv = brackets3species "div" Div
let private pmodulesqrt = brackets2species "sqrt" Sqrt
let private pmodulecmp = brackets2species "cmp" Cmp
let private pmoduleld = brackets2species "ld" ModuleS.Ld
let private pmoduleadd = brackets3species "add" ModuleS.Add
let private pmodulesub = brackets3species "sub" ModuleS.Sub
let private pmodulemul = brackets3species "mul" ModuleS.Mul
let private pmodulediv = brackets3species "div" ModuleS.Div
let private pmodulesqrt = brackets2species "sqrt" ModuleS.Sqrt
let private pmodulecmp = brackets2species "cmp" ModuleS.Cmp

let private pmodule =
choice
Expand All @@ -63,7 +68,7 @@ let private pmodule =
pmodulecmp ]

let private prxn =
brackets3 (start_bracket "[" "rxn") (end_bracket "]") pexpr pexpr pnumber ReactionS.Reaction
brackets3 (start_bracket "[" "rxn") (end_bracket "]") pexpr pexpr pnumber ReactionS

let private listparser popen pclose listelem =
between popen pclose (sepBy listelem (str_ws ","))
Expand All @@ -84,30 +89,51 @@ let private commandclose = str_ws "}" .>> str_ws "]"
let private pcommandlist start =
listparser (commandopen start) commandclose pcommand

let private pcmdif = pcommandlist "ifGT" |>> Gt
let private pcmdge = pcommandlist "ifGE" |>> Ge
let private pcmdeq = pcommandlist "ifEQ" |>> Eq
let private pcmdlt = pcommandlist "ifLT" |>> Lt
let private pcmdle = pcommandlist "ifLE" |>> Le
let private pcmdif = pcommandlist "ifGT" |>> ConditionS.Gt
let private pcmdge = pcommandlist "ifGE" |>> ConditionS.Ge
let private pcmdeq = pcommandlist "ifEQ" |>> ConditionS.Eq
let private pcmdlt = pcommandlist "ifLT" |>> ConditionS.Lt
let private pcmdle = pcommandlist "ifLE" |>> ConditionS.Le

pconref.Value <- choice [ pcmdif; pcmdge; pcmdeq; pcmdlt; pcmdle ]

let private pstep = pcommandlist "step" |>> StepS.Step
let private pstep = pcommandlist "step" |>> RootS.Step

let private proot = choice [ pstep |>> RootS.Step; pconc |>> RootS.Conc ]
let private proot = choice [ pstep; pconc |>> RootS.Conc ]

let private crnopen = str_ws "crn" >>. str_ws "=" .>> str_ws "{"

let private crnclose = str_ws "}"
let private curlyparser = listparser crnopen crnclose
let private pcrn = ws >>. curlyparser proot .>> eof |>> Crn

let private pcrn = ws >>. curlyparser proot .>> eof

let tryParse str =
let result = run pcrn str

match result with
| Success(output, _, _) -> Some(output)
| Failure(errorMsg, _, _) ->
printfn "Failure: %s" errorMsg
None

module RXN =
let private rxncommand = prxn |>> CommandS.Reaction

let private pcommandlist start =
listparser (commandopen start) commandclose rxncommand

let private pstep = pcommandlist "step"

let private proot = choice [ pstep |>> RootS.Step; pconc |>> RootS.Conc ]

let private pcrnrxn = ws >>. curlyparser proot .>> eof

let tryParse str: Option<UntypedAST> =
let result = run pcrn str

match result with
| Success(output, _, _) -> Some(output)
| Failure(errorMsg, _, _) ->
printfn "Failure: %s" errorMsg
None

56 changes: 40 additions & 16 deletions test/crncc_test/Tests.fs
Original file line number Diff line number Diff line change
@@ -1,25 +1,49 @@
module Tests

open Xunit
open System
open CRN.Parser


let example =
"crn = {
conc[c, 5.0], conc[cInitial, 4.0],
conc[one, 1], conc[zero, 0],
step[{
sub[c, one, cnext],
cmp[c, zero]
}],
step[{
ifGT[{ ld[cnext, c] }],
ifLE[{ ld[cInitial, c] }]
}]
}"
let getTestFile name =
let path = System.IO.Path.Combine("../../../../../examples/", name)
IO.File.ReadAllText path

let testParser name =
let file = getTestFile name
tryParse file


[<Fact>]
let ``Parser: counter.crn`` () =
let result = testParser "counter.crn"
Assert.True(result.IsSome, result.ToString())

[<Fact>]
let ``Parser: division.crn`` () =
Assert.True((testParser "division.crn").IsSome)

[<Fact>]
let ``Parser: euler.crn`` () =
Assert.True((testParser "euler.crn").IsSome)

[<Fact>]
let ``My test`` () =
let ``Parser: gcd.crn`` () =
Assert.True((testParser "gcd.crn").IsSome)

let maybeast = tryParse example
Assert.True(maybeast.IsSome)
[<Fact>]
let ``Parser: isqrt.crn`` () =
Assert.True((testParser "isqrt.crn").IsSome)

[<Fact>]
let ``Parser: pi.crn`` () =
let result = testParser "pi.crn"
Assert.True(result.IsSome, result.ToString())

[<Fact>]
let ``Parser: subalt.crn`` () =
Assert.True((testParser "subalt.crn").IsSome)

[<Fact>]
let ``Parser: factorial.crn`` () =
Assert.True((testParser "factorial.crn").IsSome)

0 comments on commit c5daa9e

Please sign in to comment.