Beispiel #1
0
 public void Open(LayeLibrary lib)
 {
     var libKit = new LayeKit();
     foreach (var entry in lib.entries)
         libKit[state, entry.Key] = entry.Value;
     kit.Use(state, libKit, lib.name);
 }
Beispiel #2
0
        internal static DetailLogger Compile(string filePath, Encoding encoding, out LayeKit kit)
        {
            filePath = Path.GetFullPath(filePath);
            if (!File.Exists(filePath))
                throw new ArgumentException("filePath");

            if (compiledKits.ContainsKey(filePath))
            {
                kit = compiledKits[filePath];
                return null;
            }

            var log = new DetailLogger();

            var lexer = new Lexer(log);
            var tokens = lexer.GetTokens(filePath, encoding);

            if (log.ErrorCount != 0)
                throw new CompilerException(log);

            var parser = new Parser(log);
            var ast = parser.GenerateAST(tokens);

            if (log.ErrorCount != 0)
                throw new CompilerException(log);

            var compiler = new KitCompiler(log, Path.GetFileName(filePath));
            ast.Visit(compiler);

            if (log.ErrorCount != 0)
                throw new CompilerException(log);

            var proto = compiler.GetPrototype();
            kit = new LayeKit(Directory.GetParent(filePath).FullName, proto);

            compiledKits[filePath] = kit;

            return log;
        }
Beispiel #3
0
        internal LayeClosure(LayeKit kit, FunctionPrototype proto, LayeTypeDef definedType = null, LayeObject[] defaults = null)
            : base(TYPE)
        {
            if (kit == null)
                throw new ArgumentNullException("kit");
            this.kit = kit;
            this.proto = proto;
            outers = new OuterValue[proto.outers.Length];
            this.definedType = definedType == null ? NULL : definedType;

            var numParams = proto.hasVargs ? proto.numParams - 1 : proto.numParams;
            this.defaults = new LayeObject[numParams];
            if (defaults == null || defaults.Length == 0)
                for (int i = 0; i < numParams; i++)
                    this.defaults[i] = NULL;
            else
            {
                for (uint i = 0; i < numParams - defaults.Length; i++)
                    this.defaults[i] = NULL;
                for (uint i = numParams - (uint)defaults.Length, j = 0; i < numParams; i++, j++)
                    this.defaults[i] = defaults[j];
            }
        }
Beispiel #4
0
 private void DoStore(StackFrame frame, LayeKit kit, string key)
 {
     if (kit.IsDefined(key))
         kit[this, key] = frame.Top;
     else kit.SetGlobal(this, key, frame.Top);
 }
Beispiel #5
0
 private void DoLoad(StackFrame frame, LayeKit kit, string key)
 {
     if (kit.IsDefined(key))
         frame.Push(kit[this, key]);
     else frame.Push(kit.GetGlobal(this, key));
 }
Beispiel #6
0
 internal void UseFrom(LayeState state, LayeKit kit, params string[] fields)
 {
     foreach (var field in fields)
     {
         if (!kit.IsDefined(field))
             ; // TODO error
         else SetGlobal(state, field, kit[state, field]);
     }
 }
Beispiel #7
0
 internal void UseAllFrom(LayeState state, LayeKit kit)
 {
     foreach (var field in kit.fields)
         SetGlobal(state, field.Key, field.Value);
 }
Beispiel #8
0
 internal void Use(LayeState state, LayeKit kit, string kitPath, string useAs = null)
 {
     if (usedKits.Contains(kitPath))
         return;
     if (useAs == null)
     {
         if (kitPath.Contains("."))
             useAs = kitPath.Substring(kitPath.LastIndexOf(".") + 1);
         else useAs = kitPath;
     }
     SetGlobal(state, useAs, kit);
     usedKits.Add(kitPath);
 }
Beispiel #9
0
        public void Run()
        {
            var builder = new FunctionBuilder();
            builder.fileName = Path.GetFileName(filePath);

            var lines = File.ReadAllLines(filePath);
            for (uint lineNum = 0; lineNum < lines.Length; lineNum++)
            {
                var line = lines[lineNum].Trim();
                if (line.Length == 0 || line.StartsWith(";"))
                    continue;

                // make sure the builder knows what line we're on, woo.
                builder.currentLineNumber = lineNum + 1;

                var command = (line.Contains(" ") ? line.Substring(0, line.IndexOf(' ')) : line).ToLower();
                var rest = line.Substring(command.Length).Trim();

                if (command.StartsWith("."))
                {
                    switch (command.Substring(1))
                    {
                        case "fn":
                            var paramNames = rest.Split(' ');
                            builder = new FunctionBuilder(builder);
                            builder.currentLineNumber = lineNum + 1;
                            for (int i = 0; i < paramNames.Length; i++)
                                builder.AddParameter(paramNames[i]);
                            continue;
                        case "endfn":
                            var proto = builder.Build();
                            builder = builder.parent;
                            builder.OpClosure(proto);
                            continue;
                        default: Console.WriteLine(command); throw new ArgumentException();
                    }
                }
                else
                {
                    switch (command)
                    {
                        case "nop": CheckEmpty(rest); builder.OpNop(); continue;
                        case "pop": CheckEmpty(rest); builder.OpPop(); continue;
                        case "dup": CheckEmpty(rest); builder.OpDup(); continue;

                        case "jump": builder.OpJump((uint)(builder.InsnCount + int.Parse(rest) + 1)); continue;
                        case "jumpeq": builder.OpJumpEq((uint)(builder.InsnCount + int.Parse(rest) + 1)); continue;
                        case "jumpneq": builder.OpJumpNeq((uint)(builder.InsnCount + int.Parse(rest) + 1)); continue;
                        case "jumpt": builder.OpJumpT((uint)(builder.InsnCount + int.Parse(rest) + 1)); continue;
                        case "jumpf": builder.OpJumpF((uint)(builder.InsnCount + int.Parse(rest) + 1)); continue;

                        case "lload":
                        {
                            CheckSymbol(rest);
                            uint location;
                            if (builder.GetLocalLocation(rest, out location))
                                builder.OpLLoad(location);
                            else throw new ArgumentException();
                        } continue;
                        case "lstore":
                        {
                            CheckSymbol(rest);
                            uint location;
                            if (builder.GetLocalLocation(rest, out location))
                                builder.OpLStore(location);
                            else throw new ArgumentException();
                        } continue;
                        case "oload":
                        {
                            CheckSymbol(rest);
                            uint location;
                            if (builder.GetOuterLocation(rest, out location))
                                builder.OpOLoad(location);
                            else throw new ArgumentException();
                        } continue;
                        case "ostore":
                        {
                            CheckSymbol(rest);
                            uint location;
                            if (builder.GetOuterLocation(rest, out location))
                                builder.OpOStore(location);
                            else throw new ArgumentException();
                        } continue;
                        case "kload": CheckSymbol(rest); builder.OpKLoad(rest); continue;
                        case "kstore": CheckSymbol(rest); builder.OpKStore(rest); continue;
                        case "gload": CheckSymbol(rest); builder.OpGLoad(rest); continue;
                        case "gstore": CheckSymbol(rest); builder.OpGStore(rest); continue;
                        case "iload": CheckEmpty(rest); builder.OpILoad(uint.Parse(rest)); continue;
                        case "istore": CheckEmpty(rest); builder.OpIStore(uint.Parse(rest)); continue;
                        case "fload": CheckSymbol(rest); builder.OpFLoad(rest); continue;
                        case "fstore": CheckSymbol(rest); builder.OpFStore(rest); continue;
                        case "load": CheckSymbol(rest); builder.OpLoad(rest); continue;
                        case "store": CheckSymbol(rest); builder.OpStore(rest); continue;

                        case "null": CheckEmpty(rest); builder.OpNull(); continue;
                        case "bconst": builder.OpBConst(bool.Parse(rest)); continue;

                        case "iconst": builder.OpIConst(Laye.ConvertToInt(rest)); continue;
                        case "fconst": builder.OpFConst(Laye.ConvertToFloat(rest)); continue;

                        case "invoke": builder.OpInvoke(uint.Parse(rest)); continue;

                        case "prefix": CheckOperator(rest); builder.OpPrefix(rest); continue;
                        case "infix": CheckOperator(rest); builder.OpInfix(rest); continue;

                        case "compis": CheckEmpty(rest); builder.OpCompIs(); continue;
                        case "compnotis": CheckEmpty(rest); builder.OpCompNotIs(); continue;
                        case "comptypeof": CheckEmpty(rest); builder.OpCompTypeOf(); continue;
                        case "compnottypeof": CheckEmpty(rest); builder.OpCompNotTypeOf(); continue;
                        case "typeof": CheckEmpty(rest); builder.OpTypeOf(); continue;

                        default: Console.WriteLine(command); throw new ArgumentException();
                    }
                }
            }

            var kit = new LayeKit();
            var closure = new LayeClosure(kit, builder.Build());
            var lstate = new LayeState();
            /*
            lstate["println"] = (LayeCallback)((state, args) =>
            {
                var sbuilder = new StringBuilder();
                for (int i = 0; i < args.Length; i++)
                {
                    if (i > 0)
                        sbuilder.Append(" ");
                    sbuilder.Append(args[i].ToString());
                }
                Console.WriteLine(sbuilder);
                return LayeObject.NULL;
            }); */
            closure.Invoke(lstate);
        }
Beispiel #10
0
 /// <summary>
 /// Puts a kit in the global namespace if a kit with the same name doesn't already exist.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="kit"></param>
 public void UseKit(string name, LayeKit kit)
 {
     this.kit.Use(state, kit, name);
 }
Beispiel #11
0
 private LayeScript(LayeKit kit, LayeState state)
 {
     this.kit = kit;
     this.state = state;
 }