From b536c399f55e02a605933ca80603c3c42d42e932 Mon Sep 17 00:00:00 2001 From: martijnv Date: Wed, 31 Jan 2024 12:29:41 +0100 Subject: [PATCH] html geupdated oepsie --- index.html | 1455 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 986 insertions(+), 469 deletions(-) diff --git a/index.html b/index.html index 3243259..c41eac3 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Notes @@ -60,233 +60,260 @@

Notes

Table of Contents

-
-

1. Introduction

+
+

1. Introduction

-
-

1.1. Definitions

+
+

1.1. Definitions

  • A language is a set of “correct” sentences
  • @@ -304,12 +331,12 @@

    1.1. Definitions

-
-

1.2. Course

+
+

1.2. Course

-
-

1.2.1. In this course

+
+

1.2.1. In this course

  • Classes (“difficulty levels”) of languages @@ -337,8 +364,8 @@

    1.2.1. In this course<

-
-

1.2.2. Learning goals

+
+

1.2.2. Learning goals

  • To describe structures (i.e., “formulas”) using grammars;
  • @@ -351,8 +378,8 @@

    1.2.2. Learning goals<

-
-

1.3. Haskell

+
+

1.3. Haskell

Haskell is used because many concept from formal language theory have a direct correspondence in Haskell @@ -415,8 +442,8 @@

1.3. Haskell

-
-

1.4. Language and sets

+
+

1.4. Language and sets

An alphabet is a set of symbols that can be used to form sentences @@ -453,8 +480,8 @@

1.4. Language and sets

-
-

1.5. Summary

+
+

1.5. Summary

Alphabet: A finite set of symbols. @@ -470,16 +497,16 @@

1.5. Summary

-
-

2. Grammars and parsing

+
+

2. Grammars and parsing

-
-

2.1. Grammar

+
+

2.1. Grammar

-
-

2.1.1. Grammar and productions

+
+

2.1.1. Grammar and productions

A grammar is formalism to describe a language inductively. @@ -498,8 +525,8 @@

2.1.1. Grammar and pro

-
-

2.1.2. Restricted grammars/context free

+
+

2.1.2. Restricted grammars/context free

We consider only restricted grammars: @@ -521,8 +548,8 @@

2.1.2. Restricted gram

-
-

2.1.3. Examples:

+
+

2.1.3. Examples:

natural numbers without leading zeros @@ -555,8 +582,8 @@

2.1.3. Examples:

-
-

2.1.4. Ambiguity

+
+

2.1.4. Ambiguity

A grammar where every sentence corresponds to a unique parse tree is called unambiguous. @@ -596,8 +623,8 @@

2.1.4. Ambiguity

-
-

2.1.5. Grammar transformations

+
+

2.1.5. Grammar transformations

A grammar transformation is a mapping from one grammar to another, such that the generated language remains the same. @@ -619,12 +646,12 @@

2.1.5. Grammar transfo

-
-

2.2. Parsing

+
+

2.2. Parsing

-
-

2.2.1. Parsing problem

+
+

2.2.1. Parsing problem

Given a grammar G and a string s, the parsing problem is to decide wether or not \(s\in L(G)\) @@ -635,8 +662,8 @@

2.2.1. Parsing problem

-
-

2.2.2. Parse trees in haskell

+
+

2.2.2. Parse trees in haskell

Consider this grammar: @@ -659,7 +686,7 @@

2.2.2. Parse trees in The string 1-0-1 corresponds to the parse tree

-
+

2023-11-17_11-50-16_screenshot.png

@@ -688,8 +715,8 @@

2.2.2. Parse trees in

-
-

2.3. Summary

+
+

2.3. Summary

Grammar A way to describe a language inductively. @@ -733,12 +760,12 @@

2.3. Summary

-
-

3. Parser Combinators

+
+

3. Parser Combinators

-
-

3.1. Parser data type

+
+

3.1. Parser data type

parseDate5 :: Parser Date
@@ -787,8 +814,8 @@ 

3.1. Parser data type<

-
-

3.2. Actual parse data type is slightly different

+
+

3.2. Actual parse data type is slightly different

The actual type also has what type of symbol we are trying to parse, usually char. @@ -815,8 +842,8 @@

3.2. Actual parse data

-
-

3.3. Implementing <*> and <$>

+
+

3.3. Implementing <*> and <$>

<$> :: (a -> b) -> Parser a -> Parser b
@@ -848,8 +875,8 @@ 

3.3. Implementing <

-
-

3.4. Examples <*> and <$>

+
+

3.4. Examples <*> and <$>

Examples: @@ -864,8 +891,8 @@

3.4. Examples <*>

-
-

3.5. Guard

+
+

3.5. Guard

Only succeed if the result of a parser satisfys a given predicate @@ -891,8 +918,8 @@

3.5. Guard

-
-

3.6. Choice: <|>

+
+

3.6. Choice: <|>

Parses using either or both parsers @@ -915,8 +942,8 @@

3.6. Choice: <|>

-
-

3.7. Longest

+
+

3.7. Longest

This function isn’t actually in library, but could still be a usefull example for a low level parser @@ -934,8 +961,8 @@

3.7. Longest

-
-

3.8. <$ <* and *>

+
+

3.8. <$ <* and *>

All of these are made for ignoring the result of a parser @@ -963,8 +990,8 @@

3.8. <$ <* and *

-
-

3.9. succeed and epsilon

+
+

3.9. succeed and epsilon

Creates a parser that always results in the same value, doesn’t consume anything from the input string @@ -980,8 +1007,8 @@

3.9. succeed and epsil

-
-

3.10. empty

+
+

3.10. empty

Parser that always fails @@ -994,12 +1021,12 @@

3.10. empty

-
-

3.11. satisfy and symbol

+
+

3.11. satisfy and symbol

-
-

3.11.1. satify

+
+

3.11.1. satify

satisfy takes a predicate and returns a parser that parses a single symbol satisfying that predicate. @@ -1013,8 +1040,8 @@

3.11.1. satify

-
-

3.11.2. symbol

+
+

3.11.2. symbol

symbol parses a specific given symbol @@ -1028,8 +1055,8 @@

3.11.2. symbol

-
-

3.12. Biased choice: <<|>

+
+

3.12. Biased choice: <<|>

Biased choice. If the left hand side parser succeeds, the right hand side is not considered. @@ -1042,8 +1069,8 @@

3.12. Biased choice: &

-
-

3.13. Bind: >>=

+
+

3.13. Bind: >>=

Monadic bind @@ -1084,8 +1111,8 @@

3.13. Bind: >>=<

-
-

3.14. do notation

+
+

3.14. do notation

Because we have defined the bind operator we can also use the do notation! @@ -1114,8 +1141,8 @@

3.14. do notation

-
-

3.15. Applicative functors and monads

+
+

3.15. Applicative functors and monads

The operations parsers support are very common, many other types support the same interface(s). @@ -1140,8 +1167,8 @@

3.15. Applicative func

-
-

3.16. option

+
+

3.16. option

Parses an optional element. Takes the default value as its second argument. @@ -1154,12 +1181,12 @@

3.16. option

-
-

3.17. many, some, listOf and greedy

+
+

3.17. many, some, listOf and greedy

-
-

3.17.1. many

+
+

3.17.1. many

Parses many, i.e., zero or more, occurrences of a given parser. @@ -1172,8 +1199,8 @@

3.17.1. many

-
-

3.17.2. some

+
+

3.17.2. some

Parser some, i.e., one or more, occurrences of a given parser. @@ -1190,8 +1217,8 @@

3.17.2. some

-
-

3.17.3. listOf

+
+

3.17.3. listOf

Takes a parser p and a separator parser s. Parses a sequence of p’s that is separated by s’s @@ -1216,11 +1243,11 @@

3.17.3. listOf

-
-

3.17.4. greedy

+
+

3.17.4. greedy

-Greedy variant of many will always parse the most amount it can +Greedy variant of many will always parse the most amount it can

@@ -1248,11 +1275,11 @@

3.17.4. greedy

-
-

3.17.5. greedy1

+
+

3.17.5. greedy1

-Greedy variant of some: +Greedy variant of some:

@@ -1263,11 +1290,11 @@

3.17.5. greedy1

-
-

3.18. chainl and chainr

+
+

3.18. chainl and chainr

-For more details see operators +For more details see operators

chainl :: Parser s a -> Parser s (a -> a -> a) -> Parser s a
@@ -1280,16 +1307,16 @@ 

3.18. chainl and chain

-
-

4. Parser design

+
+

4. Parser design

-
-

4.1. Grammar transformations

+
+

4.1. Grammar transformations

-
-

4.1.1. Removing duplicates

+
+

4.1.1. Removing duplicates

A → u | u | v @@ -1322,12 +1349,12 @@

4.1.1. Removing duplic

-
-

4.1.2. Left factoring

+
+

4.1.2. Left factoring

    -
  1. Left recursion
    +
  2. Left recursion

    A production is called left-recursive if the right hand side starts with the nonterminal of the left hand side. @@ -1358,7 +1385,7 @@

    4.1.2. Left factoring<

  3. -
  4. Removing left recursion
    +
  5. Removing left recursion

    First, split the productions for A into left-recursive and others: @@ -1388,12 +1415,12 @@

    4.1.2. Left factoring<

-
-

4.2. Operators

+
+

4.2. Operators

-
-

4.2.1. Parsing associative operators

+
+

4.2.1. Parsing associative operators

Consider a grammar for simple equations: @@ -1462,8 +1489,8 @@

4.2.1. Parsing associa

-
-

4.2.2. Parsing associative operators of different priorities

+
+

4.2.2. Parsing associative operators of different priorities

The basic idea is to associate operators of different priorities with different non-terminals. @@ -1525,8 +1552,8 @@

4.2.2. Parsing associa

-
-

4.2.3. A general operator parser

+
+

4.2.3. A general operator parser

type Op a = (Char, a -> a -> a)
@@ -1557,12 +1584,12 @@ 

4.2.3. A general opera

-
-

5. Regular Expressions

+
+

5. Regular Expressions

-
-

5.1. A simpler subset of parser combinators

+
+

5.1. A simpler subset of parser combinators

We would like to create a simple subset of parser combinators @@ -1615,8 +1642,8 @@

5.1. A simpler subset

-
-

5.2. Regular Expression

+
+

5.2. Regular Expression

The following expressions in the simplified languages can be converted to regex: @@ -1690,8 +1717,8 @@

5.2. Regular Expressio

-
-

5.3. Limitations of regular expressions/languages

+
+

5.3. Limitations of regular expressions/languages

No parsing @@ -1711,22 +1738,22 @@

5.3. Limitations of re

-
-

6. Finite State Machines

+
+

6. Finite State Machines

We want to create a efficient algorithm for matching regular expressions.

-
-

6.1. Moore Machine

+
+

6.1. Moore Machine

Computers are complicated so instead we consider a Moore Machine

-
+

2024-01-03_10-40-53_screenshot.png

@@ -1737,14 +1764,14 @@

6.1. Moore Machine

  • Finite State Machine (FSM)
  • Finite State Automaton (FSA)
  • -
  • Deterministic Finite Automaton (DFA): result is true or false. +
  • Deterministic Finite Automaton (DFA): result is true or false.
    • This is what we end up using for regular expression matching
  • -
    -

    6.1.1. Example: moore machine for lamp

    +
    +

    6.1.1. Example: moore machine for lamp

    We can model the function of a lamp with three buttons using a moore machine @@ -1759,7 +1786,7 @@

    6.1.1. Example: moore

    -
    +

    2024-01-03_11-07-49_screenshot.png

    @@ -1769,14 +1796,14 @@

    6.1.1. Example: moore

    -
    +

    2024-01-03_11-08-48_screenshot.png

    -
    -

    6.1.2. Advantages of Moore Machines

    +
    +

    6.1.2. Advantages of Moore Machines

    • Easy to use
    • @@ -1821,8 +1848,8 @@

      6.1.2. Advantages of M

    -
    -

    6.1.3. Running Moore Machines

    +
    +

    6.1.3. Running Moore Machines

    runMoore :: Moore inp state out -> [inp] -> state
    @@ -1838,19 +1865,19 @@ 

    6.1.3. Running Moore M

    -
    -

    6.2. Moore Machines for RegExp Matching

    +
    +

    6.2. Moore Machines for RegExp Matching

    -
    -

    6.2.1. Examples

    +
    +

    6.2.1. Examples

    An example Moore Machine for the regular expression a*aaaba*

    -
    +

    2024-01-03_12-14-00_screenshot.png

    @@ -1860,14 +1887,14 @@

    6.2.1. Examples

    -
    +

    2024-01-03_12-18-03_screenshot.png

    -
    -

    6.2.2. Compiling Regular Expressions to DFA

    +
    +

    6.2.2. Compiling Regular Expressions to DFA

    Not all of regular expressions have a direct and easy translation to DFA, this is why we end up using NFAε @@ -1881,7 +1908,7 @@

    6.2.2. Compiling Regul

    -
    +

    2024-01-03_12-33-29_screenshot.png

    @@ -1903,7 +1930,7 @@

    6.2.2. Compiling Regul
  • Every succes state of r1 should be linked to the beginning of r2
  • -
    +

    2024-01-03_12-39-58_screenshot.png

    @@ -1919,7 +1946,7 @@

    6.2.2. Compiling Regul -
    +

    2024-01-03_14-25-26_screenshot.png

    @@ -1938,8 +1965,8 @@

    6.2.2. Compiling Regul

    -
    -

    6.2.3. Regex to Non Deterministic Finite Automaton (NFA)

    +
    +

    6.2.3. Regex to Non Deterministic Finite Automaton (NFA)

    We opt to use NFAε instead of DFA for regular expression matching @@ -1977,8 +2004,8 @@

    6.2.3. Regex to Non De

    -
    -

    6.2.4. Running NFAε

    +
    +

    6.2.4. Running NFAε

    runNFAε :: NFAε symbol state -> [symbol] -> Set state
    @@ -1994,8 +2021,8 @@ 

    6.2.4. Running NFAε

    -
    -

    6.2.5. Performance of the NFA regex

    +
    +

    6.2.5. Performance of the NFA regex

    If n = length input and m = length regexp, then… @@ -2013,8 +2040,8 @@

    6.2.5. Performance of

    -
    -

    6.2.6. Converting NFAε to DFA

    +
    +

    6.2.6. Converting NFAε to DFA

    Basically just create a DFA where the state variable is a set of state @@ -2042,8 +2069,8 @@

    6.2.6. Converting NFA

    -
    -

    7. Folding

    +
    +

    7. Folding

    A compiler roughly has the folowing phases @@ -2069,8 +2096,8 @@

    7. Folding

    We use folding to systematically traverse an AST

    -
    -

    7.1. List folding

    +
    +

    7.1. List folding

    Most common functions over lists can be expressed as folds @@ -2114,8 +2141,8 @@

    7.1. List folding

    -
    -

    7.2. Matched parentheses

    +
    +

    7.2. Matched parentheses

    Consider a grammer with corresponding data type @@ -2191,8 +2218,8 @@

    7.2. Matched parenthes

    -
    -

    7.3. Arithmetic expressions

    +
    +

    7.3. Arithmetic expressions

    Lets take a simple grammar for arithmetic expressions @@ -2262,8 +2289,8 @@

    7.3. Arithmetic expres

    -
    -

    7.4. Building a fold for any datatype

    +
    +

    7.4. Building a fold for any datatype

    For a datatype T, we can define a fold function as follows: @@ -2282,8 +2309,8 @@

    7.4. Building a fold f Every datatype has an identity algebra, which arises by using the constructors as components of the algebra.

    -
    -

    7.4.1. Trees example

    +
    +

    7.4.1. Trees example

    data Tree a = Leaf a
    @@ -2322,8 +2349,8 @@ 

    7.4.1. Trees example

    -
    -

    7.5. TODO Fix

    +
    +

    7.5. TODO Fix

    Dit leek me niet super nuttig, misschien later samenvatten. @@ -2336,8 +2363,8 @@

    7.5. -

    7.6. Algebra for families of datatypes

    +
    +

    7.6. Algebra for families of datatypes

    Each datatype in the family can have its own result type. @@ -2409,8 +2436,8 @@

    7.6. Algebra for famil

    -
    -

    7.7. RepMax fold

    +
    +

    7.7. RepMax fold

    RepMax replaces all the elements of a list with the largest number. @@ -2459,12 +2486,12 @@

    7.7. RepMax fold

    -
    -

    8. Simple Stack Machine

    +
    +

    8. Simple Stack Machine

    -
    -

    8.1. Documentation

    +
    +

    8.1. Documentation

    A lot more detailed documentation can be found on the SSM page: @@ -2475,8 +2502,8 @@

    8.1. Documentation

    -
    -

    8.2. Architecture

    +
    +

    8.2. Architecture

    The simple stack machine is a virtual machine that executes programs consisting of assembly language instructions @@ -2509,28 +2536,28 @@

    8.2. Architecture

    -
    -

    8.3. Instructions

    +
    +

    8.3. Instructions

    -
    -

    8.3.1. LDC - load constant

    +
    +

    8.3.1. LDC - load constant

    Pushes the inline constant on the stack.

    -
    -

    8.3.2. LDR - load from register

    +
    +

    8.3.2. LDR - load from register

    Pushes a value from a register onto the stack.

    -
    -

    8.3.3. LDL - loal local

    +
    +

    8.3.3. LDL - loal local

    Pushes a value relative to the markpointer register. @@ -2544,7 +2571,7 @@

    8.3.3. LDL -
    +

    2024-01-07_18-11-36_screenshot.png

    @@ -2554,14 +2581,14 @@

    8.3.3. LDL -
    +

    2024-01-07_18-12-24_screenshot.png

    -
    -

    8.3.4. LDS - load from stack

    +
    +

    8.3.4. LDS - load from stack

    Pushes a value relative to the top of the stack. @@ -2576,7 +2603,7 @@

    8.3.4. LDS -
    +

    2024-01-07_18-13-50_screenshot.png

    @@ -2586,14 +2613,14 @@

    8.3.4. LDS -
    +

    2024-01-07_18-14-45_screenshot.png

    -
    -

    8.3.5. LDLA - load local adress

    +
    +

    8.3.5. LDLA - load local adress

    Pushes the address of a value relative to the markpointer. @@ -2604,8 +2631,8 @@

    8.3.5. LDLA

    -
    -

    8.3.6. LDA - load via adress

    +
    +

    8.3.6. LDA - load via adress

    Pushes the value pointed to by the value at the top of the stack. The pointer value is offset by a constant offset. @@ -2616,8 +2643,8 @@

    8.3.6. LDA

    -
    -

    8.3.7. LDRR - load register from register

    +
    +

    8.3.7. LDRR - load register from register

    Copy the content of the second register to the first. Does not affect the stack. @@ -2632,7 +2659,7 @@

    8.3.7. LDRR -
    +

    2024-01-07_19-22-01_screenshot.png

    @@ -2642,30 +2669,30 @@

    8.3.7. LDRR -
    +

    2024-01-07_19-22-37_screenshot.png

    -
    -

    8.3.8. NOP - noop

    +
    +

    8.3.8. NOP - noop

    No operation, does nothing, goes to next instruction.

    -
    -

    8.3.9. HALT - halt program

    +
    +

    8.3.9. HALT - halt program

    Machine stops executing instructions.

    -
    -

    8.3.10. AJS - adjust stack pointer

    +
    +

    8.3.10. AJS - adjust stack pointer

    Adjusts the stackpointer with fixed amount. @@ -2680,7 +2707,7 @@

    8.3.10. AJS -
    +

    2024-01-07_19-25-42_screenshot.png

    @@ -2690,22 +2717,22 @@

    8.3.10. AJS -
    +

    2024-01-07_19-26-59_screenshot.png

    -
    -

    8.3.11. BRA - unconditional branch

    +
    +

    8.3.11. BRA - unconditional branch

    Jumps to the destination. Replaces the PC with the destination address.

    -
    -

    8.3.12. BSR - branch to subroutine

    +
    +

    8.3.12. BSR - branch to subroutine

    Pushes the PC on the stack and jumps to the subroutine. @@ -2720,7 +2747,7 @@

    8.3.12. BSR -
    +

    2024-01-08_11-50-30_screenshot.png

    @@ -2730,14 +2757,14 @@

    8.3.12. BSR -
    +

    2024-01-08_11-51-16_screenshot.png

    -
    -

    8.3.13. RET - return from subroutine

    +
    +

    8.3.13. RET - return from subroutine

    Pops a previously pushed PC from the stack and jumps to it. @@ -2752,7 +2779,7 @@

    8.3.13. RET -
    +

    2024-01-08_11-56-40_screenshot.png

    @@ -2762,38 +2789,38 @@

    8.3.13. RET -
    +

    2024-01-08_11-57-05_screenshot.png

    -
    -

    8.3.14. STR - store to register

    +
    +

    8.3.14. STR - store to register

    Pops a value from the stack and stores it in the specified register. See also ldr.

    -
    -

    8.3.15. STS - store into stack

    +
    +

    8.3.15. STS - store into stack

    Pops a value from the stack and stores it in a location relative to the top of the stack.

    -
    -

    8.3.16. STL - store local

    +
    +

    8.3.16. STL - store local

    Pops a value from the stack and stores it in a location relative to the markpointer.

    -
    -

    8.3.17. Operators

    +
    +

    8.3.17. Operators

    Operators remove stack arguments and put the result back on the stack. @@ -2828,14 +2855,14 @@

    8.3.17. Operators

      -
    1. Binary Operator Example:
      +
    2. Binary Operator Example:

      4 and 7 are on top of the stack

      -
      +

      2024-01-08_12-16-23_screenshot.png

      @@ -2849,16 +2876,16 @@

      8.3.17. Operators

    -
    -

    8.4. Translating programs

    +
    +

    8.4. Translating programs

    -
    -

    8.4.1. Translating expressions

    +
    +

    8.4.1. Translating expressions

      -
    1. Translating simple expressions
      +
    2. Translating simple expressions

      t @@ -2918,7 +2945,7 @@

      8.4.1. Translating exp

    -
  • Conditionals
    +
  • Conditionals

    Conditionals can be translated like this: @@ -2944,7 +2971,7 @@

    8.4.1. Translating exp

    -
    +

    2024-01-08_13-36-11_screenshot.png

    @@ -2971,7 +2998,7 @@

    8.4.1. Translating exp

  • -
  • Variables and environments
    +
  • Variables and environments

    To add variables to the code, we change the type of the code, to include an environment as an argument. @@ -3005,8 +3032,8 @@

    8.4.1. Translating exp

  • -
    -

    8.4.2. Statements

    +
    +

    8.4.2. Statements

    We extend our lanuage with statements: @@ -3030,7 +3057,7 @@

    8.4.2. Statements

      -
    1. While loops
      +
    2. While loops

      Translating while loops can be done in multiple ways: (cc is loop condition, cb is loop body) @@ -3040,7 +3067,7 @@

      8.4.2. Statements

      -
      +

      2024-01-08_14-50-16_screenshot.png

      @@ -3107,34 +3134,34 @@

      8.4.2. Statements

    3. -
    4. Method translation
      +
    5. Method translation

      A method call:

      • Put parameters on the stack
      • -
      • Call BSR with method label
      • +
      • Call BSR with method label

      A method definition:

        -
      • Use parameters: from LDS \(-(n+d)\) to \(-(1+d)\) +
      • Use parameters: from LDS \(-(n+d)\) to \(-(1+d)\)
        • \(n\): number of parameters
        • \(d\): current offset
      • Clean up:
    6. -
    7. Method translation with local variables
      +
    8. Method translation with local variables

      Method call as before. @@ -3153,7 +3180,7 @@

      8.4.2. Statements

    9. -
    10. Example method translation with local variables
      +
    11. Example method translation with local variables
      m(7, 12);
      @@ -3170,7 +3197,7 @@ 

      8.4.2. Statements

      -
      +

      2024-01-08_15-53-33_screenshot.png

      @@ -3179,7 +3206,7 @@

      8.4.2. Statements

      Then we put the contents of the stack pointer into the mark pointer

      -
      +

      2024-01-08_15-56-06_screenshot.png

      @@ -3188,30 +3215,30 @@

      8.4.2. Statements

      Then we adjust the stack pointer by +2, to make space for a and b

      -
      +

      2024-01-08_16-01-14_screenshot.png

      -Then we load 7, the x variable onto the top of the stack, using LDL -3 +Then we load 7, the x variable onto the top of the stack, using LDL -3

      Then we call NEG which will negate the argument at the top of the stack, 7

      -
      +

      2024-01-08_16-11-19_screenshot.png

      -Then we call STL +1 to store -7 in the a variable +Then we call STL +1 to store -7 in the a variable

      -
      +

      2024-01-08_16-21-16_screenshot.png

      @@ -3221,7 +3248,7 @@

      8.4.2. Statements

      -
      +

      2024-01-08_16-27-15_screenshot.png

      @@ -3230,16 +3257,16 @@

      8.4.2. Statements

      Then we pop the old position of the mark pointer and put it into the mark pointer.

      -
      +

      2024-01-08_16-30-20_screenshot.png

      -Then we call STS -2, which stores the current top of the stack (the return pointer/adress) two positions up relative to the top of the stack. We do this to remove the arguments of the function from the stack. +Then we call STS -2, which stores the current top of the stack (the return pointer/adress) two positions up relative to the top of the stack. We do this to remove the arguments of the function from the stack.

      -
      +

      2024-01-08_16-53-16_screenshot.png

      @@ -3250,7 +3277,7 @@

      8.4.2. Statements

      -
      +

      2024-01-08_16-59-28_screenshot.png

      @@ -3261,13 +3288,13 @@

      8.4.2. Statements

      -
      +

      2024-01-08_17-00-16_screenshot.png

    12. -
    13. Method translation with return values
      +
    14. Method translation with return values

      There are two options for methods with return values: @@ -3294,8 +3321,8 @@

      8.4.2. Statements

    -
    -

    9. Validation

    +
    +

    9. Validation

    A compiler will also compile any bugs introduced by a programmer. @@ -3363,8 +3390,8 @@

    9. Validation

  • size-limit test
  • -
    -

    9.1. Example checks at AST level

    +
    +

    9.1. Example checks at AST level

    Rest van de lecture was niet boeiend, saai voorbeeld van type checker: @@ -3578,12 +3605,12 @@

    9.1. Example checks at

    -
    -

    10. TODO Pumping Lemmas, proving (non)regular languages

    +
    +

    10. Pumping Lemmas, proving (non)regular languages

    -
    -

    10.1. General strategy for proving a language (non) regular

    +
    +

    10.1. General strategy for proving a language (non) regular

    Regular language: a language that can be expressed using a regular expression, sometimes defined as a language recognised by a finite automaton. @@ -3612,15 +3639,15 @@

    10.1. General strategy

    -
    -

    10.2. Proving a language non-regular

    +
    +

    10.2. Proving a language non-regular

    -
    -

    10.2.1. Strategy step 1: limitation in the formalism

    +
    +

    10.2.1. Strategy step 1: limitation in the formalism

    we expose a limitation in the formalism (in this case, in the concept of finite state automata) @@ -3647,8 +3674,8 @@

    10.2.1. Strategy step

    -
    -

    10.2.2. Step 2: property of language class

    +
    +

    10.2.2. Step 2: property of language class

    From previous limitation, we derive a property that all languages in the class (in this case, regular languages) must have. @@ -3659,7 +3686,7 @@

    10.2.2. Step 2: proper

    -
    +

    2024-01-20_15-57-18_screenshot.png

    @@ -3677,7 +3704,7 @@

    10.2.2. Step 2: proper

    -
    +

    2024-01-20_16-17-55_screenshot.png

    @@ -3691,7 +3718,7 @@

    10.2.2. Step 2: proper

    -
    +

    2024-01-20_16-18-55_screenshot.png

    @@ -3722,8 +3749,8 @@

    10.2.2. Step 2: proper

    -
    -

    10.2.3. Step 3: pumping lemma

    +
    +

    10.2.3. Step 3: pumping lemma

    The we proceed with the final step of the strategy. In order to show that a language is not regular, we show that it does not have the pumping lemma property as follows: @@ -3758,8 +3785,8 @@

    10.2.3. Step 3: pumpin

    -
    -

    10.3. Proving context-free grammar

    +
    +

    10.3. TODO Proving context-free grammar

    A context-free grammar consists of a sequence of productions: @@ -3797,8 +3824,8 @@

    10.3. Proving context-
  • therefore, if a language does not have that property, it cannot be in the class.
  • -
    -

    10.3.1. Step 1: limitation in the formalism

    +
    +

    10.3.1. Step 1: limitation in the formalism

    This time, we analyze parse trees rather than finite state @@ -3813,8 +3840,8 @@

    10.3.1. Step 1: limita

    -
    -

    10.3.2. Step 2: property of language class

    +
    +

    10.3.2. Step 2: property of language class

    If the word is long enough, we have a derivation of the form @@ -3853,8 +3880,8 @@

    10.3.2. Step 2: proper

    -
    -

    10.3.3. Step 3: pumping lemma

    +
    +

    10.3.3. Step 3: pumping lemma

    Pumping lemma for context-free languages @@ -3898,8 +3925,8 @@

    10.3.3. Step 3: pumpin

    -
    -

    10.4. Normal forms

    +
    +

    10.4. Normal forms

    Context-free grammars can be wildly complex, in general. @@ -3914,11 +3941,11 @@

    10.4. Normal forms

    -We get to them by applying grammar transformations (see lecture 4). +We get to them by applying grammar transformations (see lecture 4).

    -
    -

    10.4.1. Chomksy Normal Form

    +
    +

    10.4.1. Chomksy Normal Form

    A context-free grammar is in Chomsky Normal Form if each production rule has one of these forms: @@ -3939,8 +3966,8 @@

    10.4.1. Chomksy Normal

    -
    -

    10.4.2. Greibach Normal Form

    +
    +

    10.4.2. Greibach Normal Form

    A context-free grammar is in Greibach Normal Form if each production rule has one of these forms: @@ -3962,14 +3989,504 @@

    10.4.2. Greibach Norma

    -
    -

    11. Optimizations

    +
    +

    11. Nanopass Compilation

    +

    +A nanopass compiler is a compiler that focusses on creating small passes and many intermediate representations. This makes them easier to understand and maintain. +

    + +

    +This becomes very important for compilers, because compilers are very complex: language options, different compilation targets, support lsp features etc. +

    -
    -

    11.1. Optimization passes

    +
    +

    11.1. Nanopass passes

    +The following is just a bunch of passes a nanopass compiler might do +

    +
    +
    +

    11.1.1. Parse

    +
    + +
    +

    2024-01-30_16-22-33_screenshot.png +

    +
    +
    +
    +
    +

    11.1.2. Type-Check

    +
    +

    +Checks the types +2024-01-30_16-23-29_screenshot.png +

    +
    +
    +
    +

    11.1.3. for → while

    +
    +

    +Translates for loops to while loops +

    + +
    +
    for(int i = 0; i < l.length; i++) {
    +    do_stuff();
    +}
    +
    +
    + +

    +Translated to: +

    +
    +
    int i = 0;
    +while(i < l.length) {
    +    do_stuff();
    +    i++;
    +}
    +
    +
    + +

    +Can be implemented as such: +

    +
    +
    for2while :: AstF  AstW
    +for2while (For (i,c,n) b) = i `Seq` While c (b `Seq` n)
    +for2while (Call f) = Call f
    +for2while (Var i) = Var i
    +for2while (Add e1 e2) = Add e1 e2
    +for2while (Seq e2 e2) = Seq e2 e2
    +for2while _ = ...
    +
    +
    +
    +
    +
    +

    11.1.4. λ → class

    +
    +

    +Convert any lambda function to a class +

    + +
    +
    int[] squares (int[] l) {
    +    Logger q = get_logger();
    +    return sum( map((x => x*x), l));
    +}
    +
    +
    + +

    +Get translated to: +

    +
    +
    int[] squares (int[] l) {
    +    Logger q = get_logger();
    +    return sum( map(new Lam43() , l));
    +}
    +
    +class Lam43 : Runnable {
    +    object run (object x) {
    +        return x*x;
    +    }
    +}
    +
    +
    +
    +
    +
    +

    11.1.5. class → struct

    +
    +

    +Convert all classes to references to structs +

    + +
    +
    class Player {
    +    uint coins;
    +    int hiscore;
    +
    +    void again(){
    +        if(coins-- > 0) {
    +            int score = play();
    +            hiscore = max(score, hiscore);
    +            }
    +    }
    +}
    +
    +
    + +

    +Get translated to: +

    +
    +
    struct Player {
    +    uint coins;
    +    int hiscore;
    +}
    +
    +void again(Player* self){
    +    if(self->coins-- > 0){
    +        int score = play();
    +        self->hiscore =
    +        max(score, self->hiscore);
    +    }
    +}
    +
    +
    +
    +
    +
    +

    11.1.6. Insert Reference-Counting code

    +
    +

    +Keep track of the amount of things still using a certain object, garbage collect object if it isn’t used anymore. +

    + +
    +
    void test() {
    +    int[] xs = list(1,1000000);
    +    int[] ys = map(xs, inc);
    +    print(ys);
    +}
    +
    +
    + +

    +Get translated to: +

    +
    +
    void test() {
    +    int[] xs = list(1,1000000);
    +    int[] ys = map(xs, inc);
    +    _drop(xs);
    +    print(ys);
    +    _drop(ys);
    +}
    +
    +
    +
    +
    +
    +

    11.1.7. Constant folding

    +
    +

    +Inline constants. Not essential, is and optimisation +

    + +
    +
    float circle_area(float r){
    +    float pi = calc_pi(5);
    +    return pi * r * r;
    +}
    +
    +
    + +

    +Get translated to: +

    +
    +
    float circle_area(float r){
    +    return 3.13159 * r * r;
    +}
    +
    +
    +
    +
    +
    +

    11.1.8. if,while, … → goto

    +
    +

    +Translate conditionals and jumps into goto’s: +

    + +
    +
    if (l.length > 7)
    +{
    +    u = insertion_sort(l);
    +}
    +else
    +{
    +    u = quick_sort(l);
    +}
    +
    +
    + +

    +Get translated to: +

    +
    +
    .L0:
    +l.length > 7
    +branch .L1 .L2
    +.L1:
    +u = insertion_sort(l)
    +goto .L3
    +.L2:
    +u = quick_sort(l)
    +goto .L3
    +.L3:
    +
    +
    +
    +
    +
    +

    11.1.9. SSM instructions → x8664 instructions

    +
    +

    +Translate the SSM to actual x86 instructions +

    +
    +
    global.get __stack_pointer
    +local.set 3
    +i32.const 32
    +local.set 4
    +local.get 3
    +local.get 4
    +i32.sub
    +local.set 5
    +local.get 5
    +global.set __stack_pointer
    +i32.const 1
    +local.set 6
    +local.get 2
    +local.set 7
    +local.get 6
    +local.set 8
    +local.get 7
    +
    +
    + +
    +
    sub rsp, 88
    +mov qword ptr [rsp + 8], rdx
    +mov qword ptr [rsp + 16], rs
    +mov qword ptr [rsp + 24], rd
    +mov qword ptr [rsp + 32], rd
    +cmp rdx, 1
    +ja .LBB0_2
    +mov rax, qword ptr [rsp + 32
    +mov rcx, qword ptr [rsp + 24
    +mov rdx, qword ptr [rsp + 8]
    +mov rsi, qword ptr [rsp + 16
    +mov qword ptr [rcx], rsi
    +mov qword ptr [rcx + 8], rdx
    +mov rsi, qword ptr [rip + .L
    +mov rdx, qword ptr [rip + .L
    +mov qword ptr [rcx + 32], rs
    +mov qword ptr [rcx + 40],
    +
    +
    +
    +
    +
    +
    +

    11.2. Nano parse abstract syntax tree?

    +
    +

    +What kind of abstract syntax tree should we use for each nanopass? +

    + +

    +There are quite a lot of options: +

    +
    +
    +

    11.2.1. Many ASTs

    +
    +

    +Use a new AST for each different representation +

    + +

    +This works but has disadvantages. +

    + +

    +One disadvantage is code repetition. For example the for → while nanopass would duplicate the entire datatype except removing the for loop. +

    + +

    +Another disadvantage is that the pass order becomes very unflexable, the λ → class and the for → while could logically be swapped, but this would not be possible because of different datatypes +

    +
    +
    +
    +

    11.2.2. One AST

    +
    +

    +LLVM uses this option. +

    + +

    +The major disadvantage here is no type safety. +

    + +

    +The result of a for → while pass should never include a for loop, but this would be possible if every pass uses the same AST +

    +
    +
    +
    +

    11.2.3. Generics

    +
    +

    +Describe the change in AST that should happen after each pass. +

    + +

    +2024-01-30_17-08-05_screenshot.png +\(\Delta_1\) could be remove for loop for example. +

    + +

    +In the language Racket this is possible by default. +

    + +

    +It’s not possible in default haskell. +

    + +

    +If done it could look something like this: +

    +
    +
    {-# LANGUAGE TemplateHaskell #-}
    +
    +import Vaporware.Generics.Library
    +
    +patch4 :: ΔData
    +patch4 = \exp ->
    +    [ RemoveConstructor "For" [(exp,exp,exp),exp]
    +    , AddConstructor "While" [exp, exp]
    +    ]
    +
    +data Exp4 = $(patch_datatype Exp3 patch4)
    +
    +for2while :: Ast3.Exp
    +for2while (For (i,c,n) b) = i `Seq` While c (b `Seq` n)
    +for2while _ = $(generate_fold_boilerplate)
    +
    +
    + +

    +It is generally speaking also quite complicated. +

    + +

    +There is still a lot of research being done for this. +

    +
    +
    +
    +

    11.2.4. One AST, with refinements

    +
    +

    +Can be seen as a combinations of one AST and generics. +

    + +

    +In haskell self we just use the single AST, but we add liquid haskell, a program verifier to add refinements. +

    + +
    +
    {-@ type Exp3 = {e :: Exp | noWhile e && ...} @-}
    +{-@ type Exp4 = {e :: Exp | noFor e && ...} @-}
    +
    +{-@ for2while :: Exp3 -> Exp4 @-}
    +for2while :: Exp -> Exp
    +
    +
    + +

    +The disadvantage here is difficulty in setting up, and it not being default haskell +

    +
    +
    +
    +

    11.2.5. One AST, with parameters

    +
    +
    +
    data Exp a b c d e f g h ... -- One param per ctr.
    += Raw a String
    +| If b Exp Exp Exp
    +| Goto c Label
    +| Instr d SSM.Instr
    +| Typed e Type Exp
    +| For f (Exp,Exp,Exp) Exp
    +| While g Exp Exp
    +| ...
    +
    +for2while :: Exp a b c d e for  while ...
    +          -> Exp a b c d e Void ()    ...
    +
    +
    +

    +This is Pattern-checker friendly and make re-ordering easy. +

    + +

    +The disadvantage is that this results in big types. +

    +
    +
    +
    +

    11.2.6. TODO One AST, with parameter + type functions

    +
    +

    +Geen idee nog hoe dit werkt +

    +
    +
    data Exp ζ
    +    = Raw (XRaw ζ) String
    +    | If (XIf ζ) Exp Exp Exp
    +    | Goto (XGoto ζ) Label
    +    | Instr (XInstr ζ) SSM.Instr
    +    | Typed (XTyped ζ) Type Exp
    +    | For (XFor ζ) (Exp,Exp,Exp) Exp
    +    | While (XWhile ζ) Exp Exp
    +    | ...
    +
    +-- One type per ctr.
    +type family XRaw ζ
    +type family XIf ζ
    +type family XGoto ζ
    +type family XInstr ζ
    +type family XTyped ζ
    +type family XFor ζ
    +type family XWhile ζ
    +
    +
    + +

    +https://wiki.haskell.org/GHC/Type_families +

    + +

    +https://gitlab.haskell.org/ghc/ghc/-/wikis/implementing-trees-that-grow +

    + +

    +https://ics.uu.nl/docs/vakken/b3tc/downloads-2018/TC-14-final.pdf +

    +
    +
    +
    +
    +
    +

    12. Optimizations

    +
    +
    +
    +

    12.1. Optimization passes

    +
    +

    What is a compiler optimization?

      @@ -3984,9 +4501,9 @@

      11.1. Optimization pas

    -
    -

    11.2. Simple optimizations

    -
    +
    +

    12.2. Simple optimizations

    +
    • Group of simple but effective optimizations
    • Find and replace
    • @@ -4002,9 +4519,9 @@

      11.2. Simple optimizat
    • \(x \leftarrow 3;x \leftarrow 4 \Rightarrow x \leftarrow 4\)
    -
    -

    11.2.1. Unreachable/dead code elimination:

    -
    +
    +

    12.2.1. Unreachable/dead code elimination:

    +
    • Uncalled methods/functions
    • Code after a return statement
    • @@ -4012,9 +4529,9 @@

      11.2.1. Unreachable/de

    -
    -

    11.2.2. Tail call elimination:

    -
    +
    +

    12.2.2. Tail call elimination:

    +

    Turn a simple recursive function into a loop, removes a lot of overhead from function calls. Also prevent stack from growing.

    @@ -4042,13 +4559,13 @@

    11.2.2. Tail call elim

    -
    -

    11.3. Loop optimization

    -
    +
    +

    12.3. Loop optimization

    +
    -
    -

    11.3.1. Loop unrolling

    -
    +
    +

    12.3.1. Loop unrolling

    +

    Removes some overhead from the loop, such as jumps, checking the condition.

    @@ -4081,9 +4598,9 @@

    11.3.1. Loop unrolling

    -
    -

    11.3.2. Loop invariant code motion

    -
    +
    +

    12.3.2. Loop invariant code motion

    +
    for (int i = 0; i < n; i++)
     {
    @@ -4103,9 +4620,9 @@ 

    11.3.2. Loop invariant

    -
    -

    11.3.3. Loop fusion

    -
    +
    +

    12.3.3. Loop fusion

    +

    Less overhead from jumps and conditions.

    @@ -4157,9 +4674,9 @@

    11.3.3. Loop fusion

    -
    -

    11.3.4. Loop fission

    -
    +
    +

    12.3.4. Loop fission

    +

    Oposite of fussion.

    @@ -4194,13 +4711,13 @@

    11.3.4. Loop fission

    -
    -

    11.4. Other optimizations

    -
    +
    +

    12.4. Other optimizations

    +
    -
    -

    11.4.1. Inlining

    -
    +
    +

    12.4.1. Inlining

    +
    let x = 5 in x * y + x
     
    @@ -4212,9 +4729,9 @@

    11.4.1. Inlining

    -
    -

    11.4.2. Common Subexpression Elimination

    -
    +
    +

    12.4.2. Common Subexpression Elimination

    +

    Opposite of inlining: Tradeoff between computation and memory

    @@ -4231,11 +4748,11 @@

    11.4.2. Common Subexpr

    -
    -

    11.5. Compiler pipeline

    -
    +
    +

    12.5. Compiler pipeline

    +
    -
    +

    2024-01-23_10-04-39_screenshot.png

    @@ -4252,7 +4769,7 @@

    11.5. Compiler pipelin

    Author: Martijn Voordouw

    -

    Created: 2024-01-29 Mon 17:32

    +

    Created: 2024-01-31 Wed 12:29