Share
Embed
Ruby as a Frontend for Programming Language Implementations (RubyKaigi 2025Β LT)
White-Green
April 17, 2025
Transcript
35 slides
-
RubyKaigi 2025 LT Ruby as a Frontend for Programming Language
Implementations @White-Green (GitHub) @White_Green2525 (π) 2025/04/17 STORES, Inc. -
What Iβll Talk About β’ My Own Programming Language β£
https://github.com/White-Green/equivoc β£ Forget this exists β’ One of the idea that came out of developing this β’ Make a Programming Language effortless 2 -
Programming Language Implementation p 2 + 2 execute β Programming
Language Implementation (e.g. CRuby) 4 5 -
Programming Language Implementation p 2 + 2 parse β AST
translate β IR1 β¦ IRn translate β Bytecode Machine Code execute β 4 6 -
Programming Language Implementation p 2 + 2 parse β Prism
AST translate β IR1 β¦ IRn translate β YJIT Bytecode Machine Code execute β 4 7 -
Programming Language Implementation p 2 + 2 β String parse
β AST translate β IR1 β¦ IRn translate β Bytecode Machine Code execute β 4 8 -
Programming Language Implementation p 2 + 2 parse β AST
β { tag: "Expr", expr: { tag: "Call", fn: "p", args: [ { tag: "Add", lhs: { tag: "Const", value: 2, }, rhs: { tag: "Const", value: 2, translate β IR1 β¦ IRn translate β Bytecode Machine Code execute β 4 9 -
Programming Language Implementation p 2 + 2 parse β AST
translate β IR1 β¦ IRn β Easy to Optimize & Translate SSA Form [ { tag: "Const", out: "v0", value: 2 }, { tag: "Const", out: "v1", value: 2 }, { tag: "Add", out: "v2", lhs: "v0", rhs: "v1" }, { tag: "Call", out: "v3", fn: "p", args: ["v2"] }, ] translate β Bytecode Machine Code execute β 4 10 -
Programming Language Implementation p 2 + 2 parse β AST
translate β IR1 β¦ IRn translate β Bytecode Machine Code execute β 4 β Frontend Backend β 11 -
Programming Language Implementation p 2 + 2 parse β AST
translate β IR1 β¦ IRn translate β Bytecode Machine Code execute β 4 β Frontend Complicated (even if in PoC) Backend β Simple 12 -
Programming Language Implementation p 2 + 2 parse β AST
translate β IR1 β¦ IRn translate β Bytecode Machine Code execute β 4 β’ I want to make a New Programming Language 13 -
Programming Language Implementation p 2 + 2 parse β AST
translate β IR1 β¦ IRn translate β Bytecode Machine Code execute β 4 β’ I want to make a New Programming Language β£ β Develop these ALL! (so hardβ¦) 14 -
My Idea: Use Ruby as a Frontend Ruby β IR1
β¦ IRn translate β Bytecode Machine Code execute β 4 15 -
My Idea: Use Ruby as a Frontend Example of My
Own Programming Language require "./equivoc" # import something def fma(a, b, c) = a * b + c v = fma(1, 2, 3) e_if v < 0 do # custom if statement v = 0 end 16 -
My Idea: Use Ruby as a Frontend Example of My
Own Programming Language require "./equivoc" def fma(a, b, c) = a * b + c v = fma(1, 2, 3) e_if v < 0 do v = 0 end Run $ ruby ./entry.rb β # easy to create a backend to process this INSTRUCTIONS = [ {tag:"Call",out:"v0",fn:"fma",args:[1, 2, 3]}, {tag:"Le",out:"v1",lhs:"v0",rhs:0}, {tag:"If",cond:"v1", updates:[{"v3","v2","v0"}], then_instr:[ {tag:"Const",out:"v2",value:0}, ],else_instr:[]}, ] 17 -
internal equivoc.rb: Variable INSTRUCTIONS = [] class Variable def +(rhs)
out = Variable.new out end end 21 -
internal equivoc.rb: Variable INSTRUCTIONS = [] class Variable def +(rhs)
out = Variable.new instr = { tag: "Add", out:, lhs: self, rhs: } INSTRUCTIONS << instr out end end 22 -
internal equivoc.rb: if def e_if(cond, &block) INSTRUCTIONS, buffer = [],
INSTRUCTIONS # Save INSTRUCTIONS block.call INSTRUCTIONS, result = buffer, INSTRUCTIONS # Restore INSTRUCTIONS end 24 -
internal equivoc.rb: if def e_if(cond, &block) INSTRUCTIONS, buffer = [],
INSTRUCTIONS block.call INSTRUCTIONS, result = buffer, INSTRUCTIONS instr = { tag: "If", cond:, updates: [], then_instr: result, else_instr: [] } INSTRUCTIONS << instr end 25 -
internal equivoc.rb: if def e_if(cond, &block) INSTRUCTIONS, buffer = [],
INSTRUCTIONS before_variables = block.binding.#(snip) # Save local variables in block block.call after_variables = block.binding.#(snip) INSTRUCTIONS, result = buffer, INSTRUCTIONS updates = # variable updates from before_variables, after_variables instr = { tag: "If", cond:, updates:, then_instr: result, else_instr: [] } INSTRUCTIONS << instr end 26 -
internal equivoc.rb: function class Object def self.method_added(name) # Called on
`def` # Since, top-level function is private method of Object end end 27 -
internal equivoc.rb: function class Object def self.method_added(name) # override method
# (collect INSTRUCTIONS in the method before overwriting) define_method name do |*args| end end end 28 -
internal equivoc.rb: function class Object def self.method_added(name) # override method
define_method name do |*args| out = Variable.new instr = { tag: "Call", out:, fn: name, args: } INSTRUCTIONS << instr out end end end 29 -
internal equivoc.rb: call backend process at exit Kernel.at_exit do #
Called when the program exits end 31 -
internal equivoc.rb: call backend process at exit # in equivoc.rb
Kernel.at_exit do # Called when the program exits # We can use INSTRUCTIONS # INSTRUCTIONS = [ # {tag:"Call",out:"v0",fn:"fma",args:[1, 2, 3]}, # {tag:"Le",out:"v1",lhs:"v0",rhs:0}, # {tag:"If",cond:"v1", # updates:[{"v3","v2","v0"}], # then_instr:[ # {tag:"Const",out:"v2",value:0}, # ],else_instr:[]}, # ] end 32 -
internal equivoc.rb: call backend process at exit # in equivoc.rb
Kernel.at_exit do # We can process INSTRUCTIONS as we want # e.g. Dump INSTRUCTIONS into filesystem # Spawn backend process and pass INSTRUCTIONS # Process INSTRUCTIONS in Ruby end 33 -
My Idea: Use Ruby as a Frontend Example of My
Own Programming Language require "./equivoc" # the trick is only this! # ...snip... $ ruby entry.rb β’ collect INSTRUCTIONS like SSA-Form β’ call backend process (Optimize, Translate and Execute) 34 -
My Idea: Use Ruby as a Frontend Example of My
Own Programming Language require "./equivoc" # the trick is only this! # ...snip... $ ruby entry.rb β’ collect INSTRUCTIONS like SSA-Form β’ call backend process (Optimize, Translate and Execute) β’ Here is Exactly a Programming Language Implementation! β£ Without parser β£ Without tree-traversal algorithm β’ It is enough for testing β’ Letβs make Programming Language Implementation effortless with Ruby! 35