Kompilatorer och interpretatorer: Lecture 9

Note: This is an outline of what I intend to say on the lecture. It is not a definition of the course content, and it does not replace the textbook.

Today: More GC. Interpreters. Stack machines. Executing the syntax tree.
ASU 2.8.

Rest from the previous lecture: Garbage collection

The Very Basics of Garbage Collection

Terms:

Old program (grows and crashes):
#include <stdlib.h>

int main() {
  while (1)
    malloc(100);
  return 0;
}
New program (works Ok):
#include <stdlib.h>
#include "gc.h"

int main() {
  while (1)
    GC_malloc(100);
  return 0;
}
C++: Several ways. One is to inherit from class gc:
class A: public gc {...};
A* a = new A;       // a is collectable. 

Interpreters

Approaches:

2.8 Abstract stack machines

The basics (you remember this from the lab)

Example: 2 * 3 + 4 * 5

Code:

push 2
push 3
*
push 4
push 5
*
+
Operations: push, pop (and throw away), +, -, *, ...
We need an opcode, plus an "immediate" or "address" field

l-values and r-values ("left"-values, "right"-values)

Example: 2 * a + 3

Code:

push 2
rvalue a
*
push 3
+

Example: a = 2 * a + 3

Code:

lvalue a
push 2
rvalue a
*
push 3
+
=
Operations: lvalue, rvalue

Control flow

Operations:

Statements: IF

"Yacc pseudocode", with an operator+ that concatenates instruction sequences:
stmt: IF '(' expr ')' stmt1 {
  int afterwards = newlabel();
  $$ = $3 +
       instr(gofalse, afterwards) +
       $5 +
       instr(label, afterwards);
}
Or, with plain printf:
stmt: IF '(' expr ')'
      { afterwards = newlabel(); printf("gofalse %d\n", afterwards); }
      stmt1
      { printf("label%d\n", afterwards); }
Example source code:
if (a > 2)
  a = a + 1;
Target code for the stack machine:
rvalue a
push 2
>
gofalse 1
lvalue a
rvalue a
push 1
+
=
label 1

Statements: WHILE

"Yacc pseudocode":
stmt: WHILE '(' expr ')' stmt1 {
  int before = newlabel();
  int afterwards = newlabel();
  $$ = instr(label, before) +
       $3 +
       instr(gofalse, afterwards) +
       $5 +
       instr(jump, before) +
       instr(label, afterwards);
}
Example source code:
if (a > 2)
  while (a < 10)
    a = a + 1;
Target code for the stack machine:
rvalue a
push 2
>
gofalse 1
label 2
rvalue a
push 10
<
gofalse 3
lvalue a
rvalue a
push 1
+
=
jump 2
label 3
label 1

Short-circuit evaluation of boolean operators

if (expr1 || expr2) ...
Target code for the stack machine:
Code for expr1
copy
gotrue 1
pop
Code for expr2
label 1
And use it for something. With a statement:
if (expr1 || expr2) statement
Target code for the stack machine:
Code for expr1
copy
gotrue 1
pop
Code for expr2
label 1
gofalse 2
Code for statement
label 2

Executing the syntax tree

Lisp


Thomas Padron-McCarthy (Thomas.Padron-McCarthy@tech.oru.se) February 16, 2003