static Expression CompileTableConstructor(Ast.TableConstructor table, Expression Context) { var values = new List <KeyValuePair <Expression, Expression> >(); int i = 0; var exprs = new List <Expression>(); var type = typeof(Dictionary <LuaObject, LuaObject>); var add = type.GetMethod("Add", new[] { LuaObject_Type, LuaObject_Type }); var variable = Expression.Parameter(type); var assign = Expression.Assign(variable, Expression.New(type.GetConstructor(new Type[] { }))); exprs.Add(assign); foreach (KeyValuePair <IExpression, IExpression> kvpair in table.Values) { if (i == table.Values.Count - 1) { var k = CompileSingleExpression(kvpair.Key, Context); var v = CompileExpression(kvpair.Value, Context); var singlev = GetFirstArgument(v); var ifFalse = Expression.Call(variable, add, k, singlev); var counter = Expression.Parameter(typeof(int)); var value = Expression.Parameter(LuaArguments_Type); var @break = Expression.Label(); var breakLabel = Expression.Label(@break); var assignValue = Expression.Assign(value, v); var assignCounter = Expression.Assign(counter, Expression.Constant(0)); var incrementCounter = Expression.Assign(counter, Expression.Increment(counter)); var loopCondition = Expression.LessThan(counter, Expression.Property(v, "Length")); var addValue = Expression.Call(variable, add, Expression.Add(k, Expression.Call(LuaObject_Type.GetMethod("FromNumber"), Expression.Convert(counter, typeof(double)))), Expression.Property(value, "Item", counter)); var check = Expression.IfThenElse(loopCondition, Expression.Block(addValue, incrementCounter), Expression.Break(@break)); var loopBody = Expression.Loop(check); var ifTrue = Expression.Block(new[] { counter, value }, assignCounter, assignValue, loopBody, breakLabel); var condition = Expression.IsTrue(Expression.Property(k, "IsNumber")); var ifblock = Expression.IfThenElse(condition, ifTrue, ifFalse); exprs.Add(ifblock); } else { var k = CompileSingleExpression(kvpair.Key, Context); var v = CompileSingleExpression(kvpair.Value, Context); exprs.Add(Expression.Call(variable, add, k, v)); } i++; } exprs.Add(Expression.Call(LuaObject_Type.GetMethod("FromTable"), variable)); var block = Expression.Block(new[] { variable }, exprs.ToArray()); return(Expression.Invoke(Expression.Lambda <Func <LuaObject> >(block))); }
Ast.TableConstructor ParseTableConstruct(ParseTreeNode node) { if (node.Term.Name == "TableConstruct") { if (node.ChildNodes.Count == 0) { return(new Ast.TableConstructor() { Values = new Dictionary <Ast.IExpression, Ast.IExpression>() }); } else { var child = node.ChildNodes[0]; Ast.TableConstructor t = new Ast.TableConstructor(); t.Values = new Dictionary <Ast.IExpression, Ast.IExpression>(); int i = 1; while (true) { if (child.ChildNodes.Count == 0) { break; } var value = child.ChildNodes[0]; if (value.ChildNodes.Count == 1) { t.Values.Add(new Ast.NumberLiteral() { Value = i }, ParseExpression(value.ChildNodes[0])); i++; } else { var prefix = value.ChildNodes[0]; Ast.IExpression key; if (prefix.ChildNodes[0].Term.Name == "identifier") { key = new Ast.StringLiteral() { Value = prefix.ChildNodes[0].Token.ValueString } } ; else { key = ParseExpression(prefix.ChildNodes[0]); } var expr = value.ChildNodes[1]; Ast.IExpression val = ParseExpression(expr); t.Values.Add(key, val); } //child = child.ChildNodes[1].ChildNodes[0]; child = child.ChildNodes[1]; if (child.ChildNodes.Count == 0) { break; } child = child.ChildNodes[0]; } return(t); } } throw new Exception("Invalid TableConstruct node"); }
Ast.TableConstructor ParseTableConstruct(ParseTreeNode node) { if (node.Term.Name == "TableConstruct") { if (node.ChildNodes.Count == 0) { return new Ast.TableConstructor() { Values = new Dictionary<Ast.IExpression, Ast.IExpression>() }; } else { var child = node.ChildNodes[0]; Ast.TableConstructor t = new Ast.TableConstructor(); t.Values = new Dictionary<Ast.IExpression, Ast.IExpression>(); int i = 1; while (true) { if (child.ChildNodes.Count == 0) break; var value = child.ChildNodes[0]; if (value.ChildNodes.Count == 1) { t.Values.Add(new Ast.NumberLiteral() { Value = i }, ParseExpression(value.ChildNodes[0])); i++; } else { var prefix = value.ChildNodes[0]; Ast.IExpression key; if (prefix.ChildNodes[0].Term.Name == "identifier") key = new Ast.StringLiteral() { Value = prefix.ChildNodes[0].Token.ValueString }; else key = ParseExpression(prefix.ChildNodes[0]); var expr = value.ChildNodes[1]; Ast.IExpression val = ParseExpression(expr); t.Values.Add(key, val); } //child = child.ChildNodes[1].ChildNodes[0]; child = child.ChildNodes[1]; if (child.ChildNodes.Count == 0) break; child = child.ChildNodes[0]; } return t; } } throw new Exception("Invalid TableConstruct node"); }