add lots of operators. Assignment becomes operator. fix the mess
This commit is contained in:
parent
3974f2516d
commit
cc5915135a
@ -25,26 +25,6 @@ module Ast
|
||||
end
|
||||
end
|
||||
|
||||
class AssignmentExpression < Expression
|
||||
attr_reader :assignee, :assigned
|
||||
def initialize assignee, assigned
|
||||
@assignee, @assigned = assignee, assigned
|
||||
end
|
||||
def inspect
|
||||
self.class.name + ".new(" + assignee.inspect + ", " + assigned.inspect + ")"
|
||||
end
|
||||
|
||||
def compile context
|
||||
value = @assigned.compile(context)
|
||||
variable = Vm::Variable.new @assignee , :r0 , value
|
||||
context.locals[@assignee] = variable
|
||||
variable
|
||||
end
|
||||
|
||||
def attributes
|
||||
[:assignee, :assigned]
|
||||
end
|
||||
end
|
||||
class OperatorExpression < Expression
|
||||
attr_reader :operator, :left, :right
|
||||
|
||||
@ -62,6 +42,14 @@ module Ast
|
||||
parent_locals = context.locals
|
||||
context.locals = {}
|
||||
args = []
|
||||
|
||||
#assignemnt
|
||||
value = @assigned.compile(context)
|
||||
variable = Vm::Variable.new @assignee , :r0 , value
|
||||
context.locals[@assignee] = variable
|
||||
variable
|
||||
|
||||
|
||||
params.each do |param|
|
||||
args << param.compile(context) # making the argument a local
|
||||
end
|
||||
|
@ -20,7 +20,7 @@ module Parser
|
||||
rule(:double_quote){ str('"') }
|
||||
rule(:minus) { str('-') }
|
||||
rule(:plus) { str('+') }
|
||||
rule(:equal_sign) { str('=') >> space?}
|
||||
|
||||
rule(:sign) { plus | minus }
|
||||
rule(:dot) { str('.') }
|
||||
rule(:digit) { match('[0-9]') }
|
||||
|
@ -5,6 +5,7 @@ require_relative "conditional"
|
||||
require_relative "expression"
|
||||
require_relative "function_call"
|
||||
require_relative "function_definition"
|
||||
require_relative "operators"
|
||||
|
||||
module Parser
|
||||
|
||||
@ -20,11 +21,12 @@ module Parser
|
||||
include BasicTypes
|
||||
include Tokens
|
||||
include Keywords
|
||||
include FunctionCall
|
||||
include FunctionDefinition
|
||||
include Conditional
|
||||
include Expression
|
||||
include FunctionCall
|
||||
include FunctionDefinition
|
||||
include Operators
|
||||
|
||||
rule(:root){ (function_definition | expression | assignment | function_call).repeat }
|
||||
rule(:root){ (function_definition | expression | operator_expression | function_call).repeat }
|
||||
end
|
||||
end
|
||||
|
@ -2,21 +2,15 @@ module Parser
|
||||
module Expression
|
||||
include Parslet
|
||||
|
||||
rule(:assignment) { name.as(:asignee) >> equal_sign >> expression.as(:asigned) }
|
||||
|
||||
rule(:simple_expression) { function_call | integer | string | name }
|
||||
rule(:expression) { (conditional | simple_expression ) >> newline.maybe }
|
||||
|
||||
def delimited_expressions( delimit )
|
||||
( (delimit.absent? >> (assignment | expression)).repeat(1)).as(:expressions) >> delimit >> newline.maybe
|
||||
( (delimit.absent? >> (operator_expression | expression)).repeat(1)).as(:expressions) >> delimit >> newline.maybe
|
||||
end
|
||||
|
||||
rule(:expressions_else) { delimited_expressions(keyword_else) }
|
||||
rule(:expressions_end) { delimited_expressions(keyword_end) }
|
||||
|
||||
rule(:operator_expression) do
|
||||
infix_expression(expression, [multiply, 2, :left], [plus, 1, :right])
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -1,15 +1,18 @@
|
||||
module Parser
|
||||
module Keywords
|
||||
include Parslet
|
||||
rule(:keyword_if) { str('if') >> space? }
|
||||
rule(:keyword_else) { str('else') >> space? }
|
||||
rule(:keyword_def) { str('def') >> space? }
|
||||
rule(:keyword_end) { str('end') >> space? }
|
||||
rule(:keyword_true) { str('true').as(:true) >> space?}
|
||||
rule(:keyword_false){ str('false').as(:false) >> space?}
|
||||
rule(:keyword_nil) { str('null').as(:nil) >> space?}
|
||||
rule(:keyword_while) { str('while').as(:while) >> space?}
|
||||
rule(:keyword_do) { str('do').as(:do) >> space?}
|
||||
rule(:keyword_begin) { str('begin').as(:begin) >> space?}
|
||||
rule(:keyword_begin) { str('begin').as(:begin) >> space?}
|
||||
rule(:keyword_def) { str('def') >> space? }
|
||||
rule(:keyword_do) { str('do').as(:do) >> space?}
|
||||
rule(:keyword_else) { str('else').as(:else) >> space? }
|
||||
rule(:keyword_end) { str('end').as(:end) >> space? }
|
||||
rule(:keyword_false) { str('false').as(:false) >> space?}
|
||||
rule(:keyword_if) { str('if').as(:if) >> space? }
|
||||
rule(:keyword_rescue) { str('rescue').as(:rescue) >> space?}
|
||||
rule(:keyword_true) { str('true').as(:true) >> space?}
|
||||
rule(:keyword_nil) { str('nil').as(:nil) >> space?}
|
||||
rule(:keyword_unless) { str('unless').as(:unless) >> space?}
|
||||
rule(:keyword_until) { str('until').as(:until) >> space?}
|
||||
rule(:keyword_while) { str('while').as(:while) >> space?}
|
||||
end
|
||||
end
|
@ -0,0 +1,52 @@
|
||||
module Parser
|
||||
module Operators
|
||||
include Parslet
|
||||
rule(:exponent) { str('**') >> space?}
|
||||
rule(:multiply) { match['*/%'] >> space? }
|
||||
rule(:plus) { match['+-'] >> space? }
|
||||
rule(:shift) { str(">>") | str("<<") >> space?}
|
||||
rule(:bit_and) { str('&') >> space?}
|
||||
rule(:bit_or) { str('|') >> space?}
|
||||
rule(:greater_equal) { str('>=') >> space?}
|
||||
rule(:smaller_equal) { str('<=') >> space?}
|
||||
rule(:larger) { str('>') >> space?}
|
||||
rule(:smaller) { str('<') >> space?}
|
||||
rule(:identity) { str('===') >> space?}
|
||||
rule(:equal) { str('==') >> space?}
|
||||
rule(:not_equal) { str('!=') >> space?}
|
||||
rule(:boolean_and) { str('&&') | str("and") >> space?}
|
||||
rule(:boolean_or) { str('||') | str("or") >> space?}
|
||||
rule(:assign) { str('=') >> space?}
|
||||
rule(:op_assign) { str('+=')|str('-=')|str('*=')|str('/=')|str('%=') >> space?}
|
||||
rule(:eclipse) { str('..') |str("...") >> space?}
|
||||
rule(:assign) { str('=') >> space?}
|
||||
|
||||
#infix doing the heavy lifting here,
|
||||
# is defined as an expressions and array of [atoms,priority,binding] triples
|
||||
rule(:operator_expression) do infix_expression(expression,
|
||||
[exponent, 120, :left] ,
|
||||
[multiply, 120, :left] ,
|
||||
[plus, 110, :left],
|
||||
[shift, 100, :left],
|
||||
[bit_and, 90, :left],
|
||||
[bit_or, 90, :right],
|
||||
[greater_equal, 80, :left],
|
||||
[smaller_equal, 80, :left],
|
||||
[larger, 80, :left],
|
||||
[smaller, 80, :left],
|
||||
[identity, 70, :right],
|
||||
[equal, 70, :right],
|
||||
[not_equal, 70, :right],
|
||||
[boolean_and, 60, :left],
|
||||
[boolean_or, 50, :right],
|
||||
[eclipse, 40, :right],
|
||||
[keyword_rescue, 30, :right],
|
||||
[assign, 20, :right],
|
||||
[op_assign, 20, :right],
|
||||
[keyword_until, 10, :right],
|
||||
[keyword_while, 10, :right],
|
||||
[keyword_unless, 10, :right],
|
||||
[keyword_if, 10, :right])
|
||||
end
|
||||
end
|
||||
end
|
@ -15,7 +15,5 @@ module Parser
|
||||
rule(:question_mark) { str('?') >> space? }
|
||||
rule(:excamation_mark) { str('!') >> space? }
|
||||
|
||||
rule(:multiply) { match['*/'] >> space? }
|
||||
rule(:plus) { match['+-'] >> space? }
|
||||
end
|
||||
end
|
@ -18,14 +18,14 @@ module Parser
|
||||
Ast::FuncallExpression.new(function_call.name, argument_list)
|
||||
end
|
||||
|
||||
rule(:conditional => simple(:conditional),
|
||||
:if_true => {:expressions => sequence(:if_true)},
|
||||
:if_false => {:expressions => sequence(:if_false)}) do
|
||||
rule(:if => simple(:if), :conditional => simple(:conditional),
|
||||
:if_true => {:expressions => sequence(:if_true) , :else => simple(:else) },
|
||||
:if_false => {:expressions => sequence(:if_false) , :end => simple(:e) }) do
|
||||
Ast::ConditionalExpression.new(conditional, if_true, if_false)
|
||||
end
|
||||
|
||||
rule(:while => simple(:while), :while_cond => simple(:while_cond) , :do => simple(:do),
|
||||
:body => {:expressions => sequence(:body)}) do
|
||||
:body => {:expressions => sequence(:body) , :end => simple(:e) }) do
|
||||
Ast::WhileExpression.new(while_cond, body)
|
||||
end
|
||||
|
||||
@ -34,14 +34,10 @@ module Parser
|
||||
|
||||
rule(:function_definition => simple(:function_definition),
|
||||
:parmeter_list => sequence(:parmeter_list),
|
||||
:expressions => sequence(:expressions)) do
|
||||
:expressions => sequence(:expressions) , :end => simple(:e)) do
|
||||
Ast::FunctionExpression.new(function_definition.name, parmeter_list, expressions)
|
||||
end
|
||||
|
||||
rule(:asignee => simple(:left) , :asigned => simple(:right) ) do
|
||||
Ast::AssignmentExpression.new(left , right )
|
||||
end
|
||||
|
||||
rule(l: simple(:l), o: simple(:o) , r: simple(:r)) do
|
||||
Ast::OperatorExpression.new( o.to_s.strip , l ,r)
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user