static LuaArguments write(LuaArguments args) { var self = args[0]; if (isStream(self)) { FileObject fobj = self.luaobj as FileObject; foreach (var arg in args) { if (arg == self) { continue; } if (!(arg.IsString || arg.IsNumber)) { Lua.Return(); } if (fobj.stream.CanWrite) { fobj.writer.Write(arg.ToString()); } else { Lua.Return(); } } return(Lua.Return(self)); } else { return(Lua.Return()); } }
static LuaArguments EvalExpression(IExpression Expression, LuaContext Context) { if (Expression is NumberLiteral) { return(Lua.Return(((NumberLiteral)Expression).Value)); } else if (Expression is StringLiteral) { return(Lua.Return(((StringLiteral)Expression).Value)); } else if (Expression is NilLiteral) { return(Lua.Return(LuaObject.Nil)); } else if (Expression is BoolLiteral) { return(Lua.Return(((BoolLiteral)Expression).Value)); } else if (Expression is BinaryExpression) { BinaryExpression exp = (BinaryExpression)Expression; return(Lua.Return(EvalBinaryExpression(exp, Context))); } else if (Expression is UnaryExpression) { UnaryExpression exp = (UnaryExpression)Expression; return(Lua.Return(EvalUnaryExpression(exp, Context))); } else if (Expression is Variable) { Variable var = (Variable)Expression; return(Lua.Return(EvalVariable(var, Context))); } else if (Expression is FunctionCall) { FunctionCall call = (FunctionCall)Expression; return(EvalFunctionCall(call, Context)); } else if (Expression is TableAccess) { TableAccess taccess = (TableAccess)Expression; return(Lua.Return(EvalTableAccess(taccess, Context))); } else if (Expression is FunctionDefinition) { FunctionDefinition fdef = (FunctionDefinition)Expression; return(Lua.Return(EvalFunctionDefinition(fdef, Context))); } else if (Expression is TableConstructor) { TableConstructor tctor = (TableConstructor)Expression; return(Lua.Return(EvalTableConstructor(tctor, Context))); } else if (Expression is VarargsLiteral) { return(Context.Varargs); } return(Lua.Return()); }
static LuaArguments EvalWhile(WhileStat stat, LuaContext Context, out LuaReturnStatus returned) { returned.returned = false; returned.broke = false; LuaObject cond = EvalExpression(stat.Condition, Context)[0]; LuaContext ctx = new LuaContext(Context); while (cond.AsBool()) { LuaArguments obj = EvalBlock(stat.Block, ctx, out returned); if (returned.broke) { break; } if (returned.returned) { return(obj); } else { cond = EvalExpression(stat.Condition, Context)[0]; } } return(Lua.Return()); }
static LuaArguments EvalRepeat(RepeatStat stat, LuaContext Context, out LuaReturnStatus returned) { returned.returned = false; returned.broke = false; LuaContext ctx = new LuaContext(Context); while (true) { LuaArguments obj = EvalBlock(stat.Block, ctx, out returned); if (returned.broke) { break; } if (returned.returned) { return(obj); } LuaObject cond = EvalExpression(stat.Condition, ctx)[0]; if (cond) { break; } } return(Lua.Return()); }
static LuaArguments EvalNumericFor(NumericFor stat, LuaContext Context, out LuaReturnStatus returned) { returned.broke = false; returned.returned = false; var varList = EvalExpression(stat.Var, Context); var limitList = EvalExpression(stat.Limit, Context); var stepList = EvalExpression(stat.Step, Context); var var = LuaEvents.toNumber(varList[0]); var limit = LuaEvents.toNumber(limitList[0]); var step = LuaEvents.toNumber(stepList[0]); if (!(var & limit & step).AsBool()) { throw new LuaException("Error in for loop"); } LuaContext ctx = new LuaContext(Context); while ((step > 0 & var <= limit) | (step <= 0 & var >= limit)) { ctx.SetLocal(stat.Variable, var); LuaArguments obj = EvalBlock(stat.Block, ctx, out returned); if (returned.broke) { break; } if (returned.returned) { return(obj); } var = var + step; } return(Lua.Return()); }
static LuaArguments io_temp(LuaArguments args) { string path = Path.GetTempFileName(); Stream s = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Write, Int16.MaxValue, FileOptions.DeleteOnClose); return(Lua.Return(CreateFileObject(s))); }
static LuaArguments io_output(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { currentOutput = obj; return(Lua.Return(currentOutput)); } else if (obj.IsString) { #if PORTABLE MemoryStream stream = new MemoryStream(); #else FileStream stream = new FileStream(obj.ToString(), FileMode.OpenOrCreate); #endif currentOutput = CreateFileObject(stream); return(Lua.Return(currentOutput)); } else if (args.Length == 0) { return(Lua.Return(currentOutput)); } else { throw new LuaException("Invalid argument"); } }
/// <summary> /// Parses and executes the specified string /// </summary> public LuaArguments DoString(string Chunk) { FunctionDefinition def = new FunctionDefinition(); def.Arguments = new List <Argument>(); def.Body = p.ParseString(Chunk); var function = LuaCompiler.CompileFunction(def, Expression.Constant(ctx)).Compile(); return(function().Call(Lua.Return())); }
/// <summary> /// Parses and executes the specified parsed block /// </summary> public LuaArguments DoAst(Block block) { FunctionDefinition def = new FunctionDefinition(); def.Arguments = new List <Argument>(); def.Body = block; var function = LuaCompiler.CompileFunction(def, Expression.Constant(ctx)).Compile(); return(function().Call(Lua.Return())); }
static LuaArguments math_min(LuaArguments args) { var min = args[0]; foreach (LuaObject o in args) { min = Math.Min(min, o); } return(Lua.Return(min)); }
static LuaArguments math_max(LuaArguments args) { var max = args[0]; foreach (LuaObject o in args) { max = Math.Max(max, o); } return(Lua.Return(max)); }
static LuaArguments close(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { FileObject fobj = obj.luaobj as FileObject; fobj.stream.Close(); } return(Lua.Return()); }
static LuaArguments flush(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { FileObject fobj = obj.luaobj as FileObject; fobj.writer.Flush(); } return(Lua.Return()); }
static LuaArguments read(LuaArguments args) { var self = args[0]; if (isStream(self)) { var fobj = self.luaobj as FileObject; if (args.Length == 1) { var line = fobj.reader.ReadLine(); return(Lua.Return(line)); } else { List <LuaObject> ret = new List <LuaObject>(); foreach (var arg in args) { if (arg == self) { continue; } if (arg.IsNumber) { StringBuilder bld = new StringBuilder(); for (int i = 0; i < arg; i++) { bld.Append((char)fobj.reader.Read()); } ret.Add(bld.ToString()); } else if (arg == "*a") { ret.Add(fobj.reader.ReadToEnd()); } else if (arg == "*l") { ret.Add(fobj.reader.ReadLine()); } else if (arg == "*n") { //TODO: Implement io.read("*n") throw new NotImplementedException(); } } return(Lua.Return(ret.ToArray())); } } else { return(Lua.Return()); } }
static LuaArguments io_write(LuaArguments args) { var obj = args[0]; if (!obj.IsNil) { return(currentOutput["write"].MethodCall(currentOutput, args)); } else { return(Lua.Return()); } }
/// <summary> /// Parses and executes the specified file /// </summary> /// <param name="Filename">The file to execute</param> public LuaArguments DoFile(string Filename) { #if INTERPRETED LuaInterpreter.LuaReturnStatus ret; return(LuaInterpreter.EvalBlock(p.ParseFile(Filename), ctx, out ret)); #endif #if COMPILED FunctionDefinition def = new FunctionDefinition(); def.Arguments = new List <Argument>(); def.Body = p.ParseFile(Filename); var function = LuaCompiler.CompileFunction(def, Expression.Constant(ctx)).Compile(); return(function().Call(Lua.Return())); #endif }
static LuaArguments EvalGenericFor(GenericFor stat, LuaContext Context, out LuaReturnStatus returned) { returned.broke = false; returned.returned = false; LuaArguments args = null; foreach (IExpression expr in stat.Expressions) { if (args == null) { args = EvalExpression(expr, Context); } else { args.Concat(EvalExpression(expr, Context)); } } LuaObject f = args[0], s = args[1], var = args[2]; LuaContext ctx = new LuaContext(Context); while (true) { LuaArguments res = f.Call(s, var); for (int i = 0; i < stat.Variables.Count; i++) { ctx.SetLocal(stat.Variables[i], res[i]); } if (res[0].IsNil) { break; } var = res[0]; LuaArguments obj = EvalBlock(stat.Block, ctx, out returned); if (returned.broke) { break; } if (returned.returned) { return(obj); } } return(Lua.Return()); }
static LuaArguments io_type(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { FileObject fobj = obj.luaobj as FileObject; if (!fobj.stream.CanWrite && !fobj.stream.CanRead) { return(Lua.Return("closed file")); } else { return(Lua.Return("file")); } } return(Lua.Return()); }
static LuaArguments io_open(LuaArguments args) { var file = args[0]; var mode = args[1]; if (file.IsString) { FileMode fmode = FileMode.Open; FileAccess faccess = FileAccess.Read; if (mode.IsString) { switch (mode.ToString()) { case "r": faccess = FileAccess.Read; break; case "w": fmode = FileMode.Create; faccess = FileAccess.ReadWrite; break; case "a": fmode = FileMode.Append; faccess = FileAccess.Write; break; case "r+": case "w+": case "a+": // TODO: Implement rwa+ throw new NotImplementedException(); } } FileStream stream = new FileStream(file.ToString(), fmode, faccess); return(Lua.Return(CreateFileObject(stream))); } else { return(Lua.Return()); } }
static LuaArguments io_input(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { currentInput = obj; return(Lua.Return(currentInput)); } else if (obj.IsString) { currentInput = io_open(args)[0]; return(Lua.Return(currentInput)); } else if (args.Length == 0) { return(Lua.Return(currentInput)); } else { throw new LuaException("Invalid argument"); } }
static LuaArguments seek(LuaArguments args) { var obj = args[0]; var whence = args[1] | "cur"; var offset = args[2] | 0; if (isStream(obj)) { var fobj = obj.luaobj as FileObject; switch (whence.ToString()) { case "cur": fobj.stream.Position += (long)offset; break; case "set": fobj.stream.Position = (long)offset; break; case "end": fobj.stream.Position = fobj.stream.Length + (long)offset; break; } return(Lua.Return(fobj.stream.Position)); } return(Lua.Return()); }
internal static LuaArguments EvalBlock(Block Block, LuaContext Context, out LuaReturnStatus returned) { returned.broke = false; returned.returned = false; LuaArguments obj = new LuaObject[] { LuaObject.Nil }; foreach (IStatement stat in Block.Statements) { if (stat is Assignment) { Assignment assign = stat as Assignment; LuaArguments values = null; foreach (IExpression expr in assign.Expressions) { if (values == null) { values = EvalExpression(expr, Context); } else { values.Concat(EvalExpression(expr, Context)); } } for (int i = 0; i < assign.Variables.Count; i++) { SetAssignable(assign.Variables[i], values[i], Context); } } else if (stat is LocalAssignment) { LocalAssignment assign = stat as LocalAssignment; LuaArguments values = null; foreach (IExpression expr in assign.Values) { if (values == null) { values = EvalExpression(expr, Context); } else { values.Concat(EvalExpression(expr, Context)); } } for (int i = 0; i < assign.Names.Count; i++) { Context.SetLocal(assign.Names[i], values[i]); } } else if (stat is ReturnStat) { ReturnStat ret = stat as ReturnStat; returned.returned = true; List <LuaObject> values = new List <LuaObject>(); int i = 0; foreach (IExpression expr in ret.Expressions) { if (i == ret.Expressions.Count - 1) { values.AddRange(EvalExpression(expr, Context)); } else { values.Add(EvalExpression(expr, Context)[0]); } i++; } return(values.ToArray()); } else if (stat is FunctionCall) { FunctionCall call = stat as FunctionCall; EvalFunctionCall(call, Context); } else if (stat is Block) { Block block = stat as Block; LuaContext ctx = new LuaContext(Context); obj = EvalBlock(block, ctx, out returned); if (returned.returned) { return(obj); } } else if (stat is IfStat) { obj = EvalIf(stat as IfStat, Context, out returned); if (returned.returned) { return(obj); } } else if (stat is WhileStat) { obj = EvalWhile(stat as WhileStat, Context, out returned); if (returned.returned) { return(obj); } } else if (stat is RepeatStat) { obj = EvalRepeat(stat as RepeatStat, Context, out returned); if (returned.returned) { return(obj); } } else if (stat is BreakStat) { returned.returned = false; returned.broke = true; return(Lua.Return(LuaObject.Nil)); } else if (stat is NumericFor) { obj = EvalNumericFor(stat as NumericFor, Context, out returned); if (returned.returned) { return(obj); } } else { obj = EvalGenericFor(stat as GenericFor, Context, out returned); if (returned.returned) { return(obj); } } } return(obj); }
static LuaArguments math_cosh(LuaArguments args) { return(Lua.Return(Math.Cosh(args[0]))); }
static LuaArguments math_exp(LuaArguments args) { return(Lua.Return(Math.Exp(args[0]))); }
static LuaArguments math_floor(LuaArguments args) { return(Lua.Return(Math.Floor(args[0]))); }
static LuaArguments math_log(LuaArguments args) { return(Lua.Return(Math.Log(args[0], args[1] | Math.E))); }
static LuaArguments math_pow(LuaArguments args) { return(Lua.Return(Math.Pow(args[0], args[1]))); }
static LuaArguments math_abs(LuaArguments args) { return(Lua.Return(Math.Abs(args[0]))); }
static LuaArguments math_sinh(LuaArguments args) { return(Lua.Return(Math.Sinh(args[0]))); }
static LuaArguments math_ceil(LuaArguments args) { return(Lua.Return(Math.Ceiling(args[0]))); }