aboutsummaryrefslogtreecommitdiff
path: root/source/lux
diff options
context:
space:
mode:
Diffstat (limited to 'source/lux')
-rw-r--r--source/lux/codata/function.lux2
-rw-r--r--source/lux/data/char.lux4
-rw-r--r--source/lux/data/list.lux6
-rw-r--r--source/lux/data/text.lux13
-rw-r--r--source/lux/host/jvm.lux28
-rw-r--r--source/lux/meta/lux.lux67
-rw-r--r--source/lux/meta/type.lux34
7 files changed, 130 insertions, 24 deletions
diff --git a/source/lux/codata/function.lux b/source/lux/codata/function.lux
index a23e969b3..1b7336049 100644
--- a/source/lux/codata/function.lux
+++ b/source/lux/codata/function.lux
@@ -14,7 +14,7 @@
(def #export (flip f)
(All [a b c]
(-> (-> a b c) (-> b a c)))
- (lambda [y x] (f x y)))
+ (lambda [x y] (f y x)))
(def #export (. f g)
(All [a b c]
diff --git a/source/lux/data/char.lux b/source/lux/data/char.lux
index 4e0d41b22..b7b4c6bda 100644
--- a/source/lux/data/char.lux
+++ b/source/lux/data/char.lux
@@ -16,3 +16,7 @@
(defstruct #export Char/Show (S;Show Char)
(def (show x)
($ text:++ "#\"" (_jvm_invokevirtual "java.lang.Object" "toString" [] x []) "\"")))
+
+(def #export (->text c)
+ (-> Char Text)
+ (_jvm_invokevirtual "java.lang.Object" "toString" [] c []))
diff --git a/source/lux/data/list.lux b/source/lux/data/list.lux
index 563282f32..6bf050228 100644
--- a/source/lux/data/list.lux
+++ b/source/lux/data/list.lux
@@ -336,3 +336,9 @@
(def #export zip2 (zip 2))
(def #export zip3 (zip 3))
+
+(def #export (empty? xs)
+ (All [a] (-> (List a) Bool))
+ (case xs
+ #;Nil true
+ _ false))
diff --git a/source/lux/data/text.lux b/source/lux/data/text.lux
index 744a22f2e..af2de51ff 100644
--- a/source/lux/data/text.lux
+++ b/source/lux/data/text.lux
@@ -180,3 +180,16 @@
_
(#;Left "Wrong syntax for <>")))
+
+(def #export (split-lines text)
+ (-> Text (List Text))
+ (case (: (Maybe (List Text))
+ (do Maybe/Monad
+ [idx (index-of "\n" text)
+ [head post] (split (inc idx) text)]
+ (wrap (#;Cons head (split-lines post)))))
+ #;None
+ (#;Cons text #;Nil)
+
+ (#;Some xs)
+ xs))
diff --git a/source/lux/host/jvm.lux b/source/lux/host/jvm.lux
index 573e181b5..737c1731d 100644
--- a/source/lux/host/jvm.lux
+++ b/source/lux/host/jvm.lux
@@ -93,6 +93,21 @@
arg-classes (map second args)]]
(wrap [vars var-types (list:join var-rebinds) arg-classes])))
+(def (class->type class)
+ (-> JvmType AST)
+ (case class
+ "boolean" (' (;^ java.lang.Boolean))
+ "byte" (' (;^ java.lang.Byte))
+ "short" (' (;^ java.lang.Short))
+ "int" (' (;^ java.lang.Integer))
+ "long" (' (;^ java.lang.Long))
+ "float" (' (;^ java.lang.Float))
+ "double" (' (;^ java.lang.Double))
+ "char" (' (;^ java.lang.Character))
+ "void" (` ;Unit)
+ _
+ (` (^ (~ (symbol$ ["" class]))))))
+
## Parsers
(def annotation-params^
(Parser (List AnnotationParam))
@@ -227,7 +242,7 @@
(def (gen-expected-output [ex? opt? output] body)
(-> ExpectedOutput AST (, AST AST))
- (let [type (` (^ (~ (symbol$ ["" output]))))
+ (let [type (class->type output)
[body type] (if opt?
[(` (;;??? (~ body)))
(` (Maybe (~ type)))]
@@ -321,14 +336,15 @@
(defsyntax #export (null? obj)
(emit (@list (` (;_jvm_null? (~ obj))))))
-(defsyntax #export (new$ [class local-symbol^] [args (tuple^ (*^ exp-input^))] [ex? (tag?^ ["" "!"])])
+(defsyntax #export (new$ [class local-symbol^] [args (tuple^ (*^ exp-input^))] [unsafe? (tag?^ ["" "unsafe"])])
(do Lux/Monad
[[vars var-types var-rebinds arg-classes] (prepare-args args)
#let [new-expr (` (;_jvm_new (~ (text$ class)) [(~@ (map text$ arg-classes))] [(~@ vars)]))
- new-expr (if ex?
- (` (try (~ new-expr)))
- new-expr)]]
- (wrap (@list (` (: (-> (, (~@ var-types)) (^ (~ (symbol$ ["" class]))))
+ return-type (class->type class)
+ [new-expr return-type] (if unsafe?
+ [(` (try (~ new-expr))) (` (Either Text (~ return-type)))]
+ [new-expr return-type])]]
+ (wrap (@list (` (: (-> (, (~@ var-types)) (~ return-type))
(lambda [[(~@ vars)]]
(let [(~@ var-rebinds)]
(~ new-expr)))))))))
diff --git a/source/lux/meta/lux.lux b/source/lux/meta/lux.lux
index 650e67133..b6ff09f59 100644
--- a/source/lux/meta/lux.lux
+++ b/source/lux/meta/lux.lux
@@ -9,9 +9,11 @@
(functor #as F)
(monad #as M #refer (#only do))
(show #as S))
- (lux/data (list #refer #all #open ("list:" List/Monoid))
+ (lux/data (list #refer #all #open ("list:" List/Monoid List/Functor))
(text #as T #open ("text:" Text/Monoid Text/Eq))
- (number/int #as I #open ("i" Int/Number))))
+ (number/int #as I #open ("i" Int/Number))
+ (tuple #as t)
+ ident))
## [Types]
## (deftype (Lux a)
@@ -77,7 +79,7 @@
(#;Some $module)
(case (|> (: (Module Compiler) $module) (get@ #;defs) (get name))
(#;Some gdef)
- (case (: (, Bool DefData) gdef)
+ (case (: Definition gdef)
[exported? (#;MacroD macro')]
(if (or exported? (text:= module current-module))
(#;Some macro')
@@ -210,7 +212,7 @@
(case (get module (get@ #;modules state))
(#;Some =module)
(using List/Monad
- (#;Right [state (join (map (: (-> (, Text (, Bool DefData))
+ (#;Right [state (join (map (: (-> (, Text Definition)
(List Text))
(lambda [gdef]
(let [[name [export? _]] gdef]
@@ -251,7 +253,7 @@
envs)))
(def (find-in-defs' name state)
- (-> Ident Compiler (Maybe DefData))
+ (-> Ident Compiler (Maybe Definition))
(let [[v-prefix v-name] name
{#;source source #;modules modules
#;envs envs #;type-vars types #;host host
@@ -266,17 +268,17 @@
#;None
#;None
- (#;Some [_ def-data])
- (case def-data
- (#;AliasD name') (find-in-defs' name' state)
- _ (#;Some def-data)
+ (#;Some def)
+ (case def
+ [_ (#;AliasD name')] (find-in-defs' name' state)
+ _ (#;Some def)
)))
))
(def #export (find-in-defs name state)
(-> Ident Compiler (Maybe Type))
(case (find-in-defs' name state)
- (#;Some def-data)
+ (#;Some [_ def-data])
(case def-data
(#;ValueD [type value]) (#;Some type)
(#;MacroD _) (#;Some Macro)
@@ -315,9 +317,50 @@
(case (find-in-defs' name' state)
(#;Some def-data)
(case def-data
- (#;TypeD type) (#;Right [state type])
- _ (#;Left ($ text:++ "Definition is not a type: " (ident->text name))))
+ [_ (#;TypeD type)] (#;Right [state type])
+ _ (#;Left ($ text:++ "Definition is not a type: " (ident->text name))))
_
(#;Left ($ text:++ "Unknown var: " (ident->text name))))))
))
+
+(def #export (defs module-name state)
+ (-> Text (Lux (List (, Text Definition))))
+ (case (get module-name (get@ #;modules state))
+ #;None (#;Left ($ text:++ "Unknown module: " module-name))
+ (#;Some module) (#;Right [state (get@ #;defs module)])
+ ))
+
+(def #export (exports module-name)
+ (-> Text (Lux (List (, Text Definition))))
+ (do Lux/Monad
+ [defs (defs module-name)]
+ (wrap (filter (lambda [[name [exported? data]]] exported?)
+ defs))))
+
+(def #export (modules state)
+ (Lux (List Text))
+ (|> state
+ (get@ #;modules)
+ (list:map t;first)
+ (#;Right state)))
+
+(def #export (find-module name state)
+ (-> Text (Lux (Module Compiler)))
+ (case (get name (get@ #;modules state))
+ (#;Some module)
+ (#;Right state module)
+
+ _
+ (#;Left ($ text:++ "Unknown module: " name))))
+
+(def #export (tags-for [module name])
+ (-> Ident (Lux (Maybe (List Ident))))
+ (do Lux/Monad
+ [module (find-module module)]
+ (case (get name (get@ #;types module))
+ (#;Some [tags _])
+ (wrap (#;Some tags))
+
+ _
+ (wrap #;None))))
diff --git a/source/lux/meta/type.lux b/source/lux/meta/type.lux
index a1c34b1ac..0938d104d 100644
--- a/source/lux/meta/type.lux
+++ b/source/lux/meta/type.lux
@@ -7,14 +7,36 @@
(lux (control show
eq
monad)
- (data (text #open ("text:" Text/Monoid Text/Eq))
- (number/int #open ("int:" Int/Eq Int/Show))
+ (data (char #as c)
+ (text #as t #open ("text:" Text/Monoid Text/Eq))
+ (number/int #open ("int:" Int/Number Int/Ord Int/Show))
maybe
- (list #refer #all #open ("list:" List/Monad List/Fold)))
+ (list #refer #all #open ("list:" List/Monad List/Monoid List/Fold)))
))
(open List/Fold)
+## [Utils]
+(def (unravel-fun type)
+ (-> Type (, Type (List Type)))
+ (case type
+ (#;LambdaT in out')
+ (let [[out ins] (unravel-fun out')]
+ [out (@list& in ins)])
+
+ _
+ [type (@list)]))
+
+(def (unravel-app type)
+ (-> Type (, Type (List Type)))
+ (case type
+ (#;AppT left' right)
+ (let [[left rights] (unravel-app left')]
+ [left (list:++ rights (@list right))])
+
+ _
+ [type (@list)]))
+
## [Structures]
(defstruct #export Type/Show (Show Type)
(def (show type)
@@ -44,7 +66,8 @@
($ text:++ "(| " (|> members (list:map show) (interpose " ") (foldL text:++ "")) ")"))
(#;LambdaT input output)
- ($ text:++ "(-> " (show input) " " (show output) ")")
+ (let [[out ins] (unravel-fun type)]
+ ($ text:++ "(-> " (|> ins (list:map show) (interpose " ") (foldL text:++ "")) " " (show out) ")"))
(#;VarT id)
($ text:++ "⌈" (int:show id) "⌋")
@@ -56,7 +79,8 @@
($ text:++ "⟨" (int:show id) "⟩")
(#;AppT fun param)
- ($ text:++ "(" (show fun) " " (show param) ")")
+ (let [[type-fun type-args] (unravel-app type)]
+ ($ text:++ "(" (show type-fun) " " (|> type-args (list:map show) (interpose " ") (foldL text:++ "")) ")"))
(#;UnivQ env body)
($ text:++ "(All " (show body) ")")