diff --git a/app/elm/Compiler/Ast.elm b/app/elm/Compiler/Ast.elm index 039013c..d8bbe38 100644 --- a/app/elm/Compiler/Ast.elm +++ b/app/elm/Compiler/Ast.elm @@ -85,6 +85,7 @@ type Node | Run Node | Make Node Node | Localmake Node Node + | Thing Node | Variable String | Value Type.Value | Raise Exception @@ -205,6 +206,9 @@ typeOfCallee node = Localmake _ _ -> Command { name = "localmake" } + Thing _ -> + Primitive { name = "thing" } + Variable name -> Primitive { name = name } @@ -786,6 +790,12 @@ compile context node = ] |> List.concat + Thing name -> + [ compileInContext (Expression { caller = "thing" }) name + , [ Instruction.Thing ] + ] + |> List.concat + Variable name -> [ PushVariable name ] diff --git a/app/elm/Compiler/Parser.elm b/app/elm/Compiler/Parser.elm index 2699554..7eedb16 100644 --- a/app/elm/Compiler/Parser.elm +++ b/app/elm/Compiler/Parser.elm @@ -290,6 +290,7 @@ statement state = , localmake state , make state , templateVariable + , thing state , variable , P.lazy (\_ -> functionCall state) , Value.value @@ -702,6 +703,16 @@ make state = ) +thing : State -> Parser Ast.Node +thing state = + P.inContext Thing <| + (P.succeed Ast.Thing + |. Helper.keyword "thing" + |. Helper.spaces + |= booleanExpression state + ) + + variable : Parser Ast.Node variable = P.inContext Variable <| diff --git a/app/elm/Compiler/Parser/Context.elm b/app/elm/Compiler/Parser/Context.elm index ed11c5a..ad98ab3 100644 --- a/app/elm/Compiler/Parser/Context.elm +++ b/app/elm/Compiler/Parser/Context.elm @@ -17,6 +17,7 @@ type Context | TemplateVariable | Localmake | Make + | Thing | Variable | ValueOutsideList | ValueInList diff --git a/app/elm/Vm/Instruction.elm b/app/elm/Vm/Instruction.elm index 4e5da56..96e467c 100644 --- a/app/elm/Vm/Instruction.elm +++ b/app/elm/Vm/Instruction.elm @@ -16,6 +16,7 @@ type Instruction | LocalVariable String | Make | Localmake + | Thing | Introspect0 I.Introspect0 | Introspect1 I.Introspect1 | Eval diff --git a/app/elm/Vm/Vm.elm b/app/elm/Vm/Vm.elm index cf3475a..98888be 100644 --- a/app/elm/Vm/Vm.elm +++ b/app/elm/Vm/Vm.elm @@ -119,6 +119,9 @@ encodeInstruction instruction = Localmake -> "Localmake" + Thing -> + "Thing" + Introspect0 { name } -> "Introspect0 " ++ name @@ -812,6 +815,30 @@ localmake vm = ) +thing : Vm -> Result Error Vm +thing vm = + popValue1 vm + |> Result.andThen + (\( name, newVm ) -> + name + |> Type.toWord + |> Result.mapError (\_ -> WrongInput "thing" (Type.toDebugString name)) + |> Result.andThen + (\word -> + case Scope.thing word vm.scopes of + Just (Defined value) -> + Ok + (newVm + |> pushValue1 value + |> incrementProgramCounter + ) + + _ -> + Err <| Error.VariableUndefined word + ) + ) + + pushLoopScope : Vm -> Result Error Vm pushLoopScope vm = popValue1 vm @@ -1061,6 +1088,9 @@ execute instruction vm = Localmake -> localmake vm + Thing -> + thing vm + Introspect0 primitive -> introspect0 primitive vm diff --git a/tests/Test/Run/Builtin.elm b/tests/Test/Run/Builtin.elm index 672e208..2cf67f7 100644 --- a/tests/Test/Run/Builtin.elm +++ b/tests/Test/Run/Builtin.elm @@ -1,4 +1,4 @@ -module Test.Run.Builtin exposing (commands, make, primitives, print, show) +module Test.Run.Builtin exposing (commands, make, primitives, print, show, thing) import Test exposing (Test, describe) import Test.Helper exposing (printsLine, runsWithoutError) @@ -179,3 +179,12 @@ make = , printsLine "make 1.1 1 print :1.1" "1" , printsLine "make 1.1 1 make :1.1 2 print :1" "2" ] + + +thing : Test +thing = + describe "thing" <| + [ printsLine "make \"a \"word print thing \"a" "word" + , printsLine "make \"a \"word make \"b \"a print thing :b" "word" + , printsLine "make \"a \"word make \"b \"a print thing thing \"b" "word" + ]