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
|
||||||
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
|
||||||
|
@ -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]') }
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
@ -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(: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
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user