diff --git a/HISTORY.md b/HISTORY.md index 0fe64ef..5f90f6c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -12,11 +12,18 @@ the macro itself as the first argument to the macro.) The Robin definitions of macros in the standard library such as `let` and `list` have been rewritten this way. +* The object that a `macro` form evaluates to is no + longer called a "macro". It is an "operator". There + there are other ways to obtain an operator than applying + a `macro` form (for instance there have always been + intrinsic operators; it's not fair to call them "macros".) For the reference implementation, * Fixed recent import changes which prevented it from running under Hugs. +* The `Macro` type of expressions has been removed, + and `Builtin` renamed `Operator`. Robin 0.7 --------- diff --git a/build-packages.sh b/build-packages.sh index 8ecb8e6..844f8b0 100755 --- a/build-packages.sh +++ b/build-packages.sh @@ -5,7 +5,7 @@ mkdir -p pkg cat stdlib/abort.robin stdlib/equal-p.robin stdlib/eval.robin stdlib/head.robin \ - stdlib/if.robin stdlib/list-p.robin stdlib/macro-p.robin stdlib/macro.robin \ + stdlib/if.robin stdlib/list-p.robin stdlib/operator-p.robin stdlib/macro.robin \ stdlib/number-p.robin stdlib/prepend.robin stdlib/recover.robin stdlib/sign.robin \ stdlib/subtract.robin stdlib/symbol-p.robin stdlib/tail.robin \ > pkg/intrinsics.robin diff --git a/doc/Robin.md b/doc/Robin.md index 5c688c4..7c4169a 100644 --- a/doc/Robin.md +++ b/doc/Robin.md @@ -314,6 +314,8 @@ ### Macros ### +TODO rewrite this section + A macro is a term which, in an environment, describes how to translate one S-expression to another. @@ -344,13 +346,13 @@ Macros evaluate to themselves. -Macros are represented as the S-expression expansion of their -implementation. +Operators are represented as an opaque descriptor (TODO this should be the +metadata of the operator.) | (macro (args env) args) - = (macro (args env) args) - -Macros can be applied, and that is the typical use of them. + = <macro> + +Operators can be applied, and that is the typical use of them. | ((macro (args env) args) 1) = (1) diff --git a/src/Language/Robin/Eval.hs b/src/Language/Robin/Eval.hs index 60f0e70..c0ef552 100644 --- a/src/Language/Robin/Eval.hs +++ b/src/Language/Robin/Eval.hs @@ -39,16 +39,13 @@ -- -- Evaluating a list means we must make several evaluations. We -- evaluate the head to obtain something to apply (which must be a --- macro or intrinsic.) We then apply the body of the macro, --- passing it the tail of the list. +-- "builtin".) We then apply the "builtin", passing it the tail of the list. -- eval env (List (applierExpr:actuals)) cc = eval env applierExpr (\applier -> case applier of - m@(Macro _ _ body) -> - eval (makeMacroEnv env (List actuals) m) body cc - b@(Builtin _ fun) -> + Builtin _ fun -> fun env (List actuals) cc other -> errMsg "inapplicable-object" other) @@ -68,14 +65,22 @@ errMsg msg term = Abort (List [(Symbol msg), term]) -makeMacroEnv :: Env -> Expr -> Expr -> Env -makeMacroEnv env actuals m@(Macro closedEnv argList _) = +makeMacro :: Expr -> Expr -> Expr -> Evaluable +makeMacro defineTimeEnv formals body = + \callTimeEnv actuals cc -> + let + env = makeMacroEnv callTimeEnv actuals defineTimeEnv formals + in + eval env body cc + +makeMacroEnv callTimeEnv actuals defineTimeEnv argList = let (List [(Symbol argFormal), (Symbol envFormal)]) = argList - newEnv' = insert argFormal actuals closedEnv - newEnv'' = insert envFormal env newEnv' + newEnv' = insert argFormal actuals defineTimeEnv + newEnv'' = insert envFormal callTimeEnv newEnv' in newEnv'' + -- -- Assertions @@ -90,4 +95,4 @@ assertBoolean env = assert env (isBoolean) "expected-boolean" assertList env = assert env (isList) "expected-list" assertNumber env = assert env (isNumber) "expected-number" -assertMacro env = assert env (isMacro) "expected-macro" +assertOperator env = assert env (isOperator) "expected-operator" diff --git a/src/Language/Robin/Expr.hs b/src/Language/Robin/Expr.hs index ab2ef42..2bf6a55 100644 --- a/src/Language/Robin/Expr.hs +++ b/src/Language/Robin/Expr.hs @@ -20,7 +20,6 @@ data Expr = Symbol String | Boolean Bool | Number Int32 - | Macro Expr Expr Expr -- the 1st Expr is actually an Env | Builtin String Evaluable | List [Expr] | Abort Expr @@ -29,7 +28,6 @@ (Symbol x) == (Symbol y) = x == y (Boolean x) == (Boolean y) = x == y (Number x) == (Number y) = x == y - (Macro e1 a1 b1) == (Macro e2 a2 b2) = e1 == e2 && a1 == a2 && b1 == b2 (Builtin x _) == (Builtin y _) = x == y (List x) == (List y) = x == y (Abort x) == (Abort y) = x == y @@ -40,8 +38,6 @@ show (Boolean True) = "#t" show (Boolean False) = "#f" show (Number n) = show n - show (Macro env args body) = ("(macro " ++ (show args) ++ - " " ++ (show body) ++ ")") show (Builtin name _) = name show (Abort e) = "(abort " ++ (show e) ++ ")" show (List exprs) = "(" ++ (showl exprs) ++ ")" where @@ -72,9 +68,8 @@ isList (List _) = True isList _ = False -isMacro (Macro _ _ _) = True -isMacro (Builtin _ _) = True -isMacro _ = False - isAbort (Abort _) = True isAbort _ = False + +isOperator (Builtin _ _) = True +isOperator _ = False diff --git a/src/Language/Robin/Intrinsics.hs b/src/Language/Robin/Intrinsics.hs index 0538be8..72b1d30 100644 --- a/src/Language/Robin/Intrinsics.hs +++ b/src/Language/Robin/Intrinsics.hs @@ -42,7 +42,7 @@ symbolP = predP isSymbol listP = predP isList -macroP = predP isMacro +operatorP = predP isOperator numberP = predP isNumber subtract :: Evaluable @@ -80,7 +80,7 @@ macro :: Evaluable macro env (List [args@(List [(Symbol argsS), (Symbol envS)]), body]) cc = - cc $ Macro env args body + cc $ Builtin "<macro>" $ makeMacro env args body macro env other cc = errMsg "illegal-arguments" other abort :: Evaluable @@ -106,7 +106,7 @@ ("prepend", prepend), ("list?", listP), ("symbol?", symbolP), - ("macro?", macroP), + ("operator?",operatorP), ("number?", numberP), ("equal?", equalP), ("subtract", Language.Robin.Intrinsics.subtract), diff --git a/src/QuickCheckTests.hs b/src/QuickCheckTests.hs index 7635e5e..955346a 100644 --- a/src/QuickCheckTests.hs +++ b/src/QuickCheckTests.hs @@ -34,8 +34,8 @@ let n' = n `div` (m + 1) oneof [ Abort <$> (arbExpr n'), - List <$> (arbExprList n'), - Macro <$> (arbExpr n') <*> (arbExpr n') <*> (arbExpr n') + List <$> (arbExprList n') + -- TODO Operator ?? ] arbExprList :: Int -> Gen [Expr] diff --git a/stdlib/macro-p.robin b/stdlib/macro-p.robin deleted file mode 100644 index 7227c1d..0000000 --- a/stdlib/macro-p.robin +++ /dev/null @@ -1,39 +0,0 @@ -;'<<SPEC' - -### `macro?` ### - - -> Tests for functionality "Evaluate core Robin Expression" - -`macro?` evaluates its argument, then evaluates to `#t` if it is a macro, -or `#f` if it is not. - - | (macro? (macro (args env) args)) - = #t - -Intrinsic macros are macros. - - | (macro? macro) - = #t - -Literal symbols are not macros, even if they're the name of one. - - | (macro? ((macro (args env) (head args)) macro)) - = #f - -Numbers are not macros. - - | (macro? 5) - = #f - -The argument to `macro?` may (naturally) be any type, but there must be -exactly one argument. - - | (macro? macro macro) - ? abort (illegal-arguments (macro macro)) - - | (macro?) - ? abort (illegal-arguments ()) - -'<<SPEC' - -(require macro?) diff --git a/stdlib/operator-p.robin b/stdlib/operator-p.robin new file mode 100644 index 0000000..cfc39e7 --- /dev/null +++ b/stdlib/operator-p.robin @@ -0,0 +1,39 @@ +;'<<SPEC' + +### `operator?` ### + + -> Tests for functionality "Evaluate core Robin Expression" + +`operator?` evaluates its argument, then evaluates to `#t` if it is an operator, +or `#f` if it is not. + + | (operator? (macro (args env) args)) + = #t + +Intrinsic operators are operators. + + | (operator? macro) + = #t + +Literal symbols are not operators, even if they're the name of one. + + | (operator? ((macro (args env) (head args)) macro)) + = #f + +Numbers are not operators. + + | (operator? 5) + = #f + +The argument to `operator?` may (naturally) be any type, but there must be +exactly one argument. + + | (operator? macro macro) + ? abort (illegal-arguments (macro macro)) + + | (operator?) + ? abort (illegal-arguments ()) + +'<<SPEC' + +(require operator?)