add lots of operators. Assignment becomes operator. fix the mess

This commit is contained in:
Torsten Ruger 2014-05-11 18:37:26 +03:00
parent 3974f2516d
commit cc5915135a
8 changed files with 85 additions and 52 deletions

View File

@ -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

View File

@ -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]') }

View File

@ -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

View File

@ -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

View File

@ -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_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

View File

@ -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

View File

@ -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

View File

@ -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