Add a basic tree data structure.

This commit is contained in:
Danila Fedorin 2018-07-24 17:30:10 -07:00
parent bffa9847d2
commit e57ca6c172
2 changed files with 182 additions and 0 deletions

View File

@ -0,0 +1,68 @@
require "./tree.cr"
module Chalk
class PrintVisitor < Visitor
def initialize
@indent = 0
end
def print_indent
@indent.times do
STDOUT << " "
end
end
def visit(id : TreeId)
print_indent
puts id.id
end
def visit(lit : TreeLit)
print_indent
puts lit.lit
end
def visit(op : TreeOp)
print_indent
STDOUT << "[op] "
puts op.op
@indent += 1
end
def finish(op : TreeOp)
@indent -= 1
end
def visit(function : TreeFunction)
print_indent
STDOUT << "[function] " << function.name << "( "
function.params.each do |param|
STDOUT << param << " "
end
puts ")"
@indent += 1
end
def finish(function : TreeFunction)
@indent -= 1
end
macro forward(text, type)
def visit(tree : {{type}})
print_indent
puts {{text}}
@indent += 1
end
def finish(tree : {{type}})
@indent -= 1
end
end
forward("[block]", TreeBlock)
forward("[var]", TreeVar)
forward("[if]", TreeIf)
forward("[while]", TreeWhile)
forward("[return]", TreeReturn)
end
end

114
src/chalk/tree.cr Normal file
View File

@ -0,0 +1,114 @@
module Chalk
class Visitor
def visit(tree : Tree)
end
def finish(tree : Tree)
end
end
class Tree
def accept(v : Visitor)
v.visit(self)
v.finish(self)
end
end
class TreeId < Tree
property id : String
def initialize(@id : String) end
end
class TreeLit < Tree
property lit : Int64
def initialize(@lit : Int64) end
end
class TreeOp < Tree
property op : TokenType
property left : Tree
property right : Tree
def initialize(@op : TokenType, @left : Tree, @right : Tree) end
def accept(v : Visitor)
v.visit(self)
@left.accept(v)
@right.accept(v)
v.finish(self)
end
end
class TreeBlock < Tree
def initialize(@children : Array(Tree)) end
def accept(v : Visitor)
v.visit(self)
@children.each &.accept(v)
v.finish(self)
end
end
class TreeFunction < Tree
property name : String
property params : Array(String)
property block : Tree
def initialize(@name : String, @params : Array(String), @block : Tree) end
def accept(v : Visitor)
v.visit(self)
@block.accept(v)
v.finish(self)
end
end
class TreeVar < Tree
property name : String
property expr : Tree
def initialize(@name : String, @expr : Tree) end
def accept(v : Visitor)
v.visit(self)
@expr.accept(v)
v.finish(self)
end
end
class TreeIf < Tree
property condition : Tree
property block : Tree
property otherwise : Tree
def initialize(@condition : Tree, @block : Tree, @otherwise : Tree) end
def accept(v : Visitor)
v.visit(self)
@condition.accept(v)
@block.accept(v)
@otherwise.accept(v)
v.finish(self)
end
end
class TreeWhile < Tree
property condition : Tree
property block : Tree
def initialize(@condition : Tree, @block : Tree) end
def accept(v : Visitor)
v.visit(self)
@condition.accept(v)
@block.accept(v)
v.finish(self)
end
end
class TreeReturn < Tree
property rvalue : Tree
def initialize(@rvalue : Tree) end
def accept(v : Visitor)
v.visit(self)
@rvalue.accept(v)
v.finish(self)
end
end
end