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

Let’s create a programming language! [SoundCloud HQ edition]

Let’s create a programming language! [SoundCloud HQ edition]

Denis Defreyne

June 07, 2016
Tweet

More Decks by Denis Defreyne

Other Decks in Programming

Transcript

  1. 19 DIGIT = … NUMBER = … EXPRESSION = …

    EXPRESSIONS = intersperse( EXPRESSION, char("\n").ignore, ).compact
  2. 20 DIGIT = … NUMBER = …
 EXPRESSION = …

    EXPRESSIONS = … PROGRAM = seq(EXPRESSIONS, eof) .first
 

  3. 34 FUNCTION_CALL = seq( FUNCTION_NAME, char('(').ignore, intersperse( lazy { EXPRESSION

    }, char(',').ignore, ).compact, char(')').ignore, ).compact
  4. 39 FUNCTION_CALL = seq( FUNCTION_NAME, char('(').ignore, intersperse( lazy { EXPRESSION

    }, char(',').ignore, ).compact, char(')').ignore, ).compact
  5. 43 def eval_function_call(expr) case expr[0] when 'add' expr[1] .map {

    |e| eval_expr(e) } .reduce(:+) when 'mul' … end end
  6. 50 DIGIT = … NUMBER = repeat1(DIGIT) .capture .map {

    |d| IntNode.new(d.to_i) } 
 
 
 

  7. 55 def eval_function_call(expr) case expr[0] when 'add' expr[1] .map {

    |e| eval_expr(e) } .reduce(:+) when 'mul' … end end
  8. 56 def eval_function_call(expr) case expr.name when 'add' expr.args .map {

    |e| eval_expr(e) } .reduce(:+) when 'mul' … end end
  9. 60 def eval_function_call(expr) case expr.name when 'add' expr.args .map {

    |e| eval_expr(e) } .reduce(:+) when 'mul' … end end
  10. 72 def eval_expr(expr) case expr when IntNode expr.value when FunCallNode

    eval_function_call(expr) when VarNode eval_var(expr) end end
  11. 81 ASSIGNMENT = seq( VARIABLE_NAME, char('=').ignore, lazy { EXPRESSION },

    ).compact.map do |data| AssignNode.new(data[0], data[1]) end
  12. 94 def eval_expr(expr, env) case expr when … … when

    AssignNode eval_assign(expr, env) end end
  13. % 104 cat stuff.cke 4173 amount = { a =

    2 b = 3 add(a, b) } print(add(2, amount))
  14. 112 def eval_expr(expr, env) case expr when … … when

    ScopeNode eval_scope(expr, env) end end
  15. 113 def eval_scope(expr, env) init = ValAndEnv.new(0, env) result =

    expr.exprs.reduce(init) do |result, e| eval_expr(e, result.env) end ValAndEnv.new(result.val, env) end
  16. 114 def eval_scope(expr, env) init = ValAndEnv.new(0, env) result =

    expr.exprs.reduce(init) do |result, e| eval_expr(e, result.env) end ValAndEnv.new(result.val, env) end
  17. % 115 cat stuff.cke 4173 amount = { a =

    2 b = 3 add(a, b) } print(add(2, amount))
  18. % 121 cat stuff.cke fun multiply(a, b) { if (b)

    { add(a, multiply(a, sub(b, 1))) } else { 0 } } print(multiply(3, 5))
  19. 125 FUNCTION_DEF = seq( string('fun').ignore, FUNCTION_NAME, char('(').ignore, intersperse( VARIABLE_NAME, char(',').ignore,

    ).compact, char(')').ignore, SCOPE, ).compact.map do |data| FunDefNode.new(data[0], data[1], data[2]) end
  20. 127

  21. 128 def eval_function_call(expr, env) fun = env[expr.name] values = expr.args.map

    { |e| eval_expr(e) } 
 
 
 
 fun.body.call(*values)
  22. 129 def eval_function_call(expr, env) fun = env[expr.name] values = expr.args.map

    { |e| eval_expr(e) } case fun.body when Proc when Scope … fun.body.call(*values)
  23. 129 def eval_function_call(expr, env) fun = env[expr.name] values = expr.args.map

    { |e| eval_expr(e) } case fun.body when Proc when Scope … fun.body.call(*values)
  24. 130

  25. % 131 cat stuff.cke fun multiply(a, b) { if (b)

    { add(a, multiply(a, sub(b, 1))) } else { 0 } } print(multiply(3, 5))
  26. % 133 cat stuff.cke fun multiply(a, b) { if (b)

    { a + multiply(a, b - 1) } else { 0 } } print(multiply(3, 5))
  27. 144

  28. 144 input: infix notation e.g. a + b * c

    precedences e.g. a + b * c
  29. 144 input: infix notation e.g. a + b * c

    precedences e.g. a + b * c associativities e.g. a + b * c
  30. 144 input: infix notation e.g. a + b * c

    precedences e.g. a + b * c associativities e.g. a + b * c 
 output: postfix notation e.g. a b c * +
  31. 145 tokens = "10 - 2 - 5 * 2

    + 2 ^ 3 ^ 4" .split(" ") 
 
 
 
 
 
 

  32. 146 tokens = "10 - 2 - 5 * 2

    + 2 ^ 3 ^ 4" .split(" ") res = shunting_yard( tokens, PRECEDENCES, ASSOCIATIVITIES, )
  33. 147 tokens = "10 - 2 - 5 * 2

    + 2 ^ 3 ^ 4" .split(" ") res = shunting_yard( tokens, PRECEDENCES, ASSOCIATIVITIES, ) puts res.join(' ')
  34. 148 PRECEDENCES = { '^' => 3, '*' => 2,

    '/' => 2, '+' => 1, '-' => 1, }
  35. 149 ASSOCIATIVITIES = { '^' => :right, '*' => :left,

    '/' => :left, '+' => :left, '-' => :left, }
  36. 152 10 2 - 5 2 * - 2 3

    4 ^ ^ + 2 10
  37. 155 10 2 - 5 2 * - 2 3

    4 ^ ^ + 2 5 8
  38. 156 10 2 - 5 2 * - 2 3

    4 ^ ^ + 10 8
  39. 158 10 2 - 5 2 * - 2 3

    4 ^ ^ + 2 -2
  40. 159 10 2 - 5 2 * - 2 3

    4 ^ ^ + 3 2 -2
  41. 160 10 2 - 5 2 * - 2 3

    4 ^ ^ + 4 3 2 -2
  42. 161 10 2 - 5 2 * - 2 3

    4 ^ ^ + 81 2 -2
  43. 162 10 2 - 5 2 * - 2 3

    4 ^ ^ + 241785163 -2
  44. 163 10 2 - 5 2 * - 2 3

    4 ^ ^ + 241785163
  45. 166 postfix_tokens = shunting_yard(
 expr.tokens, PRECEDENCES, ASSOCIATIVITIES) stack = []

    postfix_tokens.each do |e| if e.is_a?(Clarke::AST::Op) values = [stack.pop, stack.pop] stack.push(eval_op(e, values)) else stack.push(e) end end
  46. % 168 cat stuff.cke fun multiply(a, b) { if (b)

    { a + multiply(a, b - 1) } else { 0 } } print(multiply(3, 5))
  47. Types! Loops! Closures! Objects!
 Classes! Inheritance! Tuples! Records! Typechecking! Multimethods!

    Enumerations! Proper lexical scoping! Pattern matching! Currying! Modules! 170
  48. 171

  49. 171 L1 Numbers L2 Function calls C1 Abstract syntax C2

    Environment L3 Variables C3 Print function
  50. 171 L1 Numbers L2 Function calls C1 Abstract syntax C2

    Environment L3 Variables C3 Print function C4 Immutable environment
  51. 171 L1 Numbers L2 Function calls C1 Abstract syntax C2

    Environment L3 Variables C3 Print function C4 Immutable environment L4 Scopes
  52. 171 L1 Numbers L2 Function calls C1 Abstract syntax C2

    Environment L3 Variables C3 Print function C4 Immutable environment L4 Scopes L5 Conditionals
  53. 171 L1 Numbers L2 Function calls C1 Abstract syntax C2

    Environment L3 Variables C3 Print function C4 Immutable environment L4 Scopes L5 Conditionals L6 Function definitions
  54. 171 L1 Numbers L2 Function calls C1 Abstract syntax C2

    Environment L3 Variables C3 Print function C4 Immutable environment L4 Scopes L5 Conditionals L6 Function definitions L7 Operators