Skip to content

Commit

Permalink
Parse macro definitions with arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
cruessler committed Feb 18, 2024
1 parent 9c51a1b commit 01cb5a5
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
8 changes: 8 additions & 0 deletions app/elm/Compiler/Ast.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module Compiler.Ast exposing
, CompiledProgram
, Context(..)
, Function
, Macro
, Node(..)
, Program
, compile
Expand Down Expand Up @@ -45,6 +46,13 @@ type alias Function =
}


type alias Macro =
{ name : String
, requiredArguments : List String
, body : List Node
}


{-| Represent a compiled function.
-}
type alias CompiledFunction =
Expand Down
32 changes: 32 additions & 0 deletions app/elm/Compiler/Parser.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Compiler.Parser exposing
, booleanExpression
, defaultState
, functionDefinition
, macroDefinition
, output
, statement
, term
Expand Down Expand Up @@ -235,6 +236,37 @@ functionBody_ state acc =
]


defineMacro : State -> Ast.Macro -> Parser Ast.Macro
defineMacro state newMacro =
functionBody state
|> P.map (\body -> { newMacro | body = body })


macroDefinition : State -> Parser Ast.Macro
macroDefinition state =
P.inContext MacroDefinition <|
(macroHeader
|> P.andThen (defineMacro state)
)


macroHeader : Parser Ast.Macro
macroHeader =
P.succeed Ast.Macro
|. Helper.keyword ".macro"
|. Helper.spaces
|= Helper.functionName
|= P.oneOf
[ P.succeed identity
|. P.backtrackable Helper.spaces
|= requiredArguments
, P.succeed []
]
|. Helper.maybeSpaces
|. Helper.symbol "\n"
|= P.succeed []


line : State -> Parser (List Ast.Node)
line state =
P.inContext Line <|
Expand Down
1 change: 1 addition & 0 deletions app/elm/Compiler/Parser/Context.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type Context
| Toplevel
| FunctionDefinition
| FunctionBody
| MacroDefinition
| Line
| Statements
| Statement
Expand Down
40 changes: 40 additions & 0 deletions tests/Test/Parser.elm
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,46 @@ functionDefinition =
]


parsesMacro : String -> Ast.Macro -> Expectation
parsesMacro source macro =
let
result =
Parser.run (Parser.macroDefinition defaultState) source
in
Expect.equal result (Ok macro)


macroDefinition : Test
macroDefinition =
describe "define a macro" <|
[ test "with mandatory arguments and no body" <|
\_ ->
parsesMacro ".macro foo :bar :baz\nend\n"
{ name = "foo"
, requiredArguments = [ "bar", "baz" ]
, body = []
}
, test "with mandatory argument and body" <|
\_ ->
parsesMacro ".macro foo :bar\nprint :bar\nend\n"
{ name = "foo"
, requiredArguments = [ "bar" ]
, body =
[ Ast.CommandN
{ name = "print", f = C.printN, numberOfDefaultArguments = 1 }
[ Ast.Variable "bar" ]
]
}
, test "without arguments" <|
\_ ->
parsesMacro ".macro foo\nend\n"
{ name = "foo"
, requiredArguments = []
, body = []
}
]


parsesArithmeticExpression : String -> Test
parsesArithmeticExpression expression =
let
Expand Down

0 comments on commit 01cb5a5

Please sign in to comment.