diff options
author | Eduardo Julian | 2015-05-04 08:00:05 -0400 |
---|---|---|
committer | Eduardo Julian | 2015-05-04 08:00:05 -0400 |
commit | da7d3d23227e6d162ff287c8b1ba3f466caafdff (patch) | |
tree | 4b0396800c02de691c4de2848301088b9c5e0f47 /src/lux/analyser/module.clj | |
parent | fa251c2a22f004cd66461d2a8a101f2d88b15460 (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.clj | 85 |
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.")))) |