aboutsummaryrefslogtreecommitdiff
path: root/src/lux/analyser/module.clj
diff options
context:
space:
mode:
authorEduardo Julian2015-05-04 08:00:05 -0400
committerEduardo Julian2015-05-04 08:00:05 -0400
commitda7d3d23227e6d162ff287c8b1ba3f466caafdff (patch)
tree4b0396800c02de691c4de2848301088b9c5e0f47 /src/lux/analyser/module.clj
parentfa251c2a22f004cd66461d2a8a101f2d88b15460 (diff)
- Added alias-lux to import lux.lux definitions.
- Fixed a few bugs both in lux.lux & the compiler. - Added exports to the language.
Diffstat (limited to 'src/lux/analyser/module.clj')
-rw-r--r--src/lux/analyser/module.clj85
1 files changed, 60 insertions, 25 deletions
diff --git a/src/lux/analyser/module.clj b/src/lux/analyser/module.clj
index 6e42a56f7..83169b17d 100644
--- a/src/lux/analyser/module.clj
+++ b/src/lux/analyser/module.clj
@@ -16,7 +16,7 @@
[["lux;Cons" [?env ["lux;Nil" _]]]]
(return* (->> state
(&/update$ &/$MODULES (fn [ms]
- (&/|update module #(&/|put name def-data %)
+ (&/|update module #(&/|put name (&/T false def-data) %)
ms)))
(&/set$ &/$ENVS (&/|list (&/update$ &/$LOCALS (fn [locals]
(&/update$ &/$MAPPINGS (fn [mappings]
@@ -32,15 +32,16 @@
(defn def-alias [a-module a-name r-module r-name]
(fn [state]
+ ;; (prn 'def-alias [a-module a-name] '=> [r-module r-name])
(matchv ::M/objects [(&/get$ &/$ENVS state)]
[["lux;Cons" [?env ["lux;Nil" _]]]]
(return* (->> state
(&/update$ &/$MODULES (fn [ms]
- (&/|update a-module #(&/|put a-name (&/V "lux;AliasD" (&/T r-module r-name)) %)
+ (&/|update a-module #(&/|put a-name (&/T false (&/V "lux;AliasD" (&/T r-module r-name))) %)
ms)))
(&/set$ &/$ENVS (&/|list (&/update$ &/$LOCALS (fn [locals]
(&/update$ &/$MAPPINGS (fn [mappings]
- (&/|put (str "" &/+name-separator+ name)
+ (&/|put (str "" &/+name-separator+ a-name)
(&/T (&/V "global" (&/T r-module r-name)) &type/$Void)
mappings))
locals))
@@ -63,12 +64,26 @@
(fail* (str "Unknown alias: " name)))))
(defn find-def [module name]
- (fn [state]
- (if-let [$module (->> state (&/get$ &/$MODULES) (&/|get module))]
- (if-let [$def (&/|get name $module)]
- (return* state $def)
- (fail* (str "[Analyser Error] Definition doesn't exist: " (str module &/+name-separator+ name))))
- (fail* (str "[Analyser Error] Module doesn't exist: " module)))))
+ (|do [current-module &/get-module-name]
+ (fn [state]
+ (if-let [$module (->> state (&/get$ &/$MODULES) (&/|get module))]
+ (if-let [$def (&/|get name $module)]
+ (matchv ::M/objects [$def]
+ [[exported? $$def]]
+ (if (or exported? (= current-module module))
+ (matchv ::M/objects [$$def]
+ [["lux;AliasD" [?r-module ?r-name]]]
+ (&/run-state (find-def ?r-module ?r-name)
+ state)
+
+ [_]
+ (return* state (&/T (&/T module name) $$def)))
+ (fail* (str "[Analyser Error] Can't use unexported definition: " (str module &/+name-separator+ name)))))
+ (fail* (str "[Analyser Error] Definition doesn't exist: " (str module &/+name-separator+ name))))
+ (do (prn [module name]
+ (str "[Analyser Error] Module doesn't exist: " module)
+ (->> state (&/get$ &/$MODULES) &/|keys &/->seq))
+ (fail* (str "[Analyser Error] Module doesn't exist: " module)))))))
(defn defined? [module name]
(&/try-all% (&/|list (|do [_ (find-def module name)]
@@ -80,26 +95,46 @@
(if-let [$module (->> state (&/get$ &/$MODULES) (&/|get module))]
(if-let [$def (&/|get name $module)]
(matchv ::M/objects [$def]
- [["lux;ValueD" ?type]]
+ [[exported? ["lux;ValueD" ?type]]]
(do ;; (prn 'declare-macro/?type (aget ?type 0))
- (&/run-state (|do [_ (&type/check &type/Macro ?type)
- ^ClassLoader loader &/loader
- :let [macro (-> (.loadClass loader (&host/location (&/|list module name)))
- (.getField "_datum")
- (.get nil))]]
- (fn [state*]
- (return* (&/update$ &/$MODULES
- (fn [$modules]
- (&/|put module (&/|put name (&/V "lux;MacroD" macro) $module)
- $modules))
- state*)
- nil)))
- state))
+ (&/run-state (|do [_ (&type/check &type/Macro ?type)
+ ^ClassLoader loader &/loader
+ :let [macro (-> (.loadClass loader (&host/location (&/|list module name)))
+ (.getField "_datum")
+ (.get nil))]]
+ (fn [state*]
+ (return* (&/update$ &/$MODULES
+ (fn [$modules]
+ (&/|put module (&/|put name (&/T exported? (&/V "lux;MacroD" macro)) $module)
+ $modules))
+ state*)
+ nil)))
+ state))
- [["lux;MacroD" _]]
+ [[_ ["lux;MacroD" _]]]
(fail* (str "[Analyser Error] Can't re-declare a macro: " (str module &/+name-separator+ name)))
- [["lux;TypeD" _]]
+ [[_ ["lux;TypeD" _]]]
(fail* (str "[Analyser Error] Definition doesn't have macro type: " module ";" name)))
(fail* (str "[Analyser Error] Definition doesn't exist: " (str module &/+name-separator+ name))))
(fail* (str "[Analyser Error] Module doesn't exist: " module)))))
+
+(defn export [module name]
+ (fn [state]
+ (matchv ::M/objects [(&/get$ &/$ENVS state)]
+ [["lux;Cons" [?env ["lux;Nil" _]]]]
+ (if-let [$def (->> state (&/get$ &/$MODULES) (&/|get module) (&/|get name))]
+ (matchv ::M/objects [$def]
+ [[true _]]
+ (fail* (str "[Analyser Error] Definition has already been exported: " module ";" name))
+
+ [[false ?data]]
+ (return* (->> state
+ (&/update$ &/$MODULES (fn [ms]
+ (&/|update module #(&/|put name (&/T true ?data) %)
+ ms))))
+ nil))
+ (fail* (str "[Analyser Error] Can't export an inexistent definition: " module ";" name)))
+
+ [_]
+ (fail* "[Analyser Error] Can't export a global definition outside of a global environment."))))