Slide 1

Slide 1 text

Implementing Languages

Slide 2

Slide 2 text

Thanks FluentConf

Slide 3

Slide 3 text

Thanks SilverStripe

Slide 4

Slide 4 text

I Am Not A Special Snowflake

Slide 5

Slide 5 text

Compilers Are Not Important

Slide 6

Slide 6 text

Great Books On The Subject

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Why Is This Useful?

Slide 10

Slide 10 text

Why Is This Useful? ▸ Improving productivity ▸ Communicating in a common domain language ▸ Alternative computational models

Slide 11

Slide 11 text

Tools You Can Use

Slide 12

Slide 12 text

Tools You Can Use ▸ Compiler generators ▸ String manipulation and state machines

Slide 13

Slide 13 text

int minutes = 90;

Slide 14

Slide 14 text

Grammar

Slide 15

Slide 15 text

Grammar ▸ List of rules which define structure and syntax ▸ Each rule is called a lexeme

Slide 16

Slide 16 text

int minutes = 90; e ! type id = value | type id

Slide 17

Slide 17 text

Lexer

Slide 18

Slide 18 text

Lexer ▸ Breaks code string into tokens ▸ Lexer ignores nesting

Slide 19

Slide 19 text

e ! type id = value | type id ["type", "int"], ["id", "minutes"], ["assign", "="], ["value", "90"],

Slide 20

Slide 20 text

Parser

Slide 21

Slide 21 text

Parser ▸ Arranges tokens in a hierarchy ▸ Checks tokens for syntax errors

Slide 22

Slide 22 text

["type", "int"], ["id", "minutes"], ["assign", "="], ["value", "90"], ["definition", [ "int", "minutes", "90", ]]

Slide 23

Slide 23 text

Abstract Syntax Tree

Slide 24

Slide 24 text

Abstract Syntax Tree ▸ Represents constructs in the compiler's language

Slide 25

Slide 25 text

["definition", [ "int", "minutes", "90", ]] new Definition( "int", "minutes", "90", )

Slide 26

Slide 26 text

Interpreter

Slide 27

Slide 27 text

Interpreter ▸ Calculates immediate effect to context ▸ Always accepts and returns a context

Slide 28

Slide 28 text

new Definition( "int", "minutes", "90", ) let context = {}; for (let i = 0; i < objects.length; i++) { context = objects[i].applyTo(context); }

Slide 29

Slide 29 text

Compiler

Slide 30

Slide 30 text

Compiler ▸ Writes the AST to a new language ▸ Checks constructs for semantic errors in target language

Slide 31

Slide 31 text

Recap

Slide 32

Slide 32 text

int minutes = 90; e ! type id = value | type id

Slide 33

Slide 33 text

e ! type id = value | type id ["type", "int"], ["id", "minutes"], ["assign", "="], ["value", "90"],

Slide 34

Slide 34 text

["type", "int"], ["id", "minutes"], ["assign", "="], ["value", "90"], ["definition", [ "int", "minutes", "90", ]]

Slide 35

Slide 35 text

["definition", [ "int", "minutes", "90", ]] new Definition( "int", "minutes", "90", )

Slide 36

Slide 36 text

new Definition( "int", "minutes", "90", ) let context = {}; for (let i = 0; i < objects.length; i++) { context = objects[i].applyTo(context); }

Slide 37

Slide 37 text

Yay!

Slide 38

Slide 38 text

Parser Expression Grammar

Slide 39

Slide 39 text

Parser Expression Grammar ▸ Uses pattern matching to tokenise and organise lexemes ▸ Generates a reusable interpreter and/or compiler

Slide 40

Slide 40 text

{ var context = {}; function __set(key, value) { context[key] = value; } function __get(key) { return context[key]; } }

Slide 41

Slide 41 text

start = expression* expression = _ definition _ / _ inspection _ _ "whitespace" = [ \t\r\n]*

Slide 42

Slide 42 text

definition "definition" = t:type _ i:id _ assign _ v:value _ terminal { __set(i, v); } / t:type _ i:id _ terminal { __set(i, null); }

Slide 43

Slide 43 text

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" = ";"

Slide 44

Slide 44 text

inspection "inspection" = "inspect" _ i:id _ terminal { console.log(__get(i)); }

Slide 45

Slide 45 text

Thanks CONFERENCES.OREILLY.COM/FLUENT/JAVASCRIPT-HTML-US/PUBLIC/SCHEDULE/DETAIL/46342 @ASSERTCHRIS