Changeset 4655 for src/Emit/PIR.hs

Show
Ignore:
Timestamp:
06/14/05 23:42:15 (4 years ago)
Author:
autrijus
svk:copy_cache_prev:
6394
Message:

* PAST compileation and PIR emission, phase 1, works! Try this,

which generates, according to Leo, "100% correct" PIR:

% ./pugs -C PIR -e 'say "Hello, World!"'
% parrot dump.ast
Hello, World!

* Also because it's now a Proper Compiler, we have this now:

% ./pugs -C PIR -e '"Hello, World!"'
*** Literal value used in constant expression: VStr "Hello, World!"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/Emit/PIR.hs

    r4647 r4655  
    1 {-# OPTIONS_GHC -fglasgow-exts #-} 
     1{-# OPTIONS_GHC -fglasgow-exts -fallow-overlapping-instances #-} 
    22 
    33module Emit.PIR where 
    44import Text.PrettyPrint 
     5import Pugs.Internals 
     6import Pugs.Pretty 
    57 
    68data RegType = RegInt | RegNum | RegStr | RegPMC 
     
    1618type SubName    = String 
    1719type VarName    = String 
     20type PrimName   = String 
     21type PkgName    = String 
    1822 
    1923data Identifier 
    20     = Var VarName 
    21     | Reg RegType Int 
     24    = VAR VarName 
     25    | PMC Int 
     26    deriving (Show, Eq) 
    2227 
    2328data Literal 
     
    2530    | LitInt Integer 
    2631    | LitNum Double 
     32    deriving (Show, Eq) 
    2733 
    2834class (Show x) => Emit x where 
    29     emit :: (Monad m) => x -> m Doc 
    30     emit x = fail ("Unrecognized construct: " ++ show x) 
     35    emit :: x -> Doc 
     36    -- emit x = error ("Unrecognized construct: " ++ show x) 
     37 
     38instance Emit String where 
     39    emit = text 
     40 
     41instance Emit Decl where 
     42    emit (DeclNS name) = emit ".namespace" <+> brackets (quotes $ emit name) 
     43    emit (DeclSub name styps stmts) 
     44        =  (emit ".sub" <+> doubleQuotes (emit name) <+> commaSep styps) 
     45        $+$ nested stmts 
     46        $+$ emit ".end" 
     47 
     48instance Emit SubType where 
     49    emit = emit . ('@':) . drop 3 . show 
     50 
     51instance (Emit a) => Emit [a] where 
     52    emit = vcat . map emit 
     53 
     54nested :: (Emit x) => x -> Doc 
     55nested = nest 4 . emit 
     56 
     57eqSep :: (Emit a, Emit b, Emit c) => a -> b -> [c] -> Doc 
     58eqSep lhs rhs args = emit lhs <+> equals <+> emit rhs <+> commaSep args 
     59 
     60commaSep :: (Emit x) => [x] -> Doc 
     61commaSep = hsep . punctuate comma . map emit 
     62 
     63curPad :: Doc 
     64curPad = int (-1) 
     65 
     66instance Emit Stmt where 
     67    emit (StmtComment []) = empty 
     68    emit (StmtComment str) = char '#' <+> emit str 
     69    emit (StmtLine file line) = text "#line" <+> doubleQuotes (emit file) <+> emit line 
     70    emit (StmtIns ins) = emit ins 
     71    emit (StmtLabel name ins) = emit name <> colon $+$ emit ins 
     72    emit (StmtPad stmts) = emit "new_pad" <+> curPad 
     73 
     74instance Emit RegType where 
     75    emit = emit . map toLower . drop 3 . show 
     76 
     77instance Emit Ins where 
     78    emit (InsLocal rtyp name) = emit ".local" <+> emit rtyp <+> emit name 
     79    emit (InsNew ident otyp) = eqSep ident "new" [otyp] 
     80    emit (InsAssign ident lit) = eqSep ident lit noArgs 
     81    emit (InsFun rets name args) = vcat 
     82        [ eqSep (PMC 0) "find_name" [LitStr name] 
     83        , emit "set_args" <+> sig <> comma <+> commaSep args 
     84        , emit "invokecc" <+> emit (PMC 0) 
     85        ] 
     86        where 
     87        sig = quotes $ parens (commaSep (replicate (length args) "0")) 
     88    emit x = error $ "can't emit: " ++ show x 
     89 
     90noArgs :: [Identifier] 
     91noArgs = [] 
     92 
     93-- set_args '(0b0,0b0,0b0)', $P1, $P2, $P3 
     94 
     95instance Emit ObjType where 
     96    emit = emit . ('.':) . show 
     97 
     98instance Emit Identifier where 
     99    emit (VAR name) = emit name 
     100    emit (PMC num) = emit "$P" <> emit num 
     101 
     102instance Emit Literal where 
     103    emit (LitStr str) = text . show $ encodeUTF8 (concatMap quoted str) 
     104 
     105instance Emit Int where 
     106    emit = int 
    31107 
    32108data Stmt 
    33     = Comment   String 
    34     | Ins       Instruction 
    35     | Label     LabelName Instruction 
     109    = StmtComment   String 
     110    | StmtLine      FilePath Int 
     111    | StmtIns       Ins 
     112    | StmtLabel     LabelName Ins 
     113    | StmtPad       [Stmt] 
     114    deriving (Show, Eq) 
    36115 
    37 data Instruction 
    38     = Local     RegType VarName 
    39     | New       ObjType Identifier 
    40     | Set       Identifier Literal 
    41     | Assign    Identifier Literal 
     116data Ins 
     117    = InsLocal      RegType VarName 
     118    | InsNew        Identifier ObjType  
     119    | InsBind       Identifier Identifier 
     120    | InsAssign     Identifier Literal 
     121    | InsFun        [Identifier] PrimName [Identifier] 
     122    | InsPrim       (Maybe Identifier) PrimName [Identifier] 
     123    | InsStoreLex   VarName Identifier 
     124    deriving (Show, Eq) 
    42125 
    43 data SubType = SubMAIN | SubLOAD | SubANON | SubMETHOD 
     126data SubType = SubMAIN | SubLOAD | SubANON | SubMETHOD | SubMULTI [ObjType] 
    44127    deriving (Show, Eq) 
    45128 
    46129type PIR = [Decl] 
    47130 
    48 data Decl = Sub SubName [SubType] 
     131data Decl 
     132    = DeclSub   SubName [SubType] [Stmt] 
     133    | DeclNS    PkgName 
     134    deriving (Show, Eq) 
    49135 
    50136{- 
     
    54140.end 
    55141    Comment :: String -> PIR Stmt 
    56     Stmt    :: Maybe Label -> PIR Instruction -> PIR Stmt 
     142    Stmt    :: Maybe Label -> PIR Ins -> PIR Stmt 
    57143    RegHard :: RegType -> Int -> PIR Var 
    58144    RegTemp :: RegType -> Int -> PIR Var 
     
    74160    CondCmp :: Bool -> PIR Var -> RelOP -> PIR Var -> Ident -> PIR Stmt 
    75161-} 
     162 
     163preludePIR :: Doc 
     164preludePIR = vcat . map emit $ 
     165    [ ".sub \"&print\"" 
     166    , "    get_params '(0b1000)', $P0" 
     167    , "    $S0 = join '', $P0" 
     168    , "    print $S0" 
     169    , ".end" 
     170    , "" 
     171    , ".sub \"&say\"" 
     172    , "    get_params '(0b1000)', $P0" 
     173    , "    $P1 = find_name '&print'" 
     174    , "    set_args '(0b1000)', $P0" 
     175    , "    invokecc $P1" 
     176    , "    print \"\\n\"" 
     177    , ".end" 
     178    , "" 
     179    , ".namespace ['main']" 
     180    , "" 
     181    ]