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;
 }
Exemple #2
0
        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();
        }
Exemple #3
0
        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
            });
        }
Exemple #4
0
        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
            });
        }
Exemple #5
0
        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);
            }
        }