public override LuatValue Resolve(LuatScript script) { LuatValue value = base.Resolve(script); if (null != value) { return(value); } int index = 1; foreach (Identifier identifier in this.Parameters) { LuatVariable local = this.Block.AddLocal(script, identifier, null); local.Description = string.Format("parameter {0}", index++); } List <string> args = new List <string>(); foreach (Identifier param in this.Parameters) { args.Add(param.Text); } LuatValue returnValue = this.Block.ReturnValues[script]; LuatFunction function = new LuatFunction(returnValue, args.ToArray()); function.Description = this.Description; function.ExpectsSelf = this.ExpectsSelf; value = function; this.ResolvedValues[script] = value; return(value); }
public LuatVariable AddLocal(LuatScript script, Identifier Name, string type) { string name = Name.Text; LuatVariable variable = Locals[script].Index(name, false) as LuatVariable; if (null == variable) { LuatTable localTable = Locals[script]; if (null != type) { variable = Database.Instance.CreateReflectedVariable(type, localTable); } if (null == variable) { variable = new LuatVariable(localTable); } localTable.AddChild(name, variable); } else { Name.AddWarning(script, WarningType.DuplicateLocal, "Warning: Local '" + name + "' already defined"); } return(variable); }
public override bool Install(LuatScript script) { if (false == base.Install(script)) { return(false); } if (null == this.Body) { return(false); } if (null == this.Start) { return(false); } LuatVariable iterator = Body.AddLocal(script, Iterator.Name, null); LuatValue.IReference reference = new Parser.AST.Expression.Reference(script, this.Start); iterator.AddAssignment(reference); AddUninstallAction(script, delegate() { iterator.RemoveAssignment(reference); }); return(base.Install(script)); }
private static void AddSledSpecificFunctions(LuatTable table) { if (table == null) { return; } // add libsleddebugger table { var debuggerTable = new LuatTable { Description = "libsleddebugger injected functionality" }; debuggerTable.AddChild("version", new LuatLiteral(LuatTypeString.Instance)); debuggerTable.AddChild("instance", new LuatLiteral(LuatTypeNumber.Instance)); table.AddChild("libsleddebugger", debuggerTable); } // add libsledluaplugin table { var luaPluginTable = new LuatTable { Description = "libsledluaplugin injected functionality" }; luaPluginTable.AddChild("version", new LuatLiteral(LuatTypeString.Instance)); luaPluginTable.AddChild("instance", new LuatLiteral(LuatTypeNumber.Instance)); { var retVal = new LuatVariable(null, LuatTypeNil.Instance, LuatVariableFlags.None); var function = new LuatFunction(retVal, new[] { "message" }) { ExpectsSelf = false }; luaPluginTable.AddChild("tty", function); } { var retVal = new LuatVariable(null, LuatTypeNil.Instance, LuatVariableFlags.None); var function = new LuatFunction(retVal, new[] { "condition", "message" }) { ExpectsSelf = false }; luaPluginTable.AddChild("assert", function); } { var retVal = new LuatVariable(null, LuatTypeNil.Instance, LuatVariableFlags.None); var function = new LuatFunction(retVal, new[] { "error" }) { ExpectsSelf = false }; luaPluginTable.AddChild("errorhandler", function); } table.AddChild("libsledluaplugin", luaPluginTable); } }
public override LuatValue Resolve(LuatScript script) { LuatValue value = base.Resolve(script); if (null != value) { return(value); } LuatTable table = new LuatTable(null); int fieldIndex = 1; foreach (Field field in Fields) { string key; if (null == field.Key) { key = (fieldIndex++).ToString(); } else if (field.Key is StringExpression) { key = (field.Key as StringExpression).String; } else if (field.Key is NumberExpression) { key = (field.Key as NumberExpression).Number.ToString(); } else if (field.Key is Identifier) { key = (field.Key as Identifier).Text; } else { continue; } if (null != table.Index(key, false)) { field.AddWarning(script, WarningType.DuplicateTableKey, string.Format("Table already contains key '{0}'", key)); continue; } LuatVariable entry = table.AddChild(key, new LuatVariable(table)); entry.Description = Description; if (null != field.Value) { entry.AddAssignment(new Parser.AST.Expression.Reference(script, field.Value, this.DisplayText)); } } this.ResolvedValues[script] = table; return(table); }
public override bool Install(LuatScript script) { if (false == base.Install(script)) { return(false); } BlockStatement block; Function func = this.FindAncestor <Function>(); if (null != func) { block = func.Block; } else { block = this.FindAncestor <BlockStatement>(); } if (null == block) { throw new Exception("ReturnStatement requires a BlockStatement as ancestor"); } List <LuatValue> values = new List <LuatValue>(); foreach (Expression expression in Values) { // TODO: not correct for multiple return values LuatVariable returnValue = block.ReturnValues[script]; LuatValue.IReference reference = new Parser.AST.Expression.Reference(script, expression, "return " + expression.DisplayText); returnValue.AddAssignment(reference); AddUninstallAction(script, delegate() { returnValue.RemoveAssignment(reference); }); } if (IsMultiline) { AddWarning(script, WarningType.MultilineReturn, string.Format("Returning value from next line")); } return(true); }
public override LuatValue Resolve(LuatScript script) { LuatValue value = base.Resolve(script); if (null != value) { return(value); } LuatValue funcValue = Owner.Resolve(script); if (null == funcValue) { return(null); } if (null != Name) { // funcValue isn't actually the function, but the owner. funcValue = funcValue.Index(Name.Text); if (null == funcValue) { return(null); } } // Infer return type for value LuatFunction function = funcValue as LuatFunction; if (null == function) { LuatVariable variable = funcValue as LuatVariable; if (null != variable) { foreach (LuatValue.IReference reference in variable.AssignmentsRecursive) { function = reference.Value as LuatFunction; if (null != function) { break; } } } } if (null == function) { return(null); } if (function.ExpectsSelf != this.PassesSelf) { string warning = string.Format("Function expects to be called using '{0}' not '{1}'", function.ExpectsSelf ? ':' : '.', this.PassesSelf ? ':' : '.'); AddWarning(script, WarningType.WrongFunctionCall, warning); } this.m_resolvedFunctions.Add(script, function); this.ResolvedValues[script] = function.ReturnValue; return(function); }
public override bool Install(LuatScript script) { if (false == base.Install(script)) { return(false); } if (false == IsLocal && Values.Count == 0) { // Illegal assignment statement, assumes parser has already emitted error. return(false); } int variableCount = Variables.Count; for (int variableIndex = 0; variableIndex < variableCount; ++variableIndex) { Expression lhs = Variables[variableIndex] as Expression; Expression rhs; if (variableIndex < Values.Count) { rhs = Values[variableIndex] as Expression; } else { rhs = new NilExpression(lhs.TextRange); rhs.Resolve(script); this.ChildNodes.Add(rhs); } LuatVariable variable = lhs.Resolve(script) as LuatVariable; bool bValid = false; do { if (null == variable) { break; } if (variable.IsReadOnly) { this.AddError(string.Format("{0} is read-only", lhs.DisplayText)); break; } bValid = true; }while (false); if (false == bValid) { // Failed to resolve or create the name. // Undo all the assignments we've done and return incomplete. Uninstall(script); return(false); } string displayText = string.Format("{0} = {1}", lhs.DisplayText, rhs.DisplayText); LuatValue.IReference reference = new Parser.AST.Expression.Reference(script, rhs, displayText); variable.AddAssignment(reference); AddUninstallAction(script, delegate() { variable.RemoveAssignment(reference); }); } return(true); }