Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Implementing Languages (FluentConf)

Implementing Languages (FluentConf)

Programming is hard. Making compilers is harder. Or so people think. The truth is that making a compiler is just a series of small steps, using regular language constructs. It's so easy, we'll make one in this talk.

Christopher Pitt

March 08, 2016
Tweet

More Decks by Christopher Pitt

Other Decks in Programming

Transcript

  1. Why Is This Useful? ▸ Improving productivity ▸ Communicating in

    a common domain language ▸ Alternative computational models
  2. e ! type id = value | type id ["type",

    "int"], ["id", "minutes"], ["assign", "="], ["value", "90"],
  3. new Definition( "int", "minutes", "90", ) let context = {};

    for (let i = 0; i < objects.length; i++) { context = objects[i].applyTo(context); }
  4. Compiler ▸ Writes the AST to a new language ▸

    Checks constructs for semantic errors in target language
  5. e ! type id = value | type id ["type",

    "int"], ["id", "minutes"], ["assign", "="], ["value", "90"],
  6. new Definition( "int", "minutes", "90", ) let context = {};

    for (let i = 0; i < objects.length; i++) { context = objects[i].applyTo(context); }
  7. Parser Expression Grammar ▸ Uses pattern matching to tokenise and

    organise lexemes ▸ Generates a reusable interpreter and/or compiler
  8. { var context = {}; function __set(key, value) { context[key]

    = value; } function __get(key) { return context[key]; } }
  9. start = expression* expression = _ definition _ / _

    inspection _ _ "whitespace" = [ \t\r\n]*
  10. definition "definition" = t:type _ i:id _ assign _ v:value

    _ terminal { __set(i, v); } / t:type _ i:id _ terminal { __set(i, null); }
  11. type "type" = "int" id "identity" = letters:[a-z]+ { return

    letters.join(""); } assign "assign" = "=" value "value" = numbers:[0-9]+ { return parseInt(numbers.join(""), 10); } terminal "terminal" = ";"