aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source')
-rw-r--r--stdlib/source/lux/type/object/protocol.lux116
1 files changed, 92 insertions, 24 deletions
diff --git a/stdlib/source/lux/type/object/protocol.lux b/stdlib/source/lux/type/object/protocol.lux
index 73bc9226f..b19c1b203 100644
--- a/stdlib/source/lux/type/object/protocol.lux
+++ b/stdlib/source/lux/type/object/protocol.lux
@@ -2,7 +2,8 @@
lux
(lux (control ["p" parser]
[monad #+ do])
- (data (coll [list "list/" Functor<List>]))
+ (data [sum]
+ (coll [list "list/" Functor<List>]))
[macro "meta/" Monad<Meta>]
(macro [code]
["s" syntax #+ syntax:]
@@ -10,34 +11,50 @@
(common ["csr" reader]
["csw" writer])))))
-(type: #export (Simple i o)
+(type: #export (Method i o)
(All [r] [i (-> o r)]))
(type: #export (Message i o)
- (Simple i o o))
+ (Method i o o))
(def: #export (message input)
(All [i o] (-> i (Message i o)))
[input id])
-(type: #export (Method s p)
+(type: #export (Class s p)
(All [r] (-> (p r) s [r s])))
+(type: #export (Alt lp rp)
+ (All [r] (| (lp r) (rp r))))
+
+(def: #export (alt left right)
+ (All [s lp rp]
+ (-> (Class s lp)
+ (Class s rp)
+ (Class s (Alt lp rp))))
+ (function [input state]
+ (case input
+ (#.Left input)
+ (left input state)
+
+ (#.Right input)
+ (right input state))))
+
(type: #export (Object p)
(All [r] (-> (p r) [r (Object p)])))
-(def: #export (object method init)
- (All [s p] (-> (Method s p) s (Object p)))
+(def: #export (object class init)
+ (All [s p] (-> (Class s p) s (Object p)))
(loop [state init]
(function [input]
- (let [[output state'] (method input state)]
+ (let [[output state'] (class input state)]
[output (recur state')]))))
(type: Method-Syntax
- {#type-variables (List Text)
- #name Text
- #input Code
- #output Code})
+ {#method-variables (List Text)
+ #method-name Text
+ #method-input Code
+ #method-output Code})
(def: method|r
(s.Syntax Method-Syntax)
@@ -49,20 +66,22 @@
(def: (method|w g!return method)
(-> Code Method-Syntax Code)
- (` ((~ (code.local-tag (get@ #name method)))
- (All [(~+ (csw.type-variables (get@ #type-variables method)))]
- [(~ (get@ #input method))
- (-> (~ (get@ #output method)) (~ g!return))]))))
+ (let [tagC (code.local-tag (get@ #method-name method))
+ varsC+ (csw.type-variables (get@ #method-variables method))
+ inputC (get@ #method-input method)
+ outputC (get@ #method-output method)]
+ (` ((~ tagC) (All [(~+ varsC+)]
+ (Method (~ inputC) (~ outputC) (~ g!return)))))))
-(def: (method-constructor export protocol method)
+(def: (method|c export protocol method)
(-> Bool cs.Declaration Method-Syntax (Meta Code))
- (let [methodC (code.local-symbol (get@ #name method))
- tagC (code.local-tag (get@ #name method))
+ (let [methodC (code.local-symbol (get@ #method-name method))
+ tagC (code.local-tag (get@ #method-name method))
protocolC (code.local-symbol (get@ #cs.declaration-name protocol))
protocol-varsC+ (csw.type-variables (get@ #cs.declaration-args protocol))
- method-varsC+ (csw.type-variables (get@ #type-variables method))
- method-inputC (get@ #input method)
- method-outputC (get@ #output method)]
+ method-varsC+ (csw.type-variables (get@ #method-variables method))
+ method-inputC (get@ #method-input method)
+ method-outputC (get@ #method-output method)]
(macro.with-gensyms [g!input g!return]
(meta/wrap (` (def: (~+ (csw.export export)) ((~ methodC) (~ g!input))
(All [(~+ protocol-varsC+) (~+ method-varsC+)]
@@ -70,15 +89,64 @@
((~ protocolC) (~+ protocol-varsC+) (~ method-outputC))))
((~ tagC) [(~ g!input) .id])))))))
+(type: Class-Syntax
+ {#class-name Text
+ #class-protocol Code})
+
+(def: class|r
+ (s.Syntax Class-Syntax)
+ (s.form ($_ p.seq
+ s.local-symbol
+ s.any)))
+
+(def: (class|w g!return class)
+ (-> Code Class-Syntax Code)
+ (let [tagC (code.local-tag (get@ #class-name class))
+ protocolC (get@ #class-protocol class)]
+ (` ((~ tagC) ((~ protocolC) (~ g!return))))))
+
+(def: (class|c export protocol class)
+ (-> Bool cs.Declaration Class-Syntax (Meta Code))
+ (let [classC (code.local-symbol (get@ #class-name class))
+ tagC (code.local-tag (get@ #class-name class))
+ protocolC (code.local-symbol (get@ #cs.declaration-name protocol))
+ protocol-varsC+ (csw.type-variables (get@ #cs.declaration-args protocol))
+ class-protocolC (get@ #class-protocol class)]
+ (macro.with-gensyms [g!sub g!return]
+ (meta/wrap (` (def: (~+ (csw.export export)) ((~ classC) (~ g!sub))
+ (All [(~+ protocol-varsC+)]
+ (-> (~ class-protocolC)
+ ((~ protocolC) (~+ protocol-varsC+))))
+ ((~ tagC) (~ g!sub))))))))
+
+(type: Super-Syntax
+ (#Method Method-Syntax)
+ (#Class Class-Syntax))
+
+(def: super|r
+ (s.Syntax Super-Syntax)
+ (p.alt method|r
+ class|r))
+
+(def: (super|w g!return)
+ (-> Code Super-Syntax Code)
+ (sum.either (method|w g!return)
+ (class|w g!return)))
+
+(def: (super|c export protocol)
+ (-> Bool cs.Declaration (| Method-Syntax Class-Syntax) (Meta Code))
+ (sum.either (method|c export protocol)
+ (class|c export protocol)))
+
(syntax: #export (protocol: [export csr.export]
[declaration csr.declaration]
- [methods (p.many method|r)])
+ [supers (p.many super|r)])
(macro.with-gensyms [g!return]
(do @
- [constructors (monad.map @ (method-constructor export declaration) methods)
+ [constructors (monad.map @ (super|c export declaration) supers)
#let [protocolC (code.local-symbol (get@ #cs.declaration-name declaration))
varsC+ (csw.type-variables (get@ #cs.declaration-args declaration))]]
(wrap (list& (` (type: (~+ (csw.export export))
((~ protocolC) (~+ varsC+) (~ g!return))
- (~+ (list/map (method|w g!return) methods))))
+ (~+ (list/map (super|w g!return) supers))))
constructors)))))