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
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 class OperatorExpression < Expression
attr_reader :operator, :left, :right attr_reader :operator, :left, :right
@ -62,6 +42,14 @@ module Ast
parent_locals = context.locals parent_locals = context.locals
context.locals = {} context.locals = {}
args = [] args = []
#assignemnt
value = @assigned.compile(context)
variable = Vm::Variable.new @assignee , :r0 , value
context.locals[@assignee] = variable
variable
params.each do |param| params.each do |param|
args << param.compile(context) # making the argument a local args << param.compile(context) # making the argument a local
end end

View File

@ -20,7 +20,7 @@ module Parser
rule(:double_quote){ str('"') } rule(:double_quote){ str('"') }
rule(:minus) { str('-') } rule(:minus) { str('-') }
rule(:plus) { str('+') } rule(:plus) { str('+') }
rule(:equal_sign) { str('=') >> space?}
rule(:sign) { plus | minus } rule(:sign) { plus | minus }
rule(:dot) { str('.') } rule(:dot) { str('.') }
rule(:digit) { match('[0-9]') } rule(:digit) { match('[0-9]') }

View File

@ -5,6 +5,7 @@ require_relative "conditional"
require_relative "expression" require_relative "expression"
require_relative "function_call" require_relative "function_call"
require_relative "function_definition" require_relative "function_definition"
require_relative "operators"
module Parser module Parser
@ -20,11 +21,12 @@ module Parser
include BasicTypes include BasicTypes
include Tokens include Tokens
include Keywords include Keywords
include FunctionCall
include FunctionDefinition
include Conditional include Conditional
include Expression 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
end end

View File

@ -2,21 +2,15 @@ module Parser
module Expression module Expression
include Parslet include Parslet
rule(:assignment) { name.as(:asignee) >> equal_sign >> expression.as(:asigned) }
rule(:simple_expression) { function_call | integer | string | name } rule(:simple_expression) { function_call | integer | string | name }
rule(:expression) { (conditional | simple_expression ) >> newline.maybe } rule(:expression) { (conditional | simple_expression ) >> newline.maybe }
def delimited_expressions( delimit ) 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 end
rule(:expressions_else) { delimited_expressions(keyword_else) } rule(:expressions_else) { delimited_expressions(keyword_else) }
rule(:expressions_end) { delimited_expressions(keyword_end) } rule(:expressions_end) { delimited_expressions(keyword_end) }
rule(:operator_expression) do
infix_expression(expression, [multiply, 2, :left], [plus, 1, :right])
end
end end
end end

View File

@ -1,15 +1,18 @@
module Parser module Parser
module Keywords module Keywords
include Parslet 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
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(:question_mark) { str('?') >> space? }
rule(:excamation_mark) { str('!') >> space? } rule(:excamation_mark) { str('!') >> space? }
rule(:multiply) { match['*/'] >> space? }
rule(:plus) { match['+-'] >> space? }
end end
end end

View File

@ -18,14 +18,14 @@ module Parser
Ast::FuncallExpression.new(function_call.name, argument_list) Ast::FuncallExpression.new(function_call.name, argument_list)
end end
rule(:conditional => simple(:conditional), rule(:if => simple(:if), :conditional => simple(:conditional),
:if_true => {:expressions => sequence(:if_true)}, :if_true => {:expressions => sequence(:if_true) , :else => simple(:else) },
:if_false => {:expressions => sequence(:if_false)}) do :if_false => {:expressions => sequence(:if_false) , :end => simple(:e) }) do
Ast::ConditionalExpression.new(conditional, if_true, if_false) Ast::ConditionalExpression.new(conditional, if_true, if_false)
end end
rule(:while => simple(:while), :while_cond => simple(:while_cond) , :do => simple(:do), 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) Ast::WhileExpression.new(while_cond, body)
end end
@ -34,14 +34,10 @@ module Parser
rule(:function_definition => simple(:function_definition), rule(:function_definition => simple(:function_definition),
:parmeter_list => sequence(:parmeter_list), :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) Ast::FunctionExpression.new(function_definition.name, parmeter_list, expressions)
end 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 rule(l: simple(:l), o: simple(:o) , r: simple(:r)) do
Ast::OperatorExpression.new( o.to_s.strip , l ,r) Ast::OperatorExpression.new( o.to_s.strip , l ,r)
end end