public RelationSchemaDiffLoader(RelationSchema.Schema SchemaNew, TreeFormatParseSetting OuterParsingSetting, TreeFormatEvaluateSetting OuterEvaluateSetting) { EntityFields = SchemaNew.GetMap().Where(p => p.Value.OnEntity).ToDictionary(p => p.Key, p => p.Value.Entity.Fields.ToDictionary(f => f.Name)); EntityMappings = new List <Semantics.Node>(); Positions = new Dictionary <Object, Syntax.FileTextRange>(); this.tfpo = OuterParsingSetting; this.tfeo = OuterEvaluateSetting; }
private void Load(String TreePath, StreamReader Reader) { var ps = new TreeFormatParseSetting { IsTableParameterFunction = Name => Name == "Module" }; var es = new TreeFormatEvaluateSetting { FunctionCallEvaluator = (f, nm) => { if (f.Parameters.Count < 1 || f.Parameters.Count > 2) { throw new Syntax.InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f); } var Name = GetLeafNodeValue(f.Parameters[0], nm, "InvalidName"); String Description = ""; if (f.Parameters.Count == 2) { Description = GetLeafNodeValue(f.Parameters[1], nm, "InvalidDescription"); } var ContentLines = new List <Syntax.TextLine> { }; if (f.Content.OnSome) { var ContentValue = f.Content.Value; if (!ContentValue.OnLineContent) { throw new Syntax.InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentValue), ContentValue); } ContentLines = ContentValue.LineContent.Lines; } if (f.Name.Text == "Module") { var Functions = new List <FunctionDecl>(); foreach (var Line in ContentLines) { var Trimmed = Line.Text.Trim(); if (Trimmed == "") { continue; } if (Trimmed.StartsWith("//")) { continue; } var ep = new ExpressionParser(nm.Text, null); var epdr = ep.ParseDeclaration(Line.Range); Functions.Add(epdr.Declaration); } Modules.Add(new ModuleDecl { Name = Name, Description = Description, Functions = Functions }); } else { throw new Syntax.InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f); } return(new List <Node> { }); } }; var pr = TreeFile.ReadRaw(Reader, TreePath, ps); var tfe = new TreeFormatEvaluator(es, pr); tfe.Evaluate(); }
public static FileParserResult ParseFile(Text Text) { var TypeFunctions = new HashSet <String>() { "Primitive", "Alias", "Record", "TaggedUnion", "Enum", "ClientCommand", "ServerCommand" }; var Functions = new HashSet <String>(TypeFunctions.Concat(new List <String>() { "Namespace", "Import" })); var ps = new TreeFormatParseSetting() { IsTableParameterFunction = Name => Functions.Contains(Name), IsTableContentFunction = Name => Functions.Contains(Name), IsTreeParameterFunction = Name => false, IsTreeContentFunction = Name => false }; var sp = new TreeFormatSyntaxParser(ps, Text); var ParserResult = sp.Parse(); var ts = new TreeSerializer(); var Types = new List <TypeDef>(); var TypeRefs = new List <TypeDef>(); var Imports = new List <String>(); var TypeToNamespace = new Dictionary <TypeDef, List <String> >(); var TypeToNamespaceImports = new Dictionary <TypeDef, List <List <String> > >(); var CurrentNamespace = new List <String>(); var CurrentNamespaceImports = new List <List <String> >(); var Positions = new Dictionary <Object, TextRange>(); foreach (var TopNode in ParserResult.Value.MultiNodesList) { if (TopNode.OnFunctionNodes) { var pr = new TreeFormatParseResult { Value = new Forest { MultiNodesList = new List <MultiNodes> { TopNode } }, Text = Text, Positions = ParserResult.Positions, RawFunctionCalls = ParserResult.RawFunctionCalls }; var es = new TreeFormatEvaluateSetting { FunctionCallEvaluator = (f, nm) => { Action <Object, Object> Mark = (SemanticsObj, SyntaxObj) => { var Range = nm.GetRange(SyntaxObj); if (Range.OnSome) { Positions.Add(SemanticsObj, Range.Value); } }; Func <TFSemantics.Node, List <String> > ExtractNamespaceParts = Node => { var Namespace = GetLeafNodeValue(Node, nm, "InvalidName"); var NamespaceParts = new List <String>(); int InvalidCharIndex; var osml = TokenParser.TrySplitSymbolMemberChain(Namespace, out InvalidCharIndex); if (osml.OnNone) { var Range = nm.GetRange(Node); var InvalidChar = Namespace.Substring(InvalidCharIndex, 1); if (Range.OnSome) { Range = new TextRange { Start = nm.Text.Calc(Range.Value.Start, InvalidCharIndex), End = nm.Text.Calc(Range.Value.Start, InvalidCharIndex + 1) }; } throw new InvalidTokenException("InvalidChar", new FileTextRange { Text = nm.Text, Range = Range }, InvalidChar); } foreach (var p in osml.Value) { if (p.Parameters.Count > 0) { var Range = nm.GetRange(Node); var Part = Namespace.Substring(p.SymbolStartIndex, p.SymbolEndIndex); if (Range.OnSome) { Range = new TextRange { Start = nm.Text.Calc(Range.Value.Start, p.SymbolStartIndex), End = nm.Text.Calc(Range.Value.Start, p.SymbolEndIndex) }; } throw new InvalidTokenException("InvalidNamespacePart", new FileTextRange { Text = nm.Text, Range = Range }, Part); } int LocalInvalidCharIndex; var oName = TokenParser.TryUnescapeSymbolName(p.Name, out LocalInvalidCharIndex); if (oName.OnNone) { InvalidCharIndex = p.NameStartIndex + LocalInvalidCharIndex; var Range = nm.GetRange(Node); var InvalidChar = Namespace.Substring(InvalidCharIndex, 1); if (Range.OnSome) { Range = new TextRange { Start = nm.Text.Calc(Range.Value.Start, InvalidCharIndex), End = nm.Text.Calc(Range.Value.Start, InvalidCharIndex + 1) }; } throw new InvalidTokenException("InvalidChar", new FileTextRange { Text = nm.Text, Range = Range }, InvalidChar); } NamespaceParts.Add(p.Name); } return(NamespaceParts); }; if (TypeFunctions.Contains(f.Name.Text)) { if (f.Parameters.Count < 1 || f.Parameters.Count > 2) { throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f); } var TypeRef = ParseTypeRef(f.Parameters[0], nm, Positions); var Name = TypeRef.Name; var Version = TypeRef.Version; var Attributes = new List <KeyValuePair <String, List <String> > >(); var Description = ""; if (f.Parameters.Count >= 2) { var DescriptionParameter = f.Parameters[1]; if (!DescriptionParameter.OnLeaf) { throw new InvalidEvaluationException("InvalidDescription", nm.GetFileRange(DescriptionParameter), DescriptionParameter); } var c = TokenParser.DecomposeDescription(DescriptionParameter.Leaf); Attributes = c.Attributes; Mark(Attributes, f.Parameters[1]); Description = c.Description; } var ContentLines = new List <FunctionCallTableLine> { }; if (f.Content.OnSome) { var ContentValue = f.Content.Value; if (!ContentValue.OnTableContent) { throw new InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentValue), ContentValue); } ContentLines = ContentValue.TableContent; } switch (f.Name.Text) { case "Primitive": { if (Version != "") { throw new InvalidEvaluationException("InvalidName", nm.GetFileRange(f.Parameters[0]), f.Parameters[0]); } var GenericParameters = new List <VariableDef>(); foreach (var Line in ContentLines) { String cName = null; TypeSpec cType = null; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } if (cName.StartsWith("'")) { cName = new String(cName.Skip(1).ToArray()); var gp = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(gp, Line); GenericParameters.Add(gp); } else { throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line); } } var p = new PrimitiveDef { Name = Name, GenericParameters = GenericParameters, Attributes = Attributes, Description = Description }; Mark(p, f); var t = TypeDef.CreatePrimitive(p); Mark(t, f); Types.Add(t); TypeToNamespace.Add(t, CurrentNamespace); TypeToNamespaceImports.Add(t, CurrentNamespaceImports); return(new List <TFSemantics.Node> { }); } case "Alias": { var GenericParameters = new List <VariableDef>(); TypeSpec Type = null; foreach (var Line in ContentLines) { String cName = null; TypeSpec cType = null; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 1) { if (Type != null) { throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line); } Type = ParseTypeSpec(Line.Nodes[0], nm, Positions); continue; } else if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } if (cName.StartsWith("'")) { cName = new String(cName.Skip(1).ToArray()); var gp = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(gp, Line); GenericParameters.Add(gp); } else { throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line); } } if (Type == null) { throw new InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentLines), ContentLines); } var a = new AliasDef { Name = Name, Version = Version, GenericParameters = GenericParameters, Type = Type, Attributes = Attributes, Description = Description }; Mark(a, f); var t = TypeDef.CreateAlias(a); Mark(t, f); Types.Add(t); TypeToNamespace.Add(t, CurrentNamespace); TypeToNamespaceImports.Add(t, CurrentNamespaceImports); return(new List <TFSemantics.Node> { }); } case "Record": { var GenericParameters = new List <VariableDef>(); var Fields = new List <VariableDef>(); foreach (var Line in ContentLines) { String cName = null; TypeSpec cType = null; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } if (cName.StartsWith("'")) { cName = new String(cName.Skip(1).ToArray()); var gp = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(gp, Line); GenericParameters.Add(gp); } else { var p = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(p, Line); Fields.Add(p); } } var r = new RecordDef { Name = Name, Version = Version, GenericParameters = GenericParameters, Fields = Fields, Attributes = Attributes, Description = Description }; Mark(r, f); var t = TypeDef.CreateRecord(r); Mark(t, f); Types.Add(t); TypeToNamespace.Add(t, CurrentNamespace); TypeToNamespaceImports.Add(t, CurrentNamespaceImports); return(new List <TFSemantics.Node> { }); } case "TaggedUnion": { var GenericParameters = new List <VariableDef>(); var Alternatives = new List <VariableDef>(); foreach (var Line in ContentLines) { String cName = null; TypeSpec cType = null; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidAlternativeName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidAlternativeName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } if (cName.StartsWith("'")) { cName = new String(cName.Skip(1).ToArray()); var gp = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(gp, Line); GenericParameters.Add(gp); } else { var p = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(p, Line); Alternatives.Add(p); } } var tu = new TaggedUnionDef { Name = Name, Version = Version, GenericParameters = GenericParameters, Alternatives = Alternatives, Attributes = Attributes, Description = Description }; Mark(tu, f); var t = TypeDef.CreateTaggedUnion(tu); Mark(t, f); Types.Add(t); TypeToNamespace.Add(t, CurrentNamespace); TypeToNamespaceImports.Add(t, CurrentNamespaceImports); return(new List <TFSemantics.Node> { }); } case "Enum": { var Literals = new List <LiteralDef>(); Int64 NextValue = 0; foreach (var Line in ContentLines) { String cName = null; Int64 cValue = NextValue; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 1) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName"); cValue = NextValue; } else if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName"); cValue = NumericStrings.InvariantParseInt64(GetLeafNodeValue(Line.Nodes[1], nm, "InvalidLiteralValue")); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName"); cValue = NumericStrings.InvariantParseInt64(GetLeafNodeValue(Line.Nodes[1], nm, "InvalidLiteralValue")); var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } NextValue = cValue + 1; var ltl = new LiteralDef { Name = cName, Value = cValue, Attributes = cAttributes, Description = cDescription }; Mark(ltl, Line); Literals.Add(ltl); } var IntTypeName = new List <String> { "Int" }; Mark(IntTypeName, f); var r = new TypeRef { Name = IntTypeName, Version = "" }; Mark(r, f); var UnderlyingType = TypeSpec.CreateTypeRef(r); Mark(UnderlyingType, f); var ed = new EnumDef { Name = Name, Version = Version, UnderlyingType = UnderlyingType, Literals = Literals, Attributes = Attributes, Description = Description }; Mark(ed, f); var t = TypeDef.CreateEnum(ed); Mark(t, f); Types.Add(t); TypeToNamespace.Add(t, CurrentNamespace); TypeToNamespaceImports.Add(t, CurrentNamespaceImports); return(new List <TFSemantics.Node> { }); } case "ClientCommand": { var OutParameters = new List <VariableDef>(); var InParameters = new List <VariableDef>(); Boolean IsInParameter = false; foreach (var Line in ContentLines) { String cName = null; TypeSpec cType = null; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 1) { if (GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName") == ">") { IsInParameter = true; continue; } else { throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line); } } else if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } var p = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(p, Line); if (IsInParameter) { InParameters.Add(p); } else { OutParameters.Add(p); } } var cc = new ClientCommandDef { Name = Name, Version = Version, OutParameters = OutParameters, InParameters = InParameters, Attributes = Attributes, Description = Description }; Mark(cc, f); var t = TypeDef.CreateClientCommand(cc); Mark(t, f); Types.Add(t); TypeToNamespace.Add(t, CurrentNamespace); TypeToNamespaceImports.Add(t, CurrentNamespaceImports); return(new List <TFSemantics.Node> { }); } case "ServerCommand": { var OutParameters = new List <VariableDef>(); foreach (var Line in ContentLines) { String cName = null; TypeSpec cType = null; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } var p = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(p, Line); OutParameters.Add(p); } var sc = new ServerCommandDef { Name = Name, Version = Version, OutParameters = OutParameters, Attributes = Attributes, Description = Description }; Mark(sc, f); var t = TypeDef.CreateServerCommand(sc); Mark(t, f); Types.Add(t); TypeToNamespace.Add(t, CurrentNamespace); TypeToNamespaceImports.Add(t, CurrentNamespaceImports); return(new List <TFSemantics.Node> { }); } default: { throw new InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f); } } } else if (f.Name.Text == "Namespace") { if (f.Parameters.Count != 1) { throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f); } var NamespaceParts = ExtractNamespaceParts(f.Parameters[0]); Mark(NamespaceParts, f); CurrentNamespace = NamespaceParts; return(new List <TFSemantics.Node> { }); } else if (f.Name.Text == "Import") { if (f.Parameters.Count != 0) { throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f); } var ContentLines = new List <FunctionCallTableLine> { }; if (f.Content.OnSome) { var ContentValue = f.Content.Value; if (!ContentValue.OnTableContent) { throw new InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentValue), ContentValue); } ContentLines = ContentValue.TableContent; } var NamespaceImports = new List <List <String> >(); foreach (var Line in ContentLines) { if (Line.Nodes.Count == 1) { var NamespaceParts = ExtractNamespaceParts(Line.Nodes[0]); Mark(NamespaceParts, Line.Nodes[0]); NamespaceImports.Add(NamespaceParts); } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } } CurrentNamespaceImports = CurrentNamespaceImports.Concat(NamespaceImports).ToList(); return(new List <TFSemantics.Node> { }); } else { throw new InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f); } } }; var e = new TreeFormatEvaluator(es, pr); e.Evaluate(); } else { var pr = new TreeFormatParseResult { Value = new Forest { MultiNodesList = new List <MultiNodes> { TopNode } }, Text = Text, Positions = ParserResult.Positions, RawFunctionCalls = ParserResult.RawFunctionCalls }; var es = new TreeFormatEvaluateSetting { }; var e = new TreeFormatEvaluator(es, pr); var er = e.Evaluate(); if (er.Value.Nodes.Count > 0) { var ReadResult = ts.Read <Schema>(CollectionOperations.CreatePair(er.Value, er.Positions)); Types.AddRange(ReadResult.Key.Types); TypeRefs.AddRange(ReadResult.Key.TypeRefs); Imports.AddRange(ReadResult.Key.Imports); foreach (var p in ReadResult.Value) { if (p.Value.Range.OnSome) { Positions.Add(p.Key, p.Value.Range.Value); } } } } } return(new FileParserResult { Text = Text, Positions = Positions, Types = Types, TypeRefs = TypeRefs, Imports = Imports, TypeToNamespace = TypeToNamespace, TypeToNamespaceImports = TypeToNamespaceImports }); }
public static FileParserResult ParseFile(Text Text) { var TypeFunctions = new HashSet <String>() { "Primitive", "Entity", "Enum" }; var TableParameterFunctions = new HashSet <String>(TypeFunctions.Concat(new List <String> { "Query" })); var TableContentFunctions = TypeFunctions; var ps = new TreeFormatParseSetting() { IsTableParameterFunction = Name => TableParameterFunctions.Contains(Name), IsTableContentFunction = Name => TableContentFunctions.Contains(Name) }; var sp = new TreeFormatSyntaxParser(ps, Text); var ParserResult = sp.Parse(); var ts = new TreeSerializer(); var Types = new List <TypeDef>(); var TypeRefs = new List <TypeDef>(); var Imports = new List <String>(); var Positions = new Dictionary <Object, TextRange>(); foreach (var TopNode in ParserResult.Value.MultiNodesList) { if (TopNode.OnFunctionNodes) { var pr = new TreeFormatParseResult { Value = new Forest { MultiNodesList = new List <MultiNodes> { TopNode } }, Text = Text, Positions = ParserResult.Positions, RawFunctionCalls = ParserResult.RawFunctionCalls }; var es = new TreeFormatEvaluateSetting { FunctionCallEvaluator = (f, nm) => { Action <Object, Object> Mark = (SemanticsObj, SyntaxObj) => { var Range = nm.GetRange(SyntaxObj); if (Range.OnSome) { Positions.Add(SemanticsObj, Range.Value); } }; if (TypeFunctions.Contains(f.Name.Text)) { if (f.Parameters.Count < 1 || f.Parameters.Count > 2) { throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f); } var VersionedName = GetLeafNodeValue(f.Parameters[0], nm, "InvalidName"); var TypeRef = ParseTypeRef(VersionedName); Mark(TypeRef, f.Parameters[0]); var Name = (String)TypeRef; var Attributes = new List <KeyValuePair <String, List <String> > >(); var Description = ""; if (f.Parameters.Count >= 2) { var DescriptionParameter = f.Parameters[1]; if (!DescriptionParameter.OnLeaf) { throw new InvalidEvaluationException("InvalidDescription", nm.GetFileRange(DescriptionParameter), DescriptionParameter); } var c = OS.TokenParser.DecomposeDescription(DescriptionParameter.Leaf); Attributes = c.Attributes; Mark(Attributes, f.Parameters[1]); Description = c.Description; } var ContentLines = new List <FunctionCallTableLine> { }; if (f.Content.OnSome) { var ContentValue = f.Content.Value; if (!ContentValue.OnTableContent) { throw new InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentValue), ContentValue); } ContentLines = ContentValue.TableContent; } switch (f.Name.Text) { case "Primitive": { var GenericParameters = new List <VariableDef>(); foreach (var Line in ContentLines) { String cName = null; TypeSpec cType = null; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); var c = OS.TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } if (cName.StartsWith("'")) { cName = new String(cName.Skip(1).ToArray()); var gp = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription, Attribute = null }; Mark(gp, Line); GenericParameters.Add(gp); } else { throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line); } } var p = new PrimitiveDef { Name = Name, Attributes = Attributes, Description = Description }; Mark(p, f); var t = TypeDef.CreatePrimitive(p); Mark(t, f); Types.Add(t); return(new List <TFSemantics.Node> { }); } case "Entity": { var Fields = new List <VariableDef>(); foreach (var Line in ContentLines) { String cName = null; TypeSpec cType = null; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName"); cType = ParseTypeSpec(Line.Nodes[1], nm, Positions); var c = OS.TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } var p = new VariableDef { Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription }; Mark(p, Line); Fields.Add(p); } var ed = new EntityDef { Name = Name, Fields = Fields, Attributes = Attributes, Description = Description }; Mark(ed, f); var t = TypeDef.CreateEntity(ed); Mark(t, f); Types.Add(t); return(new List <TFSemantics.Node> { }); } case "Enum": { var Literals = new List <LiteralDef>(); Int64 NextValue = 0; foreach (var Line in ContentLines) { String cName = null; Int64 cValue = NextValue; var cAttributes = new List <KeyValuePair <String, List <String> > >(); var cDescription = ""; if (Line.Nodes.Count == 1) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName"); cValue = NextValue; } else if (Line.Nodes.Count == 2) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName"); cValue = NumericStrings.InvariantParseInt64(GetLeafNodeValue(Line.Nodes[1], nm, "InvalidLiteralValue")); } else if (Line.Nodes.Count == 3) { cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName"); cValue = NumericStrings.InvariantParseInt64(GetLeafNodeValue(Line.Nodes[1], nm, "InvalidLiteralValue")); var c = OS.TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription")); cAttributes = c.Attributes; Mark(cAttributes, Line.Nodes[2]); cDescription = c.Description; } else if (Line.Nodes.Count == 0) { continue; } else { throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line); } NextValue = cValue + 1; var ltl = new LiteralDef { Name = cName, Value = cValue, Attributes = cAttributes, Description = cDescription }; Mark(ltl, Line); Literals.Add(ltl); } var r = (TypeRef)("Int"); Mark(r, f); var UnderlyingType = TypeSpec.CreateTypeRef(r); Mark(UnderlyingType, f); var ed = new EnumDef { Name = Name, UnderlyingType = UnderlyingType, Literals = Literals, Attributes = Attributes, Description = Description }; Mark(ed, f); var t = TypeDef.CreateEnum(ed); Mark(t, f); Types.Add(t); return(new List <TFSemantics.Node> { }); } default: { throw new InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f); } } } else if (f.Name.Text == "Query") { if (f.Parameters.Count != 0) { throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f); } var Verbs = new Dictionary <String, Func <Verb> > { { "Select", () => Verb.CreateSelect() }, { "Lock", () => Verb.CreateLock() }, { "Insert", () => Verb.CreateInsert() }, { "Update", () => Verb.CreateUpdate() }, { "Upsert", () => Verb.CreateUpsert() }, { "Delete", () => Verb.CreateDelete() } }; var Numerals = new Dictionary <String, Func <Numeral> > { { "Optional", () => Numeral.CreateOptional() }, { "One", () => Numeral.CreateOne() }, { "Many", () => Numeral.CreateMany() }, { "All", () => Numeral.CreateAll() }, { "Range", () => Numeral.CreateRange() }, { "Count", () => Numeral.CreateCount() } }; Func <int, TextLine, List <QueryDef> > ParseQueryDef = (IndentLevel, Line) => { var l = new List <TFSemantics.Node>(); List <TFSemantics.Node> cl = null; TextPosition clStart = default(TextPosition); TextPosition clEnd = default(TextPosition); if (Line.Text.Length < IndentLevel * 4) { return(new List <QueryDef> { }); } var LineRange = new TextRange { Start = Text.Calc(Line.Range.Start, IndentLevel * 4), End = Line.Range.End }; var Range = LineRange; while (true) { var tpr = TreeFormatTokenParser.ReadToken(Text, pr.Positions, Range); if (!tpr.OnSome) { break; } var v = tpr.Value.Token; if (v.OnSingleLineComment) { break; } if (v.OnLeftParenthesis) { if (cl != null) { throw new InvalidTokenException("DoubleLeftParenthesis", new FileTextRange { Text = Text, Range = Range }, "("); } cl = new List <TFSemantics.Node>(); clStart = Range.Start; clEnd = Range.End; } else if (v.OnRightParenthesis) { if (cl == null) { throw new InvalidTokenException("DismatchedRightParenthesis", new FileTextRange { Text = Text, Range = Range }, ")"); } if (cl.Count == 0) { throw new InvalidTokenException("EmptyIndex", new FileTextRange { Text = Text, Range = Range }, ")"); } if (tpr.Value.RemainingChars.OnSome) { clEnd = tpr.Value.RemainingChars.Value.End; } l.Add(nm.MakeStemNode("", cl, new TextRange { Start = clStart, End = clEnd })); cl = null; clStart = default(TextPosition); clEnd = default(TextPosition); } else if (v.OnSingleLineLiteral) { if (cl != null) { cl.Add(nm.MakeLeafNode(v.SingleLineLiteral, pr.Positions[v])); } else { l.Add(nm.MakeLeafNode(v.SingleLineLiteral, pr.Positions[v])); } } else { throw new InvalidTokenException("UnknownToken", new FileTextRange { Text = Text, Range = Range }, Text.GetTextInLine(Range)); } if (!tpr.Value.RemainingChars.OnSome) { break; } Range = tpr.Value.RemainingChars.Value; } if (cl != null) { throw new InvalidTokenException("DismatchedRightParentheses", new FileTextRange { Text = Text, Range = Range }, ""); } if (l.Count == 0) { return(new List <QueryDef> { }); } if (l.Count != 4 && l.Count != 6 && l.Count != 8) { throw new InvalidSyntaxException("InvalidQuery", new FileTextRange { Text = Text, Range = LineRange }); } var From = GetLeafNodeValue(l[0], nm, "InvalidFrom"); if (From != "From") { throw new InvalidTokenException("InvalidFrom", nm.GetFileRange(l[0]), From); } var EntityName = GetLeafNodeValue(l[1], nm, "InvalidEntityName"); var VerbName = GetLeafNodeValue(l[2], nm, "InvalidVerb"); if (!Verbs.ContainsKey(VerbName)) { throw new InvalidTokenException("InvalidVerb", nm.GetFileRange(l[2]), VerbName); } var Verb = Verbs[VerbName](); Mark(Verb, l[2]); var NumeralName = GetLeafNodeValue(l[3], nm, "InvalidNumeral"); if (!Numerals.ContainsKey(NumeralName)) { throw new InvalidTokenException("InvalidNumeral", nm.GetFileRange(l[3]), NumeralName); } var Numeral = Numerals[NumeralName](); Mark(Numeral, l[3]); var By = new List <String> { }; var OrderBy = new List <KeyColumn> { }; if (l.Count >= 6) { var ByOrOrderByName = GetLeafNodeValue(l[4], nm, "InvalidByOrOrderBy"); if (ByOrOrderByName == "By") { if (l[5].OnLeaf) { By = new List <String> { l[5].Leaf }; } else if (l[5].OnStem) { By = l[5].Stem.Children.Select(c => GetLeafNodeValue(c, nm, "InvalidKeyColumn")).ToList(); } else { throw new InvalidSyntaxException("InvalidBy", nm.GetFileRange(l[5])); } Mark(By, l[5]); } else if (ByOrOrderByName == "OrderBy") { if (l[5].OnLeaf) { OrderBy = (new List <String> { l[5].Leaf }).Select(c => c.EndsWith("-") ? new KeyColumn { Name = c.Substring(0, c.Length - 1), IsDescending = true } : new KeyColumn { Name = c, IsDescending = false }).ToList(); } else if (l[5].OnStem) { OrderBy = l[5].Stem.Children.Select(c => GetLeafNodeValue(c, nm, "InvalidKeyColumn")).Select(c => c.EndsWith("-") ? new KeyColumn { Name = c.Substring(0, c.Length - 1), IsDescending = true } : new KeyColumn { Name = c, IsDescending = false }).ToList(); } else { throw new InvalidSyntaxException("InvalidOrderBy", nm.GetFileRange(l[5])); } Mark(OrderBy, l[5]); } else { throw new InvalidSyntaxException("InvalidByOrOrderBy", nm.GetFileRange(l[5])); } } if (l.Count >= 8) { if (OrderBy.Count != 0) { throw new InvalidSyntaxException("InvalidOrderBy", nm.GetFileRange(l[6])); } var OrderByName = GetLeafNodeValue(l[6], nm, "InvalidOrderBy"); if (OrderByName == "OrderBy") { if (l[7].OnLeaf) { OrderBy = (new List <String> { l[7].Leaf }).Select(c => c.EndsWith("-") ? new KeyColumn { Name = c.Substring(0, c.Length - 1), IsDescending = true } : new KeyColumn { Name = c, IsDescending = false }).ToList(); } else if (l[7].OnStem) { OrderBy = l[7].Stem.Children.Select(c => GetLeafNodeValue(c, nm, "InvalidKeyColumn")).Select(c => c.EndsWith("-") ? new KeyColumn { Name = c.Substring(0, c.Length - 1), IsDescending = true } : new KeyColumn { Name = c, IsDescending = false }).ToList(); } else { throw new InvalidSyntaxException("InvalidOrderBy", nm.GetFileRange(l[7])); } Mark(OrderBy, l[7]); } else { throw new InvalidSyntaxException("InvalidOrderBy", nm.GetFileRange(l[7])); } } var q = new QueryDef { EntityName = EntityName, Verb = Verb, Numeral = Numeral, By = By, OrderBy = OrderBy }; Mark(q, Line); return(new List <QueryDef> { q }); }; var Queries = f.Content.Value.LineContent.Lines.SelectMany(Line => ParseQueryDef(f.Content.Value.LineContent.IndentLevel, Line)).ToList(); Mark(Queries, f); var ql = new QueryListDef { Queries = Queries }; Mark(ql, f); var t = TypeDef.CreateQueryList(ql); Mark(t, f); Types.Add(t); return(new List <TFSemantics.Node> { }); } else { throw new InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f); } } }; var e = new TreeFormatEvaluator(es, pr); e.Evaluate(); } else { var pr = new TreeFormatParseResult { Value = new Forest { MultiNodesList = new List <MultiNodes> { TopNode } }, Text = Text, Positions = ParserResult.Positions, RawFunctionCalls = ParserResult.RawFunctionCalls }; var es = new TreeFormatEvaluateSetting { }; var e = new TreeFormatEvaluator(es, pr); var er = e.Evaluate(); if (er.Value.Nodes.Count > 0) { var ReadResult = ts.Read <Schema>(CollectionOperations.CreatePair(er.Value, er.Positions)); Types.AddRange(ReadResult.Key.Types); TypeRefs.AddRange(ReadResult.Key.TypeRefs); Imports.AddRange(ReadResult.Key.Imports); foreach (var p in ReadResult.Value) { if (p.Value.Range.OnSome) { Positions.Add(p.Key, p.Value.Range.Value); } } } } } var Schema = new Schema { Types = Types, TypeRefs = TypeRefs, Imports = Imports }; return(new FileParserResult { Schema = Schema, Text = Text, Positions = Positions }); }
private void Load(String TreePath, StreamReader Reader) { var ps = new TreeFormatParseSetting { IsTableParameterFunction = Name => Name == "Module" }; var es = new TreeFormatEvaluateSetting { FunctionCallEvaluator = (f, nm) => { if (f.Parameters.Count < 1 || f.Parameters.Count > 2) { throw new Syntax.InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f); } var Name = GetLeafNodeValue(f.Parameters[0], nm, "InvalidName"); String Description = ""; if (f.Parameters.Count >= 2) { var DescriptionParameter = f.Parameters[1]; if (!DescriptionParameter.OnLeaf) { throw new Syntax.InvalidEvaluationException("InvalidDescription", nm.GetFileRange(DescriptionParameter), DescriptionParameter); } Description = DescriptionParameter.Leaf; } var ContentLines = new List <Syntax.TextLine> { }; if (f.Content.OnSome) { var ContentValue = f.Content.Value; if (!ContentValue.OnLineContent) { throw new Syntax.InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentValue), ContentValue); } ContentLines = ContentValue.LineContent.Lines; } if (f.Name.Text == "Module") { if (!ModuleDecls.ContainsKey(Name)) { throw new Syntax.InvalidEvaluationException("ModuleNotExist", nm.GetFileRange(f), f); } var Module = ModuleDecls[Name]; var FunctionDeclDict = ModuleDeclDicts[Name]; var ReachedFunctions = new HashSet <String>(); var Functions = new Dictionary <String, FunctionDef>(); foreach (var Line in ContentLines) { var Trimmed = Line.Text.Trim(); if (Trimmed == "") { continue; } if (Trimmed.StartsWith("//")) { continue; } var m = rFunctionBodyLine.Match(Line.Text); if (!m.Success) { throw new Syntax.InvalidEvaluationException("FunctionBodyLineInvalid", new Syntax.FileTextRange { Text = nm.Text, Range = Line.Range }, Line); } var FunctionName = m.Result("${Name}"); var gBody = m.Groups["Body"]; if (!FunctionDeclDict.ContainsKey(FunctionName)) { throw new Syntax.InvalidEvaluationException("FunctionNotExist", new Syntax.FileTextRange { Text = nm.Text, Range = Line.Range }, Line); } if (ReachedFunctions.Contains(FunctionName)) { throw new Syntax.InvalidEvaluationException("DuplicateFunction", new Syntax.FileTextRange { Text = nm.Text, Range = Line.Range }, Line); } var fd = FunctionDeclDict[FunctionName]; ReachedFunctions.Add(FunctionName); var ep = new ExpressionParser(null, nm.Text); var BodyRange = new Syntax.TextRange { Start = nm.Text.Calc(Line.Range.Start, gBody.Index), End = nm.Text.Calc(Line.Range.Start, gBody.Index + gBody.Length) }; var func = ep.ParseFunction(new Niveum.Expression.ExpressionRuntimeProvider <int>(), fd, BodyRange); Functions.Add(FunctionName, func.Definition); } var NoDefinitionList = FunctionDeclDict.Keys.Except(ReachedFunctions).ToList(); if (NoDefinitionList.Count > 0) { throw new Syntax.InvalidEvaluationException("DefinitionNotFoundForFunction: {0}".Formats(String.Join(" ", NoDefinitionList.ToArray())), nm.GetFileRange(f), f); } var ModuleDef = new ModuleDef { Name = Name, Description = Description, Functions = Module.Functions.Select(fd => Functions[fd.Name]).ToList() }; Modules.Add(ModuleDef); } else { throw new Syntax.InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f); } return(new List <Node> { }); } }; var pr = TreeFile.ReadRaw(Reader, TreePath, ps); var tfe = new TreeFormatEvaluator(es, pr); tfe.Evaluate(); }
private void Load(String TreePath, StreamReader Reader, List <Semantics.Node> EntityMappings) { var Functions = new HashSet <String>() { "Map" }; var TableParameterFunctions = Functions; var TableContentFunctions = new HashSet <String>(Functions.Except(new List <String> { "Map" })); TreeFormatParseSetting ps; if (tfpo == null) { ps = new TreeFormatParseSetting() { IsTableParameterFunction = Name => TableParameterFunctions.Contains(Name), IsTableContentFunction = Name => TableContentFunctions.Contains(Name) }; } else { ps = new TreeFormatParseSetting() { IsTableParameterFunction = Name => { if (TableParameterFunctions.Contains(Name)) { return(true); } return(tfpo.IsTableParameterFunction(Name)); }, IsTableContentFunction = Name => { if (TableContentFunctions.Contains(Name)) { return(true); } return(tfpo.IsTableContentFunction(Name)); }, IsTreeParameterFunction = tfpo.IsTreeParameterFunction, IsTreeContentFunction = tfpo.IsTreeContentFunction }; } var pr = TreeFile.ReadRaw(Reader, TreePath, ps); var Text = pr.Text; Func <int, Syntax.TextLine, ISemanticsNodeMaker, List <Semantics.Node> > ParseEntityMappingsAsSemanticsNodes = (IndentLevel, Line, nm) => { var l = new List <Semantics.Node>(); List <Semantics.Node> cl = null; Syntax.TextPosition clStart = default(Syntax.TextPosition); Syntax.TextPosition clEnd = default(Syntax.TextPosition); if (Line.Text.Length < IndentLevel * 4) { return(new List <Semantics.Node> { }); } var LineRange = new Syntax.TextRange { Start = Text.Calc(Line.Range.Start, IndentLevel * 4), End = Line.Range.End }; var Range = LineRange; while (true) { var tpr = TreeFormatTokenParser.ReadToken(Text, pr.Positions, Range); if (!tpr.OnSome) { break; } var v = tpr.Value.Token; if (v.OnSingleLineComment) { break; } if (v.OnLeftParenthesis) { if (cl != null) { throw new Syntax.InvalidTokenException("DoubleLeftParenthesis", new Syntax.FileTextRange { Text = Text, Range = Range }, "("); } cl = new List <Semantics.Node>(); clStart = Range.Start; clEnd = Range.End; } else if (v.OnRightParenthesis) { if (cl == null) { throw new Syntax.InvalidTokenException("DismatchedRightParenthesis", new Syntax.FileTextRange { Text = Text, Range = Range }, ")"); } if (cl.Count == 0) { throw new Syntax.InvalidTokenException("EmptyIndex", new Syntax.FileTextRange { Text = Text, Range = Range }, ")"); } if (tpr.Value.RemainingChars.OnSome) { clEnd = tpr.Value.RemainingChars.Value.End; } l.Add(nm.MakeStemNode("", cl, new Syntax.TextRange { Start = clStart, End = clEnd })); cl = null; clStart = default(Syntax.TextPosition); clEnd = default(Syntax.TextPosition); } else if (v.OnSingleLineLiteral) { if (cl != null) { cl.Add(nm.MakeLeafNode(v.SingleLineLiteral, pr.Positions[v])); } else { l.Add(nm.MakeLeafNode(v.SingleLineLiteral, pr.Positions[v])); } } else if (v.OnPreprocessDirective && (v.PreprocessDirective == "Empty")) { if (cl != null) { cl.Add(nm.MakeEmptyNode(pr.Positions[v])); } else { l.Add(nm.MakeEmptyNode(pr.Positions[v])); } } else { throw new Syntax.InvalidTokenException("UnknownToken", new Syntax.FileTextRange { Text = Text, Range = Range }, Text.GetTextInLine(Range)); } if (!tpr.Value.RemainingChars.OnSome) { break; } Range = tpr.Value.RemainingChars.Value; } if (cl != null) { throw new Syntax.InvalidTokenException("DismatchedRightParentheses", new Syntax.FileTextRange { Text = Text, Range = Range }, ""); } if (l.Count == 0) { return(new List <Semantics.Node> { }); } if (l.Count < 3) { throw new Syntax.InvalidSyntaxException("InvalidEntityMapping", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } var EntityToken = GetLeafNodeValue(l[0], nm, "InvalidEntityToken"); if (EntityToken != "Entity") { throw new Syntax.InvalidSyntaxException("InvalidEntityToken", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } var EntityName = GetLeafNodeValue(l[1], nm, "InvalidEntityName"); var EntityMethodToken = GetLeafNodeValue(l[2], nm, "InvalidEntityMethodToken"); if (EntityMethodToken == "New") { if (l.Count != 3) { throw new Syntax.InvalidSyntaxException("InvalidEntityMapping", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } return(new List <Semantics.Node> { MakeStemNode("EntityMapping", MakeStemNode("EntityName", MakeLeafNode(EntityName)), MakeStemNode("Method", MakeStemNode("New", MakeEmptyNode())) ) }); } else if (EntityMethodToken == "From") { if (l.Count != 4) { throw new Syntax.InvalidSyntaxException("InvalidEntityMapping", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } var EntityNameSource = GetLeafNodeValue(l[3], nm, "InvalidEntityName"); return(new List <Semantics.Node> { MakeStemNode("EntityMapping", MakeStemNode("EntityName", MakeLeafNode(EntityName)), MakeStemNode("Method", MakeStemNode("Copy", MakeLeafNode(EntityNameSource))) ) }); } else if (EntityMethodToken == "Field") { if (l.Count < 6) { throw new Syntax.InvalidSyntaxException("InvalidEntityMapping", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } var FieldName = GetLeafNodeValue(l[3], nm, "InvalidFieldName"); var FieldMethodToken = GetLeafNodeValue(l[4], nm, "InvalidFieldMethodToken"); if (FieldMethodToken == "New") { if (l.Count != 6) { throw new Syntax.InvalidSyntaxException("InvalidEntityMapping", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } if (!EntityFields.ContainsKey(EntityName)) { throw new Syntax.InvalidSyntaxException("EntityNotExist", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } var e = EntityFields[EntityName]; if (!e.ContainsKey(FieldName)) { throw new Syntax.InvalidSyntaxException("FieldNotExist", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } var Literal = l[5]; Semantics.Node Value; var f = e[FieldName]; if (f.Type.OnTypeRef) { if (Literal.OnEmpty) { throw new Syntax.InvalidSyntaxException("FieldTypeIncompatible", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } else { Value = MakeStemNode("Some", MakeStemNode(f.Type.TypeRef.Value + "Value", Literal)); } } else if (f.Type.OnOptional) { if (Literal.OnEmpty) { Value = MakeStemNode("None", MakeEmptyNode()); } else { Value = MakeStemNode("Some", MakeStemNode(f.Type.Optional.Value + "Value", Literal)); } } else if (f.Type.OnList) { if (f.Type.List.Value == "Byte") { if (Literal.OnEmpty) { throw new Syntax.InvalidSyntaxException("FieldTypeIncompatible", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } else { Value = MakeStemNode("Some", MakeStemNode("BinaryValue", Literal)); } } else { throw new InvalidOperationException(); } } else { throw new Syntax.InvalidSyntaxException("FieldTypeIncompatible", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } return(new List <Semantics.Node> { MakeStemNode("EntityMapping", MakeStemNode("EntityName", MakeLeafNode(EntityName)), MakeStemNode("Method", MakeStemNode("Field", MakeStemNode("FieldName", MakeLeafNode(FieldName)), MakeStemNode("Method", MakeStemNode("New", Value)) )) ) }); } else if (FieldMethodToken == "From") { if (l.Count != 6) { throw new Syntax.InvalidSyntaxException("InvalidEntityMapping", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } var FieldNameSource = GetLeafNodeValue(l[5], nm, "InvalidFieldName"); return(new List <Semantics.Node> { MakeStemNode("EntityMapping", MakeStemNode("EntityName", MakeLeafNode(EntityName)), MakeStemNode("Method", MakeStemNode("Field", MakeStemNode("FieldName", MakeLeafNode(FieldName)), MakeStemNode("Method", MakeStemNode("Copy", MakeLeafNode(FieldNameSource))) )) ) }); } else { throw new Syntax.InvalidSyntaxException("InvalidEntityMapping", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } } else { throw new Syntax.InvalidSyntaxException("InvalidEntityMapping", new Syntax.FileTextRange { Text = Text, Range = LineRange }); } }; var es = new TreeFormatEvaluateSetting() { FunctionCallEvaluator = (f, nm) => { if (f.Parameters.Count == 0) { if (f.Name.Text == "Map") { var Nodes = f.Content.Value.LineContent.Lines.SelectMany(Line => ParseEntityMappingsAsSemanticsNodes(f.Content.Value.LineContent.IndentLevel, Line, nm)).ToArray(); return(new List <Semantics.Node> { MakeStemNode("ListOfEntityMapping", Nodes) }); } else { if (tfeo != null) { return(tfeo.FunctionCallEvaluator(f, nm)); } throw new Syntax.InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f); } } else { throw new Syntax.InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f); } }, TokenParameterEvaluator = tfeo != null ? tfeo.TokenParameterEvaluator : null }; var tfe = new TreeFormatEvaluator(es, pr); var t = tfe.Evaluate(); foreach (var n in t.Value.Nodes) { EntityMappings.AddRange(n.Stem.Children); } foreach (var p in t.Positions) { Positions.Add(p.Key, p.Value); } }