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); }
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; }
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]; } }
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); }
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)); }
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]); } }
internal void UseAllFrom(LayeState state, LayeKit kit) { foreach (var field in kit.fields) SetGlobal(state, field.Key, field.Value); }
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); }
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); }
/// <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); }
private LayeScript(LayeKit kit, LayeState state) { this.kit = kit; this.state = state; }