A small compiler

8.2 A small compiler

  This section constructs a small compiler for (a part of) a small language. The compiler compiles this code into code for a hypothetical stack machine.

8.2.1 The language

  The language we consider in this section has integers, booleans, function application, and an if-then-else expression. A language with just these constructs is useless, and you will extend the language in the exercises with some other constructs, which make the language a bit more interesting. We take the following context-free grammar for the concrete syntax of the language.

  Expr0 → if Expr1 then Expr1 else Expr1 | Expr1 Expr1 → Expr2 Expr2 ∗ Expr2 → Int | Bool

  where Int generates integers, and Bool booleans. An abstract syntax for our lan- guage is given in listing 15. Note that we use a single datatype for the abstract syntax instead of three datatypes (one for each nonterminal); this simplifies the code a bit. The listing 15 also contains a definition of a fold and an algebra type for the abstract syntax.

  A parser for expressions is given in listing 16.

  8.2 A small compiler

  sptoken :: String -> Parser Char String sptoken s = (\_ b _ -> b) <>

  many (symbol ’ ’) <> token s <> many1 (symbol ’ ’)

  boolean = const True <> token "True" <|> const False <> token "False" parseExpr :: Parser Char ExprAS

  parseExpr = expr0

  where expr0 = (\a b c d e f -> If b d f) <>

  sptoken "if" <> parseExpr <> sptoken "then" <> parseExpr <> sptoken "else" <> parseExpr

  <|> expr1 expr1 = chainl expr2 (const Apply <> many1 (symbol ’ ’))

  <|> expr2 expr2 = ConBool <> boolean

  <|> ConInt <> natural

  Listing 16: ExprParser.hs

8.2.2 A stack machine

  In section 6.4.4 we have defined a stack machine with which simple arithmetic ex- pressions can be evaluated. Here we define a stack machine that has some more instructions. The language of the previous section wil be compiled into code for this stack machine in the following section.

  The stack machine we will use has the following instructions:

  • it can load an integer; • it can load a boolean; • given an argument and a function on the stack, it can call the function on the

  argument; • it can set a label in the code; • given a boolean on the stack, it can jump to a label provided the boolean is

  false; • it can jump to a label (unconditionally).

  The datatype for instructions is given in listing 17.

8.2.3 Compiling to the stackmachine

  How do we compile the different expressions to stack machine code? We want to define a function compile of type

  compile :: ExprAS -> [InstructionSM] • A ConInt i is compiled to a LoadInt i.

  Programming with higher-order folds

  data InstructionSM = LoadInt Int

  | LoadBool Bool | Call | SetLabel Label | BrFalse Label | BrAlways Label

  type Label = Int

  Listing 17: InstructionSM.hs

  compile (ConInt i) = [LoadInt i] • A ConBool b is compiled to a LoadBool b.

  compile (ConBool b) = [LoadBool b] • An application Apply f x is compiled by first compiling the argument x, then

  the ‘function’ f (at the moment it is impossible to define functions in our language, hence the quotes around ‘function’), and finally putting a Call on top of the stack.

  compile (Apply f x) = compile x ++ compile f ++ [Call] • An if-then-else expression If ce te ee is compiled by first compiling the con-

  ditional expression ce. Then we jump to a label (which will be set before the code of the else expression ee later) if the resulting boolean is false. Then we compile the then expression te. After the then expression we always jump to the end of the code of the if-then-else expression, for which we need an- other label. Then we set the label for the else expression, we compile the else expression ee, and, finally, we set the label for the end of the if-then-else expression.

  compile (If ce te ee) = compile ce

  ++ [BrFalse ?lab1] ++ compile te ++ [BrAlways ?lab2] ++ [SetLabel ?lab1] ++ compile ee ++ [SetLabel ?lab2]

  Note that we use labels here, but where do these labels come from? From the above description we see that we also need labels when compiling an

  expression. We add a label argument (an integer, used for the first label in the compiled code) to function compile, and we want function compile to return the first unused label. We change the type of function compile as follows:

  8.3 Attribute grammars

  compile :: ExprAS -> Label -> ([InstructionSM],Label) type Label = Int

  The four cases in the definition of compile have to take care of the labels. We obtain the following definition of compile:

  compile (ConInt i)

  = \l -> ([LoadInt i],l)

  compile (ConBool b)

  = \l -> ([LoadBool b],l)

  compile (Apply f x)

  = \l -> let (xc,l’) = compile x l

  (fc,l’’) = compile f l’ in (xc ++ fc ++ [Call],l’’)

  compile (If ce te ee) = \l -> let (cc,l’) = compile ce (l+2)

  (tc,l’’) = compile te l’ (ec,l’’’) = compile ee l’’

  in (

  cc ++ [BrFalse l] ++ tc ++ [BrAlways (l+1)] ++ [SetLabel l] ++ ec ++ [SetLabel (l+1)]

  ,l’’’ )

  Function compile is a fold, the carrier type of its algebra is a function of type Label -> ([InstructionSM],Label). The definition of function compile as a fold is given in listing 18.

  Exercise 8.3 . Extend the code generation example by adding variables to the datatype Expr.

  Exercise 8.4 . Extend the code generation example by adding definitions to the datatype Expr

  too.

Dokumen yang terkait

Analisis Komparasi Internet Financial Local Government Reporting Pada Website Resmi Kabupaten dan Kota di Jawa Timur The Comparison Analysis of Internet Financial Local Government Reporting on Official Website of Regency and City in East Java

19 819 7

ANTARA IDEALISME DAN KENYATAAN: KEBIJAKAN PENDIDIKAN TIONGHOA PERANAKAN DI SURABAYA PADA MASA PENDUDUKAN JEPANG TAHUN 1942-1945 Between Idealism and Reality: Education Policy of Chinese in Surabaya in the Japanese Era at 1942-1945)

1 29 9

Improving the Eighth Year Students' Tense Achievement and Active Participation by Giving Positive Reinforcement at SMPN 1 Silo in the 2013/2014 Academic Year

7 202 3

Improving the VIII-B Students' listening comprehension ability through note taking and partial dictation techniques at SMPN 3 Jember in the 2006/2007 Academic Year -

0 63 87

The Correlation between students vocabulary master and reading comprehension

16 145 49

The correlation intelligence quatient (IQ) and studenst achievement in learning english : a correlational study on tenth grade of man 19 jakarta

0 57 61

An analysis of moral values through the rewards and punishments on the script of The chronicles of Narnia : The Lion, the witch, and the wardrobe

1 59 47

Improping student's reading comprehension of descriptive text through textual teaching and learning (CTL)

8 140 133

The correlation between listening skill and pronunciation accuracy : a case study in the firt year of smk vocation higt school pupita bangsa ciputat school year 2005-2006

9 128 37

Transmission of Greek and Arabic Veteri

0 1 22