Esempio n. 1
0
        public Value Evaluate(Environment environment)
        {
            var modules = environment.GetModules();
            // resolve module file, identifier and name
            string spec;

            if (modulespec is NodeIdentifier)
            {
                spec = ((NodeIdentifier)this.modulespec).GetValue();
                if (environment.IsDefined(spec))
                {
                    var val = environment.Get(spec, this.pos);
                    if (!(val.IsObject() && val.AsObject().isModule))
                    {
                        if (!val.IsString())
                        {
                            throw new ControlErrorException(new ValueString("ERROR"), "Expected string or identifier modulespec but got " + val.Type(), pos);
                        }
                        spec = val.AsString().GetValue();
                    }
                }
            }
            else
            {
                var specval = this.modulespec.Evaluate(environment);
                if (!specval.IsString())
                {
                    throw new ControlErrorException(new ValueString("ERROR"), "Expected string or identifier modulespec but got " + specval.Type(), pos);
                }
                spec = specval.AsString().GetValue();
            }
            var modulefile = spec;

            if (!modulefile.EndsWith(".ckl"))
            {
                modulefile += ".ckl";
            }
            string moduleidentifier;
            var    modulename = this.name;
            var    parts      = spec.Split('/');
            var    name       = parts[parts.Length - 1];

            if (name.EndsWith(".ckl"))
            {
                name = name.Substring(0, name.Length - 4);
            }
            moduleidentifier = name;
            if (modulename == null)
            {
                modulename = name;
            }
            environment.PushModuleStack(moduleidentifier, pos);

            // lookup or read module
            Environment moduleEnv = null;

            if (modules.ContainsKey(moduleidentifier))
            {
                moduleEnv = modules[moduleidentifier];
            }
            else
            {
                moduleEnv = environment.GetBase().NewEnv();
                var  modulesrc = ModuleLoader.LoadModule(modulefile, environment, pos);
                Node node      = null;
                try {
                    node = Parser.Parse(modulesrc, modulefile);
                } catch (Exception) {
                    throw new ControlErrorException(new ValueString("ERROR"), "Cannot parse module " + moduleidentifier, pos);
                }
                node.Evaluate(moduleEnv);
                modules[moduleidentifier] = moduleEnv;
            }
            environment.PopModuleStack();

            // bind module or contents of module
            if (unqualified)
            {
                foreach (var symbol in moduleEnv.GetLocalSymbols())
                {
                    if (symbol.StartsWith("_"))
                    {
                        continue;                         // skip private module symbols
                    }
                    environment.Put(symbol, moduleEnv.Get(symbol, pos));
                }
            }
            else if (symbols != null)
            {
                foreach (var symbol in moduleEnv.GetLocalSymbols())
                {
                    if (symbol.StartsWith("_"))
                    {
                        continue;                         // skip private module symbols
                    }
                    if (!symbols.ContainsKey(symbol))
                    {
                        continue;
                    }
                    environment.Put(symbols[symbol], moduleEnv.Get(symbol, pos));
                }
            }
            else
            {
                var obj = new ValueObject {
                    isModule = true
                };
                foreach (var symbol in moduleEnv.GetLocalSymbols())
                {
                    if (symbol.StartsWith("_"))
                    {
                        continue;                         // skip private module symbols
                    }
                    var val = moduleEnv.Get(symbol, pos);
                    if (val.IsObject() && val.AsObject().isModule)
                    {
                        continue;                                            // do not re-export modules!
                    }
                    obj.AddItem(symbol, val);
                }
                environment.Put(modulename, obj);
            }
            return(ValueNull.NULL);
        }