aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/math/infix.lux
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--stdlib/source/lux/math/infix.lux89
1 files changed, 89 insertions, 0 deletions
diff --git a/stdlib/source/lux/math/infix.lux b/stdlib/source/lux/math/infix.lux
new file mode 100644
index 000000000..145b8f579
--- /dev/null
+++ b/stdlib/source/lux/math/infix.lux
@@ -0,0 +1,89 @@
+(.module: {#.doc "Common mathematical constants and functions."}
+ [lux #*
+ [control
+ monad
+ ["p" parser ("parser/." Functor<Parser>)]]
+ [data
+ ["." product]
+ [collection
+ [list ("list/." Fold<List>)]]]
+ [macro
+ ["s" syntax (#+ syntax: Syntax)]
+ ["." code]]])
+
+(type: #rec Infix
+ (#Const Code)
+ (#Call (List Code))
+ (#Unary Code Infix)
+ (#Binary Infix Code Infix))
+
+(def: infix^
+ (Syntax Infix)
+ (<| p.rec (function (_ infix^))
+ ($_ p.or
+ ($_ p.either
+ (parser/map code.bit s.bit)
+ (parser/map code.nat s.nat)
+ (parser/map code.int s.int)
+ (parser/map code.rev s.rev)
+ (parser/map code.frac s.frac)
+ (parser/map code.text s.text)
+ (parser/map code.identifier s.identifier)
+ (parser/map code.tag s.tag))
+ (s.form (p.many s.any))
+ (s.tuple (p.and s.any infix^))
+ (s.tuple ($_ p.either
+ (do p.Monad<Parser>
+ [_ (s.this (' #and))
+ init-subject infix^
+ init-op s.any
+ init-param infix^
+ steps (p.some (p.and s.any infix^))]
+ (wrap (product.right (list/fold (function (_ [op param] [subject [_subject _op _param]])
+ [param [(#Binary _subject _op _param)
+ (` and)
+ (#Binary subject op param)]])
+ [init-param [init-subject init-op init-param]]
+ steps))))
+ (do p.Monad<Parser>
+ [init-subject infix^
+ init-op s.any
+ init-param infix^
+ steps (p.some (p.and s.any infix^))]
+ (wrap (list/fold (function (_ [op param] [_subject _op _param])
+ [(#Binary _subject _op _param) op param])
+ [init-subject init-op init-param]
+ steps)))
+ ))
+ )))
+
+(def: (infix-to-prefix infix)
+ (-> Infix Code)
+ (case infix
+ (#Const value)
+ value
+
+ (#Call parts)
+ (code.form parts)
+
+ (#Unary op subject)
+ (` ((~ op) (~ (infix-to-prefix subject))))
+
+ (#Binary left op right)
+ (` ((~ op) (~ (infix-to-prefix right)) (~ (infix-to-prefix left))))
+ ))
+
+(syntax: #export (infix {expr infix^})
+ {#.doc (doc "Infix math syntax."
+ (infix [x i/* +10])
+ (infix [[x i/+ y] i/* [x i/- y]])
+ (infix [sin [x i/+ y]])
+ (infix [[x n/< y] and [y n/< z]])
+ (infix [#and x n/< y n/< z])
+ (infix [(n/* 3 9) gcd 450])
+
+ "The rules for infix syntax are simple."
+ "If you want your binary function to work well with it."
+ "Then take the argument to the right (y) as your first argument,"
+ "and take the argument to the left (x) as your second argument.")}
+ (wrap (list (infix-to-prefix expr))))