add a simple return, ie the normal kind, not with trailing statements

This commit is contained in:
Torsten Ruger 2014-05-27 16:33:24 +03:00
parent 21a53c6a7f
commit fbaf292bb6
7 changed files with 62 additions and 0 deletions

View File

@ -36,6 +36,7 @@ require_relative "basic_expressions"
require_relative "compound_expressions" require_relative "compound_expressions"
require_relative "if_expression" require_relative "if_expression"
require_relative "while_expression" require_relative "while_expression"
require_relative "return_expression"
require_relative "function_expression" require_relative "function_expression"
require_relative "operator_expressions" require_relative "operator_expressions"
require_relative "call_site_expression" require_relative "call_site_expression"

View File

@ -0,0 +1,24 @@
module Ast
class ReturnExpression < Expression
attr_reader :expression
def initialize expression
@expression = expression
end
def inspect
self.class.name + ".new(" + expression.inspect + " )"
end
def to_s
"return #{expression}\n"
end
def attributes
[:expression]
end
def compile context , into
expression_value = condition.compile(context , into)
puts "compiled return expression #{expression_value.inspect}"
return expression_value
end
end
end

View File

@ -6,6 +6,7 @@ This includes the parser and generated ast.
Parslet is really great in that it: Parslet is really great in that it:
- does not generate code but instean gives a clean dsl to define a grammar - does not generate code but instean gives a clean dsl to define a grammar
- uses ruby modules so one can split the grammars up - uses ruby modules so one can split the grammars up
- has support for binary operators with presedence and binding
- has a seperate tranform stage to generate an ast layer - has a seperate tranform stage to generate an ast layer
Especially the last point is great. Since it is seperate it does not clutter up the actual grammar. Especially the last point is great. Since it is seperate it does not clutter up the actual grammar.

View File

@ -13,5 +13,8 @@ module Parser
right_parenthesis >> keyword_do >> newline >> right_parenthesis >> keyword_do >> newline >>
expressions_end.as(:body) expressions_end.as(:body)
end end
rule(:simple_return) do
keyword_return >> (operator_expression|value_expression).as(:return_expression) >> eol
end
end end
end end

View File

@ -10,6 +10,7 @@ module Parser
rule(:keyword_false) { str('false').as(:false) >> space?} rule(:keyword_false) { str('false').as(:false) >> space?}
rule(:keyword_if) { str('if').as(:if) >> space? } rule(:keyword_if) { str('if').as(:if) >> space? }
rule(:keyword_rescue) { str('rescue').as(:rescue) >> space?} rule(:keyword_rescue) { str('rescue').as(:rescue) >> space?}
rule(:keyword_return) { str('return').as(:return) >> space?}
rule(:keyword_true) { str('true').as(:true) >> space?} rule(:keyword_true) { str('true').as(:true) >> space?}
rule(:keyword_nil) { str('nil').as(:nil) >> space?} rule(:keyword_nil) { str('nil').as(:nil) >> space?}
rule(:keyword_unless) { str('unless').as(:unless) >> space?} rule(:keyword_unless) { str('unless').as(:unless) >> space?}

View File

@ -36,6 +36,10 @@ module Parser
Ast::WhileExpression.new(while_cond, body) Ast::WhileExpression.new(while_cond, body)
end end
rule(:return => simple(:return) , :return_expression => simple(:return_expression))do
Ast::ReturnExpression.new(return_expression)
end
rule(:parmeter => simple(:parmeter)) { parmeter } rule(:parmeter => simple(:parmeter)) { parmeter }
rule(:parmeter_list => sequence(:parmeter_list)) { parmeter_list } rule(:parmeter_list => sequence(:parmeter_list)) { parmeter_list }

View File

@ -0,0 +1,28 @@
require_relative "helper"
class TestReturn < MiniTest::Test
# include the magic (setup and parse -> test method translation), see there
include ParserHelper
def test_return_int
@string_input = 'return 42'
@parse_output = {:return=>"return", :return_expression=>{:integer=>"42"}}
@transform_output = Ast::ReturnExpression.new(Ast::IntegerExpression.new(42) )
@parser = @parser.simple_return
end
def test_return_variable
@string_input = 'return foo'
@parse_output = {:return=>"return", :return_expression=>{:name=>"foo"}}
@transform_output = Ast::ReturnExpression.new(Ast::NameExpression.new("foo") )
@parser = @parser.simple_return
end
def test_return_string
@string_input = 'return "hello"'
@parse_output = {:return=>"return", :return_expression=>{:string=>[{:char=>"h"}, {:char=>"e"}, {:char=>"l"}, {:char=>"l"}, {:char=>"o"}]}}
@transform_output = Ast::ReturnExpression.new(Ast::StringExpression.new("hello") )
@parser = @parser.simple_return
end
end