git @ Cat's Eye Technologies Robin / a5f4aff
Remove `Macro` type internally, replace `macro?` with `operator?` Chris Pressey 4 years ago
9 changed file(s) with 77 addition(s) and 68 deletion(s). Raw diff Collapse all Expand all
1111 the macro itself as the first argument to the macro.)
1212 The Robin definitions of macros in the standard library
1313 such as `let` and `list` have been rewritten this way.
14 * The object that a `macro` form evaluates to is no
15 longer called a "macro". It is an "operator". There
16 there are other ways to obtain an operator than applying
17 a `macro` form (for instance there have always been
18 intrinsic operators; it's not fair to call them "macros".)
1419
1520 For the reference implementation,
1621
1722 * Fixed recent import changes which prevented it from
1823 running under Hugs.
24 * The `Macro` type of expressions has been removed,
25 and `Builtin` renamed `Operator`.
1926
2027 Robin 0.7
2128 ---------
44 mkdir -p pkg
55
66 cat stdlib/abort.robin stdlib/equal-p.robin stdlib/eval.robin stdlib/head.robin \
7 stdlib/if.robin stdlib/list-p.robin stdlib/macro-p.robin stdlib/macro.robin \
7 stdlib/if.robin stdlib/list-p.robin stdlib/operator-p.robin stdlib/macro.robin \
88 stdlib/number-p.robin stdlib/prepend.robin stdlib/recover.robin stdlib/sign.robin \
99 stdlib/subtract.robin stdlib/symbol-p.robin stdlib/tail.robin \
1010 > pkg/intrinsics.robin
313313
314314 ### Macros ###
315315
316 TODO rewrite this section
317
316318 A macro is a term which, in an environment, describes how to
317319 translate one S-expression to another.
318320
343345
344346 Macros evaluate to themselves.
345347
346 Macros are represented as the S-expression expansion of their
347 implementation.
348 Operators are represented as an opaque descriptor (TODO this should be the
349 metadata of the operator.)
348350
349351 | (macro (args env) args)
350 = (macro (args env) args)
351
352 Macros can be applied, and that is the typical use of them.
352 = <macro>
353
354 Operators can be applied, and that is the typical use of them.
353355
354356 | ((macro (args env) args) 1)
355357 = (1)
3838 --
3939 -- Evaluating a list means we must make several evaluations. We
4040 -- evaluate the head to obtain something to apply (which must be a
41 -- macro or intrinsic.) We then apply the body of the macro,
42 -- passing it the tail of the list.
41 -- "builtin".) We then apply the "builtin", passing it the tail of the list.
4342 --
4443
4544 eval env (List (applierExpr:actuals)) cc =
4645 eval env applierExpr (\applier ->
4746 case applier of
48 m@(Macro _ _ body) ->
49 eval (makeMacroEnv env (List actuals) m) body cc
50 b@(Builtin _ fun) ->
47 Builtin _ fun ->
5148 fun env (List actuals) cc
5249 other ->
5350 errMsg "inapplicable-object" other)
6764 errMsg msg term =
6865 Abort (List [(Symbol msg), term])
6966
70 makeMacroEnv :: Env -> Expr -> Expr -> Env
71 makeMacroEnv env actuals m@(Macro closedEnv argList _) =
67 makeMacro :: Expr -> Expr -> Expr -> Evaluable
68 makeMacro defineTimeEnv formals body =
69 \callTimeEnv actuals cc ->
70 let
71 env = makeMacroEnv callTimeEnv actuals defineTimeEnv formals
72 in
73 eval env body cc
74
75 makeMacroEnv callTimeEnv actuals defineTimeEnv argList =
7276 let
7377 (List [(Symbol argFormal), (Symbol envFormal)]) = argList
74 newEnv' = insert argFormal actuals closedEnv
75 newEnv'' = insert envFormal env newEnv'
78 newEnv' = insert argFormal actuals defineTimeEnv
79 newEnv'' = insert envFormal callTimeEnv newEnv'
7680 in
7781 newEnv''
82
7883
7984 --
8085 -- Assertions
8994 assertBoolean env = assert env (isBoolean) "expected-boolean"
9095 assertList env = assert env (isList) "expected-list"
9196 assertNumber env = assert env (isNumber) "expected-number"
92 assertMacro env = assert env (isMacro) "expected-macro"
97 assertOperator env = assert env (isOperator) "expected-operator"
1919 data Expr = Symbol String
2020 | Boolean Bool
2121 | Number Int32
22 | Macro Expr Expr Expr -- the 1st Expr is actually an Env
2322 | Builtin String Evaluable
2423 | List [Expr]
2524 | Abort Expr
2827 (Symbol x) == (Symbol y) = x == y
2928 (Boolean x) == (Boolean y) = x == y
3029 (Number x) == (Number y) = x == y
31 (Macro e1 a1 b1) == (Macro e2 a2 b2) = e1 == e2 && a1 == a2 && b1 == b2
3230 (Builtin x _) == (Builtin y _) = x == y
3331 (List x) == (List y) = x == y
3432 (Abort x) == (Abort y) = x == y
3937 show (Boolean True) = "#t"
4038 show (Boolean False) = "#f"
4139 show (Number n) = show n
42 show (Macro env args body) = ("(macro " ++ (show args) ++
43 " " ++ (show body) ++ ")")
4440 show (Builtin name _) = name
4541 show (Abort e) = "(abort " ++ (show e) ++ ")"
4642 show (List exprs) = "(" ++ (showl exprs) ++ ")" where
7167 isList (List _) = True
7268 isList _ = False
7369
74 isMacro (Macro _ _ _) = True
75 isMacro (Builtin _ _) = True
76 isMacro _ = False
77
7870 isAbort (Abort _) = True
7971 isAbort _ = False
72
73 isOperator (Builtin _ _) = True
74 isOperator _ = False
4141
4242 symbolP = predP isSymbol
4343 listP = predP isList
44 macroP = predP isMacro
44 operatorP = predP isOperator
4545 numberP = predP isNumber
4646
4747 subtract :: Evaluable
7979
8080 macro :: Evaluable
8181 macro env (List [args@(List [(Symbol argsS), (Symbol envS)]), body]) cc =
82 cc $ Macro env args body
82 cc $ Builtin "<macro>" $ makeMacro env args body
8383 macro env other cc = errMsg "illegal-arguments" other
8484
8585 abort :: Evaluable
105105 ("prepend", prepend),
106106 ("list?", listP),
107107 ("symbol?", symbolP),
108 ("macro?", macroP),
108 ("operator?",operatorP),
109109 ("number?", numberP),
110110 ("equal?", equalP),
111111 ("subtract", Language.Robin.Intrinsics.subtract),
3333 let n' = n `div` (m + 1)
3434 oneof [
3535 Abort <$> (arbExpr n'),
36 List <$> (arbExprList n'),
37 Macro <$> (arbExpr n') <*> (arbExpr n') <*> (arbExpr n')
36 List <$> (arbExprList n')
37 -- TODO Operator ??
3838 ]
3939
4040 arbExprList :: Int -> Gen [Expr]
+0
-39
stdlib/macro-p.robin less more
0 ;'<<SPEC'
1
2 ### `macro?` ###
3
4 -> Tests for functionality "Evaluate core Robin Expression"
5
6 `macro?` evaluates its argument, then evaluates to `#t` if it is a macro,
7 or `#f` if it is not.
8
9 | (macro? (macro (args env) args))
10 = #t
11
12 Intrinsic macros are macros.
13
14 | (macro? macro)
15 = #t
16
17 Literal symbols are not macros, even if they're the name of one.
18
19 | (macro? ((macro (args env) (head args)) macro))
20 = #f
21
22 Numbers are not macros.
23
24 | (macro? 5)
25 = #f
26
27 The argument to `macro?` may (naturally) be any type, but there must be
28 exactly one argument.
29
30 | (macro? macro macro)
31 ? abort (illegal-arguments (macro macro))
32
33 | (macro?)
34 ? abort (illegal-arguments ())
35
36 '<<SPEC'
37
38 (require macro?)
0 ;'<<SPEC'
1
2 ### `operator?` ###
3
4 -> Tests for functionality "Evaluate core Robin Expression"
5
6 `operator?` evaluates its argument, then evaluates to `#t` if it is an operator,
7 or `#f` if it is not.
8
9 | (operator? (macro (args env) args))
10 = #t
11
12 Intrinsic operators are operators.
13
14 | (operator? macro)
15 = #t
16
17 Literal symbols are not operators, even if they're the name of one.
18
19 | (operator? ((macro (args env) (head args)) macro))
20 = #f
21
22 Numbers are not operators.
23
24 | (operator? 5)
25 = #f
26
27 The argument to `operator?` may (naturally) be any type, but there must be
28 exactly one argument.
29
30 | (operator? macro macro)
31 ? abort (illegal-arguments (macro macro))
32
33 | (operator?)
34 ? abort (illegal-arguments ())
35
36 '<<SPEC'
37
38 (require operator?)