Skip to content

Commit

Permalink
Add local
Browse files Browse the repository at this point in the history
  • Loading branch information
cruessler committed Feb 18, 2024
1 parent e2a4e1c commit 3d97734
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 0 deletions.
10 changes: 10 additions & 0 deletions app/elm/Compiler/Ast.elm
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ type Node
| Run Node
| Make Node Node
| Localmake Node Node
| Local Node
| Thing Node
| Variable String
| Value Type.Value
Expand Down Expand Up @@ -234,6 +235,9 @@ typeOfCallee node =
Localmake _ _ ->
Command { name = "localmake" }

Local _ ->
Command { name = "local" }

Thing _ ->
Primitive { name = "thing" }

Expand Down Expand Up @@ -881,6 +885,12 @@ compile context node =
]
|> List.concat

Local name ->
[ compileInContext (Expression { caller = "local" }) name
, [ Instruction.Local ]
]
|> List.concat

Thing name ->
[ compileInContext (Expression { caller = "thing" }) name
, [ Instruction.Thing ]
Expand Down
11 changes: 11 additions & 0 deletions app/elm/Compiler/Parser.elm
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ statement state =
, P.lazy (\_ -> run state)
, stop
, localmake state
, local state
, make state
, templateVariable
, thing state
Expand Down Expand Up @@ -800,6 +801,16 @@ localmake state =
)


local : State -> Parser Ast.Node
local state =
P.inContext Local <|
(P.succeed Ast.Local
|. Helper.keyword "local"
|. Helper.spaces
|= booleanExpression state
)


make : State -> Parser Ast.Node
make state =
P.inContext Make <|
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 @@ -17,6 +17,7 @@ type Context
| InParentheses
| TemplateVariable
| Localmake
| Local
| Make
| Thing
| Variable
Expand Down
1 change: 1 addition & 0 deletions app/elm/Vm/Instruction.elm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Instruction
| LocalVariable String
| Make
| Localmake
| Local
| Thing
| Introspect0 I.Introspect0
| Introspect1 I.Introspect1
Expand Down
27 changes: 27 additions & 0 deletions app/elm/Vm/Vm.elm
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ encodeInstruction instruction =
Localmake ->
"Localmake"

Local ->
"Local"

Thing ->
"Thing"

Expand Down Expand Up @@ -858,6 +861,27 @@ localmake vm =
)


local : Vm -> Result Error Vm
local vm =
popValue1 vm
|> Result.andThen
(\( name, newVm ) ->
name
|> Type.toWord
|> Result.map
(\word ->
let
newScopes =
vm.scopes
|> Scope.local word
in
{ newVm | scopes = newScopes }
|> incrementProgramCounter
)
|> Result.mapError (\_ -> WrongInput "local" (Type.toDebugString name))
)


thing : Vm -> Result Error Vm
thing vm =
popValue1 vm
Expand Down Expand Up @@ -1134,6 +1158,9 @@ execute instruction vm =
Localmake ->
localmake vm

Local ->
local vm

Thing ->
thing vm

Expand Down
6 changes: 6 additions & 0 deletions tests/Test/Error.elm
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ functionsWithInvalidArguments =
, printsError "print fput \"wo \"rd" "fput doesn’t like wo as input"
, printsError "make [] 1" "make doesn’t like [] as input"
, printsError "localmake [] 1" "localmake doesn’t like [] as input"
, printsError "local []" "local doesn’t like [] as input"
]


Expand Down Expand Up @@ -151,6 +152,11 @@ undefinedVariable =
describe "prints error if undefined variable is used" <|
[ printsError "print :variable" "variable has no value"
, printsError ":variable" "variable has no value"
, printsError """to f
local "v make "v 1 print :v
end
f
print :v""" "v has no value"
]


Expand Down
12 changes: 12 additions & 0 deletions tests/Test/Run.elm
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,18 @@ foo"""
]


local : Test
local =
describe "variable defined by local is available in called function" <|
[ printsLines
"""to f :recurse
ifelse :recurse [ local "v make "v "word f "false ] [ print :v ]
end
f "true"""
[ "word" ]
]


optionalArguments : Test
optionalArguments =
describe "define function with default value for optional parameter" <|
Expand Down

0 comments on commit 3d97734

Please sign in to comment.