Portál AbcLinuxu, 1. května 2025 08:45

Kompilátor jazyka BC pro Parrot VM

27.11.2007 17:09 | Přečteno: 1077× | Perl 6 a Parrot | Výběrový blog | poslední úprava: 27.11.2007 17:22

BC je taková složitější kalkulačka. Od včerejška je napsání kompilátoru jazyka bc pro virtuální stroj Parrot maličkost. Stačí napsat: Stáhneme aktuální revizi Parrotu a přidáme abc do adresáře s jazyky, doladíme Makefiles a spustíme kompilaci.

Vytvoříme test jazyka:

abc> cat in.abc

(1 + 3) * 2

Překontrolujeme syntaktický strom:

abc>../../parrot abc.pbc --target=parse in.abc 

"parse" => PMC 'ABC::Grammar' => "(1 + 3) * 2" @ 0 {
    <statement_list> => PMC 'ABC::Grammar' => "(1 + 3) * 2" @ 0 {
        <statement> => ResizablePMCArray (size:1) [
            PMC 'ABC::Grammar' => "(1 + 3) * 2" @ 0 {
                <expression> => PMC 'ABC::Grammar' => "(1 + 3) * 2" @ 0 {
                    <expr> => PMC 'PGE::Match' => "*" @ 8 {
                        <type> => "infix:*"
                        <top> => Hash {
                            "arity" => 2,
                            "assoc" => "left",
                            "expect" => 258,
                            "looser" => "infix:^",
                            "match" => "PGE::Match",
                            "name" => "infix:*",
                            "pirop" => "n_mul",
                            "precclose" => "<<<<=",
                            "precedence" => \parse[0]["precclose"],
                            "syncat" => 96
                        }
                        [0] => PMC 'PGE::Match' => "(" @ 0 {
                            <type> => "circumfix:( )"
                            <top> => Hash {
                                "arity" => 1,
                                "assoc" => "left",
                                "equiv" => "term:",
                                "expect" => 257,
                                "keyclose" => ")",
                                "match" => "PGE::Match",
                                "name" => "circumfix:( )",
                                "pirop" => "set",
                                "precclose" => "=",
                                "precedence" => \parse[0]["precclose"],
                                "syncat" => 144
                            }
                            [0] => PMC 'PGE::Match' => "+" @ 3 {
                                <type> => "infix:+"
                                <top> => Hash {
                                    "arity" => 2,
                                    "assoc" => "left",
                                    "expect" => 258,
                                    "looser" => "infix:*",
                                    "match" => "PGE::Match",
                                    "name" => "infix:+",
                                    "pirop" => "n_add",
                                    "precclose" => "<<<<<=",
                                    "precedence" => \parse[0]["precclose"],
                                    "syncat" => 96
                                }
                                [0] => PMC 'ABC::Grammar' => "1" @ 1 {
                                    <integer> => PMC 'ABC::Grammar' => "1" @ 1
                                    <type> => "term:"
                                    <top> => Hash {
                                        "assoc" => "left",
                                        "expect" => 513,
                                        "match" => "PGE::Match",
                                        "name" => "term:",
                                        "parsed" => PMC 'Sub' { ... },
                                        "precclose" => "=",
                                        "precedence" => \parse[0]["precclose"],
                                        "syncat" => 16
                                    }
                                }
                                [1] => PMC 'ABC::Grammar' => "3" @ 5 {
                                    <integer> => PMC 'ABC::Grammar' => "3" @ 5
                                    <type> => "term:"
                                    <top> => \parse[0]
                                }
                            }
                        }
                        [1] => PMC 'ABC::Grammar' => "2" @ 10 {
                            <integer> => PMC 'ABC::Grammar' => "2" @ 10
                            <type> => "term:"
                            <top> => \parse[0]
                        }
                    }
                }
            }
        ]
    }
}

Překontrolujeme AST:

abc>../../parrot abc.pbc --target=past in.abc 

"past" => PMC 'PAST::Stmts'  {
    <source> => "(1 + 3) * 2"
    <pos> => 0
    [0] => PMC 'PAST::Op'  {
        <name> => "saynum"
        <pasttype> => "call"
        [0] => PMC 'PAST::Op'  {
            <pasttype> => "bind"
            [0] => PMC 'PAST::Var'  {
                <name> => "last"
                <scope> => "package"
                <lvalue> => 1
            }
            [1] => PMC 'PAST::Op'  {
                <name> => "infix:*"
                <pasttype> => undef
                <pirop> => "n_mul"
                <lvalue> => undef
                <source> => "*"
                <pos> => 8
                [0] => PMC 'PAST::Op'  {
                    <name> => "circumfix:( )"
                    <pasttype> => undef
                    <pirop> => "set"
                    <lvalue> => undef
                    <source> => "("
                    <pos> => 0
                    [0] => PMC 'PAST::Op'  {
                        <name> => "infix:+"
                        <pasttype> => undef
                        <pirop> => "n_add"
                        <lvalue> => undef
                        <source> => "+"
                        <pos> => 3
                        [0] => PMC 'PAST::Val'  {
                            <value> => "1"
                            <returns> => "Integer"
                            <source> => "1"
                            <pos> => 1
                        }
                        [1] => PMC 'PAST::Val'  {
                            <value> => "3"
                            <returns> => "Integer"
                            <source> => "3"
                            <pos> => 5
                        }
                    }
                }
                [1] => PMC 'PAST::Val'  {
                    <value> => "2"
                    <returns> => "Integer"
                    <source> => "2"
                    <pos> => 10
                }
            }
        }
    }
}

Případně překontrolujeme i POST:

abc>../../parrot abc.pbc --target=post in.abc 

"post" => PMC 'POST::Ops'  {
    <source> => "(1 + 3) * 2"
    <pos> => 0
    <result> => PMC 'POST::Ops'  {
        <source> => null
        <pos> => \post
        <result> => "$P14"
        [0] => PMC 'POST::Ops'  {
            <source> => \post
            <pos> => \post
            <result> => PMC 'POST::Op'  {
                <pirop> => "set_global"
                <result> => PMC 'POST::Ops'  {
                    <source> => "*"
                    <pos> => 8
                    <result> => "$P13"
                    [0] => PMC 'POST::Ops'  {
                        <source> => "("
                        <pos> => 0
                        <result> => "$P12"
                        [0] => PMC 'POST::Ops'  {
                            <source> => "+"
                            <pos> => 3
                            <result> => "$P11"
                            [0] => PMC 'POST::Ops'  {
                                <source> => "1"
                                <pos> => 1
                                <result> => "$P10"
                                [0] => PMC 'POST::Op'  {
                                    <pirop> => "new"
                                    [0] => "$P10"
                                    [1] => "\"Integer\""
                                }
                                [1] => PMC 'POST::Op'  {
                                    <pirop> => "assign"
                                    [0] => "$P10"
                                    [1] => "1"
                                }
                            }
                            [1] => PMC 'POST::Ops'  {
                                <source> => "3"
                                <pos> => 5
                                <result> => "3"
                            }
                            [2] => PMC 'POST::Op'  {
                                <pirop> => "n_add"
                                [0] => "$P11"
                                [1] => \post
                                [2] => \post
                            }
                        }
                        [1] => PMC 'POST::Op'  {
                            <pirop> => "set"
                            [0] => "$P12"
                            [1] => \post
                        }
                    }
                    [1] => PMC 'POST::Ops'  {
                        <source> => "2"
                        <pos> => 10
                        <result> => "2"
                    }
                    [2] => PMC 'POST::Op'  {
                        <pirop> => "n_mul"
                        [0] => "$P13"
                        [1] => \post
                        [2] => \post
                    }
                }
                [0] => "\"last\""
                [1] => \post
            }
            [0] => \post
            [1] => \post
        }
        [1] => PMC 'POST::Op'  {
            <result> => "$P14"
            <pirop> => "call"
            [0] => "\"saynum\""
            [1] => "$P13"
        }
    }
    [0] => \post
}

Koukneme na "výsledný" PIR pro Parrot VM:

abc>../../parrot abc.pbc --target=pir in.abc 

.sub "anon"
    new $P10, "Integer"
    assign $P10, 1
    n_add $P11, $P10, 3
    set $P12, $P11
    n_mul $P13, $P12, 2
    set_global "last", $P13
    $P14 = "saynum"($P13)
.end

A spustíme test:

abc>../../parrot abc.pbc in.abc
8

A to je vše, přátelé. Funguje to. Tádí dádí da.

Nyní se můžeme vrhnout na kompilátor dalšího jazyka, dodělat něco z TODO pro abc nebo jen sledovat další pokrok Patricka R. Michauda a dalších na cestě k Perlu 6.

       

Hodnocení: 82 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Nástroje: Začni sledovat (2) ?Zašle upozornění na váš email při vložení nového komentáře. , Tisk

Vložit další komentář

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.