Пример #1
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);
            }
        }