public DekiScriptExpression Visit(DekiScriptMapConstructor expr, DekiScriptExpressionEvaluationState state) { // TODO (steveb): need to figure out how to optimize maps with generators if (expr.Generator != null) { return(expr); } // optimize each item in the map var fields = new DekiScriptMapConstructor.FieldConstructor[expr.Fields.Length]; bool isLiteral = true; for (int i = 0; i < expr.Fields.Length; i++) { var current = expr.Fields[i]; DekiScriptExpression key = current.Key.VisitWith(this, state); DekiScriptExpression value = current.Value.VisitWith(this, state); fields[i] = new DekiScriptMapConstructor.FieldConstructor(current.Location, key, value); isLiteral = isLiteral && (key is DekiScriptLiteral) && (value is DekiScriptLiteral); } if (!isLiteral) { return(DekiScriptExpression.Map(expr.Location, fields)); } // convert expression to a map DekiScriptMap result = new DekiScriptMap(); foreach (var field in fields) { DekiScriptLiteral key = (DekiScriptLiteral)field.Key; // check that key is a simple type string text = key.AsString(); if (text != null) { result.Add(text, (DekiScriptLiteral)field.Value); } } return(result); }
void Field(out DekiScriptMapConstructor.FieldConstructor field) { DekiScriptExpression expr = null; DekiScriptExpression key = null; string name = null; Location location = Location.None; if (StartOf(11)) { AnyName(out name); key = DekiScriptExpression.Constant(name); } else if (la.kind == 3 || la.kind == 4) { String(out key); } else if (la.kind == 5) { Get(); key = DekiScriptExpression.Constant(t.val); } else if (la.kind == 22) { Get(); Expression(out key); Expect(23); } else SynErr(91); Expect(31); location = t.Location; Expression(out expr); field = new DekiScriptMapConstructor.FieldConstructor(location, key, expr); }