Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add local #253

Merged
merged 1 commit into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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