protected override void SetNameDetail(NameItem nameItem, XIAP.FrontendModules.Common.InsuranceDirectoryService.NameData nameData) { base.SetNameDetail(nameItem, nameData); if (nameData.NameType == (short)StaticValues.NameType.Company) { ReadOnlyCollection<INameInvolvementData> nameInvolvementDataCollection = this.GetNameInvolvements(); nameInvolvementDataCollection.ForEach(nameInvolvementData => { ClaimNameInvolvementData claimNameInvolvementData = nameInvolvementData as ClaimNameInvolvementData; if (claimNameInvolvementData != null && !string.IsNullOrWhiteSpace(claimNameInvolvementData.CustomReference04) && this.nameAndEmails[nameItem] != null && nameItem.NameID == claimNameInvolvementData.NameID) { this.nameAndEmails[nameItem].Add(new CodeRow { Code = claimNameInvolvementData.CustomReference04, Description = claimNameInvolvementData.CustomReference04 }); } }); } }
/// <summary> /// Called when get/set the value of a variable, determines whether the /// given variable is a capture from a parrent nested function. /// </summary> /// <param name="name">The name of the variable.</param> public void GetName(NameItem /*!*/ name) { bool inFunc = true; // true if cur is in the current function. TreeNode node = cur; while (node != null) { if (node.CapturedLocals.ContainsKey(name.Name) || node.TrueLocals.ContainsKey(name.Name)) { // ignore the local if it is the current function if (!inFunc) { // if it is in TrueLocals, move it to CapturedLocals. NameItem boundItem; if (node.TrueLocals.TryGetValue(name.Name, out boundItem)) { node.TrueLocals.Remove(name.Name); node.CapturedLocals.Add(name.Name, boundItem); } // update all the CapturesParrent for any nodes between // the current node and the node that defines the local. TreeNode cur2 = cur; while (cur2 != node) { cur2.CapturesParrent = true; cur2 = cur2.Parrent; } } return; } if (node.IsFunction) { inFunc = false; } node = node.Parrent; } }
/// <summary> /// Assigns the values of the parse item to the given value. /// </summary> /// <param name="target">The item to assign the value to (e.g. NameItem).</param> /// <param name="local">Whether this is a local definition.</param> /// <param name="getIndex">A function to get the index of the object, /// pass null to use the default.</param> /// <param name="getValue">A function to get the value to set to.</param> void AssignValue(IParseItem target, bool local, Action getIndex, Action getValue) { ILGenerator gen = compiler.CurrentGenerator; ChunkBuilder.VarDefinition field; if (local) { field = compiler.DefineLocal((NameItem)target); } else if (target is IndexerItem) { IndexerItem name = (IndexerItem)target; // {name.Prefix}.SetIndex({name.Expression}, value); name.Prefix.Accept(this); if (getIndex != null) { getIndex(); } else { name.Expression.Accept(this); } getValue(); gen.Emit(OpCodes.Callvirt, typeof(ILuaValue).GetMethod(nameof(ILuaValue.SetIndex))); return; } else // names[i] is NameItem { NameItem item = (NameItem)target; field = compiler.FindVariable(item); } // envField = value; field.StartSet(); getValue(); field.EndSet(); }
/// <summary> /// Called when the item is a function definition item. /// </summary> /// <param name="target">The object that was passed to IParseItem.Visit.</param> /// <returns>The passed target or a modification of it.</returns> /// <exception cref="System.ArgumentNullException">If target is null.</exception> public IParseItem Visit(FuncDefItem target) { if (target == null) { throw new ArgumentNullException(nameof(target)); } var gen = compiler.CurrentGenerator; ChunkBuilder.VarDefinition field = null; string name = null; bool store = false; if (target.Local) { // local function definition. if (target.InstanceName != null) { throw new SyntaxException(Resources.InstanceLocalMethod, target.Debug); } if (!(target.Prefix is NameItem)) { throw new SyntaxException(Resources.IndexerLocalMethod, target.Debug); } NameItem namei = (NameItem)target.Prefix; name = namei.Name; field = compiler.DefineLocal(namei); field.StartSet(); } else if (target.Prefix != null) { if (target.InstanceName != null) { // instance function definition. name = null; if (target.Prefix is NameItem) { name = ((NameItem)target.Prefix).Name; } else { name = (string)((LiteralItem)((IndexerItem)target.Prefix).Expression).Value; } name += ":" + target.InstanceName; // {Prefix}.SetIndex({InstanceName}, {ImplementFunction(..)}) target.Prefix.Accept(this); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Callvirt, typeof(ILuaEnvironment).GetProperty(nameof(ILuaEnvironment.Runtime)).GetGetMethod()); gen.Emit(OpCodes.Ldstr, target.InstanceName); gen.Emit(OpCodes.Callvirt, typeof(ILuaRuntime).GetMethod(nameof(ILuaRuntime.CreateValue))); store = true; } else if (target.Prefix is IndexerItem) { // global function definition with indexer // {Prefix}.SetIndex({Expression}, {ImplementFunction(..)}) IndexerItem index = (IndexerItem)target.Prefix; name = (string)((LiteralItem)index.Expression).Value; index.Prefix.Accept(this); index.Expression.Accept(this); store = true; } else { // global function definition with name name = ((NameItem)target.Prefix).Name; field = compiler.FindVariable((NameItem)target.Prefix); field.StartSet(); } } compiler.ImplementFunction(this, target, name); if (field != null) { field.EndSet(); } else if (store) { gen.Emit(OpCodes.Callvirt, typeof(ILuaValue).GetMethod(nameof(ILuaValue.SetIndex))); } return(target); }
private static int ItemsCompare(NameItem item1, NameItem item2) { return(-item1.Amount.CompareTo(item2.Amount)); }
public void GenralParse() { PlainParser target = new PlainParser(); TextElementEnumerator input1 = StringInfo.GetTextElementEnumerator( @"local a = 12 t = { [34]= function() print(i) end } function Some(a, ...) a, b, c = ... for i= 12, 23 do print(i) end end" ); IParseItem actual; actual = target.Parse(new Tokenizer(input1, null), null, null); // check the main block BlockItem block = actual as BlockItem; Assert.IsInstanceOf <BlockItem>(actual); Assert.IsNotNull(block.Children); Assert.AreEqual(3, block.Children.Count, "Block.Children.Count"); ValidateDebug(block.Debug, "Block", "local a = 12 t = { [ 34 ] = function ( ) print ( i ) end } function Some ( a , ... ) a , b , c = ... for i = 12 , 23 do print ( i ) end end", 1, 1, 8, 4); // check the return statement of the main block { ReturnItem ret = block.Return; Assert.IsInstanceOf <ReturnItem>(block.Return); ValidateDebug(ret.Debug, "Block.Return", null, 0, 0, 0, 0); Assert.IsNotNull(ret.Expressions); Assert.AreEqual(0, ret.Expressions.Count); } // local a = 12 { AssignmentItem init = block.Children[0] as AssignmentItem; Assert.IsNotNull(init, "Block.Children[0]"); Assert.AreEqual(true, init.Local); ValidateDebug(init.Debug, "Block.Children[0]", "local a = 12", 1, 1, 1, 13); // check the names { Assert.IsNotNull(init.Names, "Block.Children[0].Names"); Assert.AreEqual(1, init.Names.Count, "Block.Children[0].Names.Count"); NameItem name = init.Names[0] as NameItem; Assert.IsNotNull(name, "Block.Children[0].Names[0]"); Assert.AreEqual("a", name.Name, "Block.Children[0].Names[0].Name"); ValidateDebug(name.Debug, "Block.Children[0].Names[0]", "a", 1, 7, 1, 8); } // check the expressions { Assert.IsNotNull(init.Expressions, "Block.Children[0].Expressions"); Assert.AreEqual(1, init.Expressions.Count, "Block.Children[0].Expressions.Count"); LiteralItem literal = init.Expressions[0] as LiteralItem; Assert.IsNotNull(literal, "Block.Children[0].Expressions[0]"); Assert.AreEqual(12.0, literal.Value, "Block.Children[0].Expressions[0].Value"); ValidateDebug(literal.Debug, "Block.Children[0].Expressions[0]", "12", 1, 11, 1, 13); } } // t = { [34]= function() print(i) end } { AssignmentItem init = block.Children[1] as AssignmentItem; Assert.IsNotNull(init, "Block.Children[1]"); Assert.AreEqual(false, init.Local); ValidateDebug(init.Debug, "Block.Children[1]", "t = { [ 34 ] = function ( ) print ( i ) end }", 2, 1, 2, 38); // check the names { Assert.IsNotNull(init.Names, "Block.Children[1].Names"); Assert.AreEqual(1, init.Names.Count, "Block.Children[1].Names.Count"); NameItem name = init.Names[0] as NameItem; Assert.IsNotNull(name, "Block.Children[1].Names[0]"); Assert.AreEqual("t", name.Name, "Block.Children[1].Names[0].Name"); ValidateDebug(name.Debug, "Block.Children[1].Names[0]", "t", 2, 1, 2, 2); } // check the expressions { Assert.IsNotNull(init.Expressions, "Block.Children[1].Expressions"); Assert.AreEqual(1, init.Expressions.Count, "Block.Children[1].Expressions.Count"); TableItem table = init.Expressions[0] as TableItem; Assert.IsNotNull(table, "Block.Children[1].Expressions[0]"); ValidateDebug(table.Debug, "Block.Children[1].Expressions[0]", "{ [ 34 ] = function ( ) print ( i ) end }", 2, 5, 2, 38); Assert.IsNotNull(table.Fields, "Block.Children[1].Expressions[0].Fields"); Assert.AreEqual(1, table.Fields.Count, "Block.Children[1].Expressions[0].Fields.Count"); var field = table.Fields[0]; { LiteralItem literal = field.Key as LiteralItem; Assert.IsNotNull(literal, "Block.Children[1].Expressions[0].Fields[0].Item1"); Assert.AreEqual(34.0, literal.Value, "Block.Children[1].Expressions[0].Fields[0].Item1.Value"); ValidateDebug(literal.Debug, "Block.Children[1].Expressions[0].Fields[0].Item1", "34", 2, 8, 2, 10); } { FuncDefItem func = field.Value as FuncDefItem; Assert.IsNotNull(func, "Block.Children[1].Expressions[0].Fields[0].Item2"); Assert.IsNull(func.InstanceName, "Block.Children[1].Expressions[0].Fields[0].Item2.InstanceName"); Assert.IsNull(func.Prefix, "Block.Children[1].Expressions[0].Fields[0].Item2.Prefix"); Assert.AreEqual(false, func.Local, "Block.Children[1].Expressions[0].Fields[0].Item2.Local"); Assert.IsNull(func.FunctionInformation, "Block.Children[1].Expressions[0].Fields[0].Item2.FunctionInformation"); ValidateDebug(func.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2", "function ( ) print ( i ) end", 2, 13, 2, 36); // validate the block { BlockItem funcBlock = func.Block; Assert.IsNotNull(funcBlock, "Block.Children[1].Expressions[0].Fields[0].Item2.Block"); ValidateDebug(funcBlock.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block", "print ( i )", 2, 24, 2, 32); // validate the return { ReturnItem ret = funcBlock.Return; Assert.IsNotNull(ret, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Return"); ValidateDebug(ret.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Return", null, 0, 0, 0, 0); Assert.IsNotNull(ret.Expressions, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Return.Expressions"); Assert.AreEqual(0, ret.Expressions.Count, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Return.Expressions.Count"); } // validate the statement { Assert.IsNotNull(funcBlock.Children, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children"); Assert.AreEqual(1, funcBlock.Children.Count, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children.Count"); // print ( i ) { FuncCallItem call = funcBlock.Children[0] as FuncCallItem; Assert.IsNotNull(call, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0]"); Assert.AreEqual(true, call.Statement, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Statement"); Assert.IsNull(call.InstanceName, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].InstanceName"); ValidateDebug(call.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0]", "print ( i )", 2, 24, 2, 32); // validate the prefix { NameItem name = call.Prefix as NameItem; Assert.IsNotNull(call.Prefix, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Prefix"); Assert.AreEqual("print", name.Name, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Prefix.Name"); ValidateDebug(name.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Prefix.Name", "print", 2, 24, 2, 29); } // validate the arguments { Assert.IsNotNull(call.Arguments, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments"); Assert.AreEqual(1, call.Arguments.Count, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments.Count"); NameItem name = call.Arguments[0].Expression as NameItem; Assert.IsNotNull(name, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments[0]"); Assert.AreEqual("i", name.Name, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments[0].Name"); ValidateDebug(name.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments[0]", "i", 2, 30, 2, 31); } } } } } } } // function Some(a, ...) { FuncDefItem func = block.Children[2] as FuncDefItem; Assert.IsNotNull(func, "Block.Children[2]"); Assert.AreEqual(false, func.Local, "Block.Children[2].Local"); Assert.IsNull(func.InstanceName, "Block.Children[2].InstanceName"); ValidateDebug(func.Debug, "Block.Children[2]", "function Some ( a , ... ) a , b , c = ... for i = 12 , 23 do print ( i ) end end", 3, 1, 8, 4); // validate the block { BlockItem someBlock = func.Block; ValidateDebug(someBlock.Debug, "Block.Children[2].Block", "a , b , c = ... for i = 12 , 23 do print ( i ) end", 4, 5, 7, 8); // validate the return { ReturnItem ret = someBlock.Return; Assert.IsNotNull(ret, "Block.Children[2].Block.Return"); ValidateDebug(ret.Debug, "Block.Children[2].Block.Return", null, 0, 0, 0, 0); Assert.IsNotNull(ret.Expressions, "Block.Children[2].Block.Return.Expressions"); Assert.AreEqual(0, ret.Expressions.Count, "Block.Children[2].Block.Return.Expressions.Count"); } // check the children { Assert.IsNotNull(someBlock.Children, "Block.Children[2].Block.Children"); Assert.AreEqual(2, someBlock.Children.Count, "Block.Children[2].Block.Children.Count"); // a , b , c = ... { AssignmentItem varInit = someBlock.Children[0] as AssignmentItem; Assert.IsNotNull(varInit, "Block.Children[2].Block.Children[0]"); Assert.AreEqual(false, varInit.Local, "Block.Children[2].Block.Children[0].Local"); ValidateDebug(varInit.Debug, "Block.Children[2].Block.Children[0]", "a , b , c = ...", 4, 5, 4, 18); // validate the names { Assert.IsNotNull(varInit.Names, "Block.Children[2].Block.Children[0].Names"); Assert.AreEqual(3, varInit.Names.Count, "Block.Children[2].Block.Children[0].Names.Count"); NameItem name = varInit.Names[0] as NameItem; Assert.IsNotNull(name, "Block.Children[2].Block.Children[0].Names[0]"); Assert.AreEqual(name.Name, "a", "Block.Children[2].Block.Children[0].Names[0].Name"); ValidateDebug(name.Debug, "Block.Children[2].Block.Children[0].Names[0]", "a", 4, 5, 4, 6); name = varInit.Names[1] as NameItem; Assert.IsNotNull(name, "Block.Children[2].Block.Children[0].Names[1]"); Assert.AreEqual(name.Name, "b", "Block.Children[2].Block.Children[0].Names[1].Name"); ValidateDebug(name.Debug, "Block.Children[2].Block.Children[0].Names[1]", "b", 4, 8, 4, 9); name = varInit.Names[2] as NameItem; Assert.IsNotNull(name, "Block.Children[2].Block.Children[0].Names[2]"); Assert.AreEqual(name.Name, "c", "Block.Children[2].Block.Children[0].Names[2].Name"); ValidateDebug(name.Debug, "Block.Children[2].Block.Children[0].Names[2]", "c", 4, 11, 4, 12); } // validate the expressions { Assert.IsNotNull(varInit.Expressions, "Block.Children[2].Block.Children[0].Expressions"); Assert.AreEqual(1, varInit.Expressions.Count, "Block.Children[2].Block.Children[0].Expressions.Count"); NameItem name = varInit.Expressions[0] as NameItem; Assert.IsNotNull(name, "Block.Children[2].Block.Children[0].Expressions[0]"); Assert.AreEqual(name.Name, "...", "Block.Children[2].Block.Children[0].Expressions[0].Name"); ValidateDebug(name.Debug, "Block.Children[2].Block.Children[0].Expressions[0]", "...", 4, 15, 4, 18); } } // for i= 12, 23 do print ( i ) end { ForNumItem forLoop = someBlock.Children[1] as ForNumItem; Assert.IsNotNull(forLoop, "Block.Children[2].Block.Children[1]"); ValidateDebug(forLoop.Debug, "Block.Children[2].Block.Children[1]", "for i = 12 , 23 do print ( i ) end", 5, 5, 7, 8); // validate the name { NameItem name = forLoop.Name; Assert.IsNotNull(name, "Block.Children[2].Block.Children[1].Name"); ValidateDebug(name.Debug, "Block.Children[2].Block.Children[1].Name", "i", 5, 9, 5, 10); Assert.AreEqual(name.Name, "i", "Block.Children[2].Block.Children[1].Name.Name"); } // validate the start { LiteralItem lit = forLoop.Start as LiteralItem; Assert.IsNotNull(lit, "Block.Children[2].Block.Children[1].Start"); Assert.AreEqual(12.0, lit.Value, "Block.Children[2].Block.Children[1].Start.Value"); ValidateDebug(lit.Debug, "Block.Children[2].Block.Children[1].Start", "12", 5, 12, 5, 14); } // validate the limit { LiteralItem lit = forLoop.Limit as LiteralItem; Assert.IsNotNull(lit, "Block.Children[2].Block.Children[1].Limit"); Assert.AreEqual(23.0, lit.Value, "Block.Children[2].Block.Children[1].Limit.Value"); ValidateDebug(lit.Debug, "Block.Children[2].Block.Children[1].Limit", "23", 5, 16, 5, 18); } // validate the step { Assert.IsNull(forLoop.Step, "Block.Children[2].Block.Children[1].Step"); } // validate the block { BlockItem forBlock = forLoop.Block; ValidateDebug(forBlock.Debug, "Block.Children[2].Block.Children[1].Block", "print ( i )", 6, 9, 6, 17); Assert.IsNull(forBlock.Return, "Block.Children[2].Block.Children[1].Block.Return"); // validate the statement { Assert.IsNotNull(forBlock.Children, "Block.Children[2].Block.Children[1].Block.Children"); Assert.AreEqual(1, forBlock.Children.Count, "Block.Children[2].Block.Children[1].Block.Children.Count"); // print ( i ) { FuncCallItem call = forBlock.Children[0] as FuncCallItem; Assert.IsNotNull(call, "Block.Children[2].Block.Children[1].Block.Children[0]"); Assert.AreEqual(true, call.Statement, "Block.Children[2].Block.Children[1].Block.Children[0].Statement"); Assert.IsNull(call.InstanceName, "Block.Children[2].Block.Children[1].Block.Children[0].InstanceName"); ValidateDebug(call.Debug, "Block.Children[2].Block.Children[1].Block.Children[0]", "print ( i )", 6, 9, 6, 17); // validate the prefix { NameItem name = call.Prefix as NameItem; Assert.IsNotNull(call.Prefix, "Block.Children[2].Block.Children[1].Block.Children[0].Prefix"); Assert.AreEqual("print", name.Name, "Block.Children[2].Block.Children[1].Block.Children[0].Prefix.Name"); ValidateDebug(name.Debug, "Block.Children[2].Block.Children[1].Block.Children[0].Prefix.Name", "print", 6, 9, 6, 14); } // validate the arguments { Assert.IsNotNull(call.Arguments, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments"); Assert.AreEqual(1, call.Arguments.Count, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments.Count"); NameItem name = call.Arguments[0].Expression as NameItem; Assert.IsNotNull(name, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments[0]"); Assert.AreEqual("i", name.Name, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments[0].Name"); ValidateDebug(name.Debug, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments[0]", "i", 6, 15, 6, 16); } } } } } } } } }
/// <summary> /// Defines a new local variable and returns an object used to get/set it's value. There are /// two possible variable types: Local and Captured. Which one is chosen depends on whether the /// variable is captured in the FunctionInfo used to create the current function. /// </summary> /// <param name="name">The name of the variable.</param> /// <returns>An object used to get/set it's value.</returns> public IVarDefinition DefineLocal(NameItem name) { return(_curNest.DefineLocal(name)); }
/// <summary> /// Reads a function from the input. Input must be on the word 'function'. If canName is true, /// it will give the function the read name; otherwise it will give it a null name. /// </summary> /// <param name="input">Where to read input from.</param> /// <param name="canName">True if the function can have a name, otherwise false.</param> /// <param name="local">True if this function is a local definition, otherwise false.</param> /// <returns>The function definition that was read.</returns> protected virtual FuncDefItem _readFunctionHelper(Lexer input, bool canName, bool local) { Token debug = input.Expect(TokenType.Function); IParseVariable name = null; string instName = null; if (input.PeekType(TokenType.Identifier)) { Token temp = input.Expect(TokenType.Identifier); name = new NameItem(temp.Value) { Debug = temp }; while (input.ReadIfType(TokenType.Indexer)) { temp = input.Expect(TokenType.Identifier); var literal = new LiteralItem(temp.Value) { Debug = temp }; name = new IndexerItem(name, literal) { Debug = name.Debug }; } if (input.ReadIfType(TokenType.Colon)) { instName = input.Expect(TokenType.Identifier).Value; } } if (name != null && !canName) { throw new SyntaxException(Resources.FunctionCantHaveName, input.Name, debug); } if (name == null && canName) { throw new SyntaxException("Function statements must provide name", input.Name, debug); } var args = new List <NameItem>(); input.Expect(TokenType.BeginParen); if (!input.PeekType(TokenType.EndParen)) { do { Token temp = input.PeekType(TokenType.Elipsis) ? input.Expect(TokenType.Elipsis) : input.Expect(TokenType.Identifier); args.Add(new NameItem(temp.Value) { Debug = temp }); if (temp.Value == "...") { break; } } while (input.ReadIfType(TokenType.Comma)); } input.Expect(TokenType.EndParen); BlockItem chunk = _readBlock(input); input.Expect(TokenType.End); chunk.Return ??= new ReturnItem(); return(new FuncDefItem(args.ToArray(), chunk) { Debug = debug, InstanceName = instName, Prefix = name, Local = local, }); }
/// <summary> /// Reads an expression from the input. /// </summary> /// <param name="input">Where to read input from.</param> /// <param name="precedence">The precedence of the previous expression or -1 if a root.</param> /// <returns>The expression that was read.</returns> protected virtual IParseExp _readExp(Lexer input, out bool isParentheses, int precedence = -1) { Token debug = input.Peek(); IParseExp ret; var unOpType = _getUnaryOperationType(input.Peek().Type); isParentheses = false; if (unOpType != UnaryOperationType.Unknown) { input.Read(); int unaryPrec = 11; if (unaryPrec > precedence && precedence >= 0) { unaryPrec = precedence; } ret = new UnOpItem(_readExp(input, out _, unaryPrec), unOpType) { Debug = debug }; } else if (input.ReadIfType(TokenType.Nil)) { ret = new LiteralItem(null) { Debug = debug }; } else if (input.ReadIfType(TokenType.False)) { ret = new LiteralItem(false) { Debug = debug }; } else if (input.ReadIfType(TokenType.True)) { ret = new LiteralItem(true) { Debug = debug }; } else if (input.ReadIfType(TokenType.NumberLiteral)) { ret = new LiteralItem(Helpers.ParseNumber(debug.Value)) { Debug = debug }; } else if (input.ReadIfType(TokenType.StringLiteral)) { ret = new LiteralItem(debug.Value) { Debug = debug }; } else if (input.ReadIfType(TokenType.Elipsis)) { ret = new NameItem("...") { Debug = debug }; } else if (input.PeekType(TokenType.BeginTable)) { ret = _readTable(input); } else if (input.PeekType(TokenType.Function)) { ret = _readFunctionHelper(input, false, false); } else { ret = _readPrefixExp(input, out isParentheses); } while (true) { BinaryOperationType binOpType = _getBinaryOperationType(input.Peek().Type); int newPrecedence = _getPrecedence(binOpType); if (binOpType == BinaryOperationType.Unknown || (newPrecedence < precedence && precedence >= 0)) { break; } input.Read(); // For left-associative operations, use a lower precedence so the nested call doesn't read // more than it should. a+b+c should be (a+b)+c, so we need the first add to be its own // item and then have that should be the lhs of another add. Note this only works if // operations of the same precedence have the same associativity. int extra = _isRightAssociative(binOpType) ? 0 : 1; IParseExp other = _readExp(input, out _, newPrecedence + extra); ret = new BinOpItem(ret, binOpType, other) { Debug = debug }; isParentheses = false; } return(ret); }
/// <summary> /// Reads a prefix-expression from the input. /// </summary> /// <param name="input">The input to read from.</param> /// <returns>The parsed expression.</returns> protected virtual IParseExp _readPrefixExp(Lexer input, out bool isParentheses) { Token debug = input.Peek(); IParseExp ret; if (input.ReadIfType(TokenType.BeginParen)) { isParentheses = true; ret = _readExp(input, out _); input.Expect(TokenType.EndParen); } else { isParentheses = false; Token name = input.Expect(TokenType.Identifier); ret = new NameItem(name.Value) { Debug = name }; } while (true) { if (input.ReadIfType(TokenType.BeginBracket)) { isParentheses = false; IParseExp temp = _readExp(input, out _); ret = new IndexerItem(ret, temp) { Debug = debug }; input.Expect(TokenType.EndBracket); } else if (input.ReadIfType(TokenType.Indexer)) { isParentheses = false; Token token = input.Expect(TokenType.Identifier); var name = new LiteralItem(token.Value) { Debug = token }; ret = new IndexerItem(ret, name) { Debug = debug }; } else { string instName = null; int overload = -1; if (input.ReadIfType(TokenType.Colon)) { instName = input.Expect(TokenType.Identifier).Value; int idx = instName.IndexOf('`'); if (idx >= 0) { if (!int.TryParse(instName.Substring(idx + 1), out overload)) { throw input.SyntaxError(Resources.OnlyNumbersInOverload); } instName = instName.Substring(0, idx); } } else if (ret is NameItem name) { int idx = name.Name.IndexOf('`'); if (idx >= 0) { if (!int.TryParse(name.Name.Substring(idx + 1), out overload)) { throw input.SyntaxError(Resources.OnlyNumbersInOverload); } name.Name = name.Name.Substring(0, idx); } } bool isLastSingle = false; var args = new List <FuncCallItem.ArgumentInfo>(); if (input.PeekType(TokenType.BeginTable)) { args.Add(new FuncCallItem.ArgumentInfo(_readTable(input), false)); } else if (input.PeekType(TokenType.StringLiteral)) { Token token = input.Expect(TokenType.StringLiteral); args.Add(new FuncCallItem.ArgumentInfo(new LiteralItem(token.Value) { Debug = token }, false)); } else if (input.ReadIfType(TokenType.BeginParen)) { if (!input.PeekType(TokenType.EndParen)) { do { bool isRef = input.ReadIfType(TokenType.Ref); bool isRefParen = false; if (isRef) { isRefParen = input.ReadIfType(TokenType.BeginParen); } else { isRef = input.ReadIfType(TokenType.RefSymbol); } args.Add(new FuncCallItem.ArgumentInfo(_readExp(input, out isLastSingle), isRef)); if (isRefParen) { input.Expect(TokenType.EndParen); } } while (input.ReadIfType(TokenType.Comma)); } input.Expect(TokenType.EndParen); } else { break; } isParentheses = false; ret = new FuncCallItem(ret, args.ToArray()) { Debug = debug, InstanceName = instName, Overload = overload, IsLastArgSingle = isLastSingle, }; } } return(ret); }
/// <summary> /// Reads a for statement from the input. /// </summary> /// <param name="input">Where to read input from.</param> /// <returns>The object that was read.</returns> protected virtual IParseStatement _readFor(Lexer input) { Token debug = input.Expect(TokenType.For); Token name = input.Expect(TokenType.Identifier); var nameItem = new NameItem(name.Value) { Debug = name }; if (input.ReadIfType(TokenType.Assign)) { // Numeric for IParseExp start = _readExp(input, out _); input.Expect(TokenType.Comma); IParseExp limit = _readExp(input, out _); IParseExp step = null; if (input.ReadIfType(TokenType.Comma)) { step = _readExp(input, out _); } input.Expect(TokenType.Do); var block = _readBlock(input); input.Expect(TokenType.End); return(new ForNumItem(nameItem, start, limit, step, block) { Debug = debug }); } else { // Generic for statement // Read the variables var names = new List <NameItem>() { nameItem }; while (input.ReadIfType(TokenType.Comma)) { Token token = input.Expect(TokenType.Identifier); names.Add(new NameItem(token.Value) { Debug = token }); } input.Expect(TokenType.In); // Read the expression-list var exps = new List <IParseExp>(); exps.Add(_readExp(input, out _)); while (input.ReadIfType(TokenType.Comma)) { exps.Add(_readExp(input, out _)); } input.Expect(TokenType.Do); var block = _readBlock(input); input.Expect(TokenType.End); return(new ForGenItem(names.ToArray(), exps.ToArray(), block) { Debug = debug }); } }
public void Post([FromBody] NameItem value) { _context.Add(value); _context.SaveChanges(); }