Ejemplo n.º 1
0
        private static Section GetIntroSection()
        {
            //Add the first section (the introduction one)
            var introSec = new Section("DocumentMaker example");
            //Load and modify the first paragraph
            string par1 = "Welcome to this example of a document rendered using DocumentMaker C# library";

            par1 = TextFormat.ReplaceItalic(par1, "DocumentMaker");
            introSec.AddParagraph(par1);
            introSec.AddHr();
            //The second paragraph is loaded from a txt file because it is always the same
            //and it is quite long
            introSec.AddParagraph(new FileInfo(INTRO_SECONDPARAGRAPH_FILE));

            //Now let's create the subsection "About the author", of heading level 2
            var aboutSec = new Section("About the author", 2);

            introSec.AddSection(aboutSec);  //appending this subsection to the first one
            //Adding the paragraph, changing a substring in italic
            aboutSec.AddParagraph(TextFormat.ReplaceItalic(File.ReadAllText(INTRO_ABOUT_FILE),
                                                           "DocumentMaker"));
            //The dot list with contact info will be manually assembled
            var contactInfos = new DotList();

            contactInfos.AddItem("Github profile: " + new DocLink("https://github.com/PaoloCattaneo92", "Github").Render()); //custom text
            contactInfos.AddItem("Mail: " + new MailToLink("*****@*****.**").Render());                          //this is used to correctly renders mailto addresses
            contactInfos.AddItem("Linkedin profile: " + new DocLink("https://www.linkedin.com/in/paolo-cattaneo-eng/", "Linkedin").Render());
            //Appending the dot list to the about section
            aboutSec.Add(contactInfos);
            return(introSec);
        }
Ejemplo n.º 2
0
        private DotExpression ReadAhead(string token)
        {
            switch (token)
            {
            case "(":
                CurColumn += 1;
                var l = new DotList()
                {
                    Line        = CurLine,
                    Column      = CurColumn,
                    Expressions = new LinkedList <DotExpression>()
                };
                while (true)
                {
                    token = NextToken();
                    if (token == ")")
                    {
                        CurColumn += 1;
                        return(l);
                    }

                    l.Expressions.AddLast(ReadAhead(token));
                }

            case ")":
                CurColumn += 1;
                ParserErrors.Add(new ParserError()
                {
                    Line    = CurLine,
                    Column  = CurColumn,
                    Message = "Unexpected ')'!"
                });
                token = NextToken();
                return(ReadAhead(token));
            }

            if (_quotes.ContainsKey(token))
            {
                // convert to real expression
                var keyword = _quotes[token];
                var exps    = new LinkedList <DotExpression>();

                exps.AddLast(new DotSymbol(keyword, CurLine, CurColumn));
                exps.AddLast(Read().AST);

                return(new DotList
                {
                    Line = CurLine,
                    Column = CurColumn,
                    Expressions = exps
                });
            }

            var ret = ParseAtom(token, CurLine, CurColumn);

            CurColumn += token.Length;
            return(ret);
        }
Ejemplo n.º 3
0
        private List <T> ExtractTypes <T>(DotList l) where T : DotExpression
        {
            var ret = new List <T>();

            foreach (var exp in l.Expressions)
            {
                if (exp is T s)
                {
                    ret.Add(s);
                }

                if (exp is DotList innerList)
                {
                    ret.AddRange(ExtractTypes <T>(innerList));
                }
            }

            return(ret);
        }
Ejemplo n.º 4
0
        public static DotExpression Expand(DotExpression expression,
                                           bool topLevel = false)
        {
            if (!(expression is DotList l))
            {
                // constants can't be expanded
                return(expression);
            }

            if (l.Expressions.Count == 0)
            {
                throw new ParserException(
                          "An empty list needs to be quoted!", l.Line, l.Column);
            }

            var args = l.Expressions.Skip(1).ToList();

            // if (!(l.Expressions.First() is DotSymbol op))
            // {
            //     throw new EvaluatorException(
            //         "Function or special form expected!");
            // }

            if (l.Expressions.First() is DotSymbol op)
            {
                if (op.Name == "quote")
                {
                    return(expression);
                }

                // TODO Find a generic way to check function and procedure argument length and type

                if (op.Name == "def" || op.Name == "defmacro")
                {
                    if (args.Count != 2)
                    {
                        throw new ParserException("name and body expected!", op.Line,
                                                  op.Column);
                    }

                    var defBody = Expand(args.ElementAt(1));

                    if (op.Name == "defmacro")
                    {
                        if (!topLevel)
                        {
                            throw new ParserException(
                                      "'defmacro' only allowed at top level!", op.Line,
                                      op.Column);
                        }

                        var procedure = Evaluator.Eval(defBody);

                        if (!(procedure is DotProcedure dp))
                        {
                            throw new ParserException(
                                      "A macro must be a procedure", op.Line, op.Column);
                        }

                        // Add macro
                        GlobalEnvironment.MacroTable.Add(
                            (args.ElementAt(0) as DotSymbol).Name,
                            dp
                            );

                        return(DotBool.True());
                    }

                    var expandedDefinition = new LinkedList <DotExpression>();

                    expandedDefinition.AddLast(op);
                    expandedDefinition.AddLast(args.First());
                    expandedDefinition.AddLast(defBody);

                    return(new DotList()
                    {
                        Expressions = expandedDefinition
                    });
                }

                if (op.Name == "quasiquote")
                {
                    return(ExpandQuasiquote(args.First()));
                }

                if (GlobalEnvironment.MacroTable.ContainsKey(op.Name))
                {
                    // call macro
                    var macro     = GlobalEnvironment.MacroTable[op.Name];
                    var macroArgs = new DotList()
                    {
                        Expressions = args.ToLinkedList()
                    };

                    return(Expand(macro.Call(macroArgs), topLevel));
                }
            }

            l.Expressions = l.Expressions
                            .Select(exp => Expand(exp, false))
                            .ToLinkedList();
            return(l);
        }