Skip to content

Commit

Permalink
Partial work on AST refactor.
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswailes committed Jan 23, 2015
1 parent 73541e3 commit d980a25
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 21 deletions.
84 changes: 78 additions & 6 deletions lib/kalkin/ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,20 @@ class UnknownNamespace < Exception; end

module AST

class KNode < RLTK::ASTNode; end
class KNode < RLTK::ASTNode
init_order :def
end

class Expression < KNode
# More later
value :type, Type, true
end

class ArgList < KNode
child :args, [Expression]

# Init: args
# Destructure: args

def each(&block)
self.args.each &block
end
Expand All @@ -58,6 +63,9 @@ def last
class ExprSequence < Expression
child :exprs, [Expression]

# Init: exprs
# Destructure: exprs

def each(&block)
self.exprs.each &block
end
Expand All @@ -76,52 +84,82 @@ def last
end

class Literal < Expression
def !
def ~
self.ruby_val
end
end

class KAtom < Literal
value :ruby_val, String

# Init: ruby_val
# Destructure: type, ruby_val
end

class KBool < Literal
value :ruby_val, Object

# Init: ruby_val
# Destructure: type, ruby_val
end

class KFloat < Literal
value :ruby_val, Float

# Init: ruby_val
# Destructure: type, ruby_val
end

class KInteger < Literal
value :ruby_val, Fixnum

# Init: ruby_val
# Destructure: type, ruby_val
end

class KString < Literal
value :ruby_val, String

# Init: ruby_val
# Destructure: type, ruby_val
end

class If < Expression
child :cond, Expression
child :then_, Expression
child :else_, Expression

# Init: cond, then_, else_
# Destructure: type, cond, then_, else_
end

class Invocation < Expression
value :name, String

# Init: name
# Destructure: type, name
end

class FunctionCall < Invocation
child :args, ArgList

# Init: name, args
# Destructure: type, name, args
end

class MessageSendBase < Invocation
child :self_, Expression

# Init: name, self_
# Destructure: type, name, self_
end

class MessageSend < MessageSendBase
child :args, ArgList

# Init: name, self_, args
# Destructure: type, name, self_, args

def operator?
not (name[0,1] =~ /[a-z]/)
end
Expand All @@ -130,6 +168,9 @@ def operator?
class SplitMessageSend < MessageSend
value :op, String

# Init: name, self_, args, op
# Destructure: type, name, op, self_, args

def operator?
true
end
Expand All @@ -139,14 +180,21 @@ class UnaryMessageSend < MessageSendBase; end

class UnresolvedSymbol < Expression
value :name, String

# Init: name
# Destructure: type, name
end

class RefBind < Expression
value :name, String
value :type, Type

def initialize(*args)
super(*args)
# Init: name
# Destructure: type, name

def initialize(name, type)
super(name)

self.type = type

@elide_type = false
end
Expand All @@ -164,11 +212,17 @@ class ParamRefBind < RefBind; end

class RefUse < Expression
value :bind, RefBind

# Init: bind
# Destructure: type, bind
end

class ParamList < KNode
child :params, [ParamRefBind]

# Init: params
# Destructure: params

def each(&block)
self.params.each &block
end
Expand All @@ -191,21 +245,33 @@ class Invokable < KNode
value :type, Type
child :parameters, ParamList

# Init: name, type, parameters
# Destructure: name, type, parameters

alias :params :parameters
alias :'params=' :'parameters='
end

class Function < Invokable
child :body, ExprSequence

# Init: name, type, parameters, body
# Destructure: name, type, parameters, body
end

class NativeFunction < Invokable
value :generator, Proc

# Init: name, type, parameters, generator
# Destructure: name, type, parameters, generator
end

class NodeList < KNode
child :nodes, [KNode]

# Init: nodes
# Destructure: nodes

def each(&block)
self.nodes.each &block
end
Expand All @@ -227,6 +293,9 @@ class Namespace < KNode
value :name, String
child :members, [KNode]

# Init: name, members
# Destructure: name, members

def add_members(node_list)
self.members += node_list.nodes
end
Expand All @@ -242,6 +311,9 @@ def get_members(node_type = nil)

class Klass < KNode
value :name, String

# Init: name
# Destructure: name
end
end
end
20 changes: 10 additions & 10 deletions lib/kalkin/ast_writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ def undent
"def #{n}(#{visit params}) : #{t}#{indent}#{visit b}#{undent}end"
end

on FunctionCall.(n, a) do
on FunctionCall.(t, n, a) do
"#{n}(#{visit a})"
end

on MessageSend.(n, s, a) do |node|
on MessageSend.(t, n, s, a) do |node|
if s.is_a?(MessageSend) and s.operator?
"(#{visit s})"
else
Expand All @@ -75,35 +75,35 @@ def undent
end
end

on UnaryMessageSend.(n, s) do
on UnaryMessageSend.(t, n, s) do
"#{n}#{visit s}"
end

on SplitMessageSend.(m, o, s, a) do
on SplitMessageSend.(t, m, o, s, a) do
"#{visit s}.#{m} #{o} #{visit a}"
end

on If.(c, t, e) do
on If.(ty, c, t, e) do
"if #{visit c} then #{visit t} else #{visit e} end"
end

on Literal.(v) do
on Literal.(t, v) do
v.to_s
end

on KAtom.(a) do
on KAtom.(t, a) do
':' + a.to_s
end

on UnresolvedSymbol.(i) do
on UnresolvedSymbol.(t, i) do
i
end

on RefBind.(n, t) do |b|
on RefBind.(t, n) do |b|
b.elide_type? ? n : "#{n} : #{t}"
end

on RefUse.(b) do
on RefUse.(t, b) do
b.name
end

Expand Down
10 changes: 5 additions & 5 deletions lib/kalkin/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,16 @@ class Parser < RLTK::Parser
c('.IDENT LPAREN .arg_list RPAREN') { |i, a| FunctionCall.new i, ArgList.new(a) }

# Method call
c('.expr_core DOT NEWLINE* .IDENT LPAREN .arg_list RPAREN') { |s, m, a| MessageSend.new m, s, ArgList.new(a) }
c('.expr_core DOT NEWLINE* .IDENT') { |s, m| MessageSend.new m, s, ArgList.new([]) }
c('.expr_core DOT NEWLINE* .IDENT LPAREN .arg_list RPAREN') { |s, m, a| MessageSend.new m, ArgList.new(a), s }
c('.expr_core DOT NEWLINE* .IDENT') { |s, m| MessageSend.new m, ArgList.new([]), s }

# Operator call
c('.expr_core .OPERATOR NEWLINE* .expr_core') { |s, o, a| MessageSend.new o, s, ArgList.new([a]) }
c('OPERATOR expr_core') { |o, s| UnaryMessageSend.new o, s }
c('.expr_core .OPERATOR NEWLINE* .expr_core') { |s, o, a| MessageSend.new o, ArgList.new([a]), s }
c('OPERATOR expr_core') { |o, s| UnaryMessageSend.new o, [], s }

# Method/Operator Call
c('.expr_core DOT NEWLINE* .IDENT .OPERATOR NEWLINE* .expr_core') do |s, m, o, a|
SplitMessageSend.new m, o, s, ArgList.new([a])
SplitMessageSend.new m, ArgList.new([a]), s, o
end
end

Expand Down

0 comments on commit d980a25

Please sign in to comment.