# Lecture 1
###### tags: `PSD`
## Chapter: introduction
- object language is a language we study (c++, latin)
- meta language is the language in which we conduct our discussions (Danish, english)
**Expressions without variables**
first let us consider expressions consisting only of integers constants and two arguments (dyadic) operators (+) and (*)
```F#
type expr =
|CstI of int
|Prim of string * expr * epxr
```
A value of type expr is an *abstract syntax tree* that represents an expression.
| Expression | Representation |
| ---------- |:--------------------------------------------- |
| 17 | CstI 17 |
| 3-4 | Prim("-", CstI 3, CstI 4) |
| 7*9+10 | Prim("+", Prim("*", CstI 7, CstI 9), CstI 10) |
An expression can be evaluated to an integer by a function *eval : expr -> int*
````F#
let rec eval (e:expr) : int =
match e with
|CstI i -> i
|Prim("+", e1, e2) -> eval e1 + eval e2
|Prim("-", e1, e2) -> eval e1 - eval e2
|Prim("*", e1, e2) -> eval e1 * eval e2
|_ -> failwith "unknown primitive"
````
The eval function is an *interpreter* for "programs" in the expression language.
**Expressions with Variables**
We extend our expression language with variables such as *x* and *y*.
```F#
type expr =
|CstI of int
|Var of string
|Prim of string * expr * epxr
```
| Expression | Representation |
| ---------- |:---------------------------------------------- |
| 17 | CstI 17 |
| x | Var "x" |
| 3+a | Prim("+", CstI 3, Var "a") |
| b*9+a | Prim("+", Prim("*", Var "b", CstI 9), Var "a") |
We also need to extend our interpreter of expressions: The eval function.
We do this by giving eval an extra arguement (env).
an environment.
The role of the environment is to associate a value with a variable. It is a map/dictionary.
```F#
(string * int)
let env = [("a", 3); ("c", 78); ("baf", 666); ("b", 111)];;
```
An empty invironment, which does not map any variable to anything is represented by the empty aossociation list.
```F#
let emptyenv = [];;
```
The function *lookup: (stirng * int) list -> string -> int* look up a variable in an environment.
```F#
let rec lookup env x =
match env with
|[] -> failwith (x + "not found")
|(y, v)::r -> if x=y then v else lookup r x;;
```
Our new eval function which takes an expression and an environment.
It uses the lookup function to determine the value of a variable or failes.
````F#
let rec eval (e:expr) (env: (string * int) list) : int =
match e with
|CstI i -> i
|Var x -> lookup env x
|Prim("+", e1, e2) -> eval e1 env + eval e2 env
|Prim("-", e1, e2) -> eval e1 env - eval e2 env
|Prim("*", e1, e2) -> eval e1 env * eval e2 env
|_ -> failwith "unknown primitive"
````
The lookup function will return the first value associated with a variable.
if env is ```F# [("x", 11); ("x",22)];;```
then ```F# lookup env "x"```is 11 and not 22.
**Syntax and Semantics**
two kinds of syntaxs
1. Concrete syntax
2. Abstract syntax
two kinds of semantics
1. Dynamic semantics
2. Static semantics
## Chapter 2: Interpreters and Compilers
**Interpreter & compilers**
An *interpreter* executes a program on some input --> producing an output/result.
It is usaually itself a program.
For any interpreter we must distinguish the interpreted language L from the implementation language I.
L = language of the program being executed. e.g. expr
I = language in which the interpreter is written e.g. F#)
The interpreter is often called an abstract machine or virtual machine.
A *compiler* takes an input from a source program and generates as output another program (target program) that can be executed.
For any compiler we must distinguish three languages
1. the source language S (e.g. expr) of the input program
2. The target language T (e.g. texpr) of the output program
3. the implementation language I (e.g. F#) of the compiler itself.
The compiler does not execute the program.
After the target program as been generated it must be executed by a machine or interpreter which can execute program written in language T.
Here we can distinguish between
- compile-time
- (what time the source program is compiled into target program) and
- run-time
- (what time the target program is executed on actual inputs to produce a result).

**Scope and Bound and Free variables**
The *scope* of a variable is that part of a program which it is visible.
```F#
let f x = x + 3
```
the scope of x in this F# function is definition is just the function body x+3.
A language is *static scoped* if the scope of the bindings follow the syntactic structure of the program.
// Hvad betyder det helt konkret?
A language is *nested scope* if an inner scope may create a "hole" in an outer scope by declaring a new variable with the same name.
```F#
let f x = (let x = 8 in x * 2) + (x+3)
```
Here the second binding of x hides the first one in x*2 but not in x+3 so f(1) = (8*2)+(1+3)=20
A variable is *bound* if it occurs within the scope of a binding for that variable and *free* otherwise.
**Expressions with Let-bindings and Static Scope**
We add the let-binding to our language expr
```F#
type expr =
|CstI of int
|Var of string
|Let od string * expr * epxr
|Prim of string * expr * epxr
```
We can use the same lookup function as earlier.
We can evaulate ```let x = erhs in ebody end```as follows
1. evaulate the right-hand side erhs in the same env as the entire let-binding.
2. obtain the value xval for x
3. create a new environment env1 by adding the association (x,xval) and interpret the let-body ebody in that env.
4. return the same result as the result of the let-binding
````F#
let rec eval (e:expr) (env: (string * int) list) : int =
match e with
|CstI i -> i
|Var x -> lookup env x
|Let (x, erhs, ebody) ->
let xval = eval erhs env
let env1 = (x,xval)::env
eval ebody env1
|Prim("+", e1, e2) -> eval e1 env + eval e2 env
|Prim("-", e1, e2) -> eval e1 env - eval e2 env
|Prim("*", e1, e2) -> eval e1 env * eval e2 env
|_ -> failwith "unknown primitive"
````
**Closed expressions**
An expression is closed if no variable occurs free in the expression.
To test if an expression is closed see page 16 in the book for the code.
A constant is always closed.
A varible occurrence x is closed in vs if x appears in vs.
**Integer addresses instead of names**
For effeiciency, symbolic variables names are replaced by variable addresses in real machine code and most interpreters.
```F#
type texpr =
|TCstI of int
|TVar of int
|TLet of texpr * texpr
|TPrim of string * texpr * tepxr
```
we define an abstract syntax texpr for target expressions that uses integer variables indexes.
Now we can define tcomp : expr -> string list -> texpr
A compiler from expr to texpr.
```F#
let rec tcomp (e: expr) (cenv: string list) : texpr =
match e with
|CstI i -> TCstI i
|Var x -> TVar (getindex cenv x)
|Let (x, erhs, ebody) ->
let cenv1 = x::cenv
TLet(tcomp erhs cenv, tcomp ebody cenv1)
|Prim(ope, e1, e2) ->
TPrim(ope, tcomp e1 cenv, tcomp e1 cenv)
```
**Stack machines for expression evaluation**
Expression/functional programs are often evaluated by a stack machine.
A stack machine = an interpreter that implements an abstract machine.