a good stab at array anf hash constants

This commit is contained in:
Torsten Ruger
2014-05-12 21:36:38 +03:00
parent 25a7c3ea68
commit fdb5dd4f67
14 changed files with 126 additions and 24 deletions

View File

@ -0,0 +1,39 @@
module Ast
class ArrayExpression < Expression
attr_reader :values
def initialize vals
@values = vals
end
def inspect
self.class.name + ".new(" + values.to_s+ ")"
end
def compile context
to.do
end
def attributes
[:values]
end
end
class AssociationExpression < Expression
attr_reader :key , :value
def initialize key , value
@key , @value = key , value
end
def inspect
self.class.name + ".new(" + key.inspect + " , " + value.inspect + ")"
end
def compile context
to.do
end
def attributes
[:key , :value]
end
end
class HashExpression < ArrayExpression
def compile context
to.do
end
end
end

View File

@ -15,9 +15,6 @@ module Ast
def compile context
raise "abstract #{self}"
end
def inspectt
self.class.name + ".new(" + self.attributes.collect{|m| self.send(m).inspect }.join( ",") +")"
end
def attributes
raise "abstract #{self}"
end
@ -36,6 +33,7 @@ module Ast
end
require_relative "basic_expressions"
require_relative "compound_expressions"
require_relative "conditional_expression"
require_relative "while_expression"
require_relative "function_expression"

View File

@ -1,7 +1,5 @@
module Parser
# Basic types are numbers and strings
# later maybe arrays and hashes
# floats ?
module BasicTypes
include Parslet
# space really is just space. ruby is newline sensitive, so there is more whitespace footwork
@ -35,19 +33,10 @@ module Parser
nonquote.as(:char)
).repeat(1).as(:string) >> quote }
# rule(:string_special) { match['\0\t\n\r"\\\\'] }
# rule(:escaped_special) { str("\\") >> match['0tnr"\\\\'] }
#anything in double quotes
# rule(:string){
# double_quote >>
# ( escaped_special | string_special.absent? >> any ).repeat.as(:string) >>
# double_quote >> space?
# }
rule(:integer) { sign.maybe >> digit.repeat(1).as(:integer) >> space? }
rule(:float) { integer >> dot >> integer >>
(exponent >> sign.maybe >> digit.repeat(1,3)).maybe >> space?}
rule(:basic_type){ integer | name | string | float }
end
end

View File

@ -0,0 +1,20 @@
module Parser
# Compound types are Arrays and Hashes
module CompundTypes
include Parslet
rule(:array) do
left_bracket >>
( ((operator_expression|value_expression).as(:element) >> space? >>
(comma >> space? >> (operator_expression|value_expression).as(:element)).repeat(0)).repeat(0,1)).as(:array) >>
space? >> right_bracket
end
rule(:hash_pair) { basic_type.as(:argument) >> association >> (operator_expression|value_expression).as(:element) }
rule(:hash) { left_brace >> ((hash_pair.as(:hash_pair) >>
(comma >> space? >> hash_pair.as(:hash_pair)).repeat(0)).repeat(0,1)).as(:hash)>>
space? >> right_brace }
end
end

View File

@ -3,13 +3,13 @@ module Parser
include Parslet
rule(:conditional) do
keyword_if >>
(( (simple_expression|operator_expression).as(:conditional) ) |
left_parenthesis >> (operator_expression|simple_expression).as(:conditional) >> right_parenthesis) >>
(( (value_expression|operator_expression).as(:conditional) ) |
left_parenthesis >> (operator_expression|value_expression).as(:conditional) >> right_parenthesis) >>
newline >> expressions_else.as(:if_true) >> newline >> expressions_end.as(:if_false)
end
rule(:while_do) do
keyword_while >> left_parenthesis >> (operator_expression|simple_expression).as(:while_cond) >>
keyword_while >> left_parenthesis >> (operator_expression|value_expression).as(:while_cond) >>
right_parenthesis >> keyword_do >> newline >>
expressions_end.as(:body)
end

View File

@ -1,4 +1,5 @@
require_relative "basic_types"
require_relative "compound_types"
require_relative "tokens"
require_relative "keywords"
require_relative "control"
@ -19,6 +20,7 @@ module Parser
class Crystal < Parslet::Parser
include BasicTypes
include CompundTypes
include Tokens
include Keywords
include Control

View File

@ -2,7 +2,7 @@ module Parser
module Expression
include Parslet
rule(:simple_expression) { function_call | integer | string | name }
rule(:value_expression) { function_call | basic_type }
rule(:expression) { (while_do | conditional | operator_expression | function_call ) >> newline }

View File

@ -4,8 +4,8 @@ module Parser
rule(:argument_list) {
left_parenthesis >>
( (simple_expression.as(:argument) >> space? >>
(comma >> space? >> simple_expression.as(:argument)).repeat(0)).repeat(0,1)).as(:argument_list) >>
( (value_expression.as(:argument) >> space? >>
(comma >> space? >> value_expression.as(:argument)).repeat(0)).repeat(0,1)).as(:argument_list) >>
space? >> right_parenthesis
}

View File

@ -23,7 +23,7 @@ module Parser
#infix doing the heavy lifting here,
# is defined as an expressions and array of [atoms,priority,binding] triples
rule(:operator_expression) do infix_expression(simple_expression,
rule(:operator_expression) do infix_expression(value_expression,
[exponent, 120, :left] ,
[multiply, 120, :left] ,
[plus, 110, :left],

View File

@ -8,7 +8,10 @@ module Parser
rule(:right_parenthesis) { str(')') >> space? }
rule(:left_brace) { str('{') >> space? }
rule(:right_brace) { str('}') >> space? }
rule(:left_bracket) { str('[') >> space? }
rule(:right_bracket) { str(']') >> space? }
rule(:association) { str("=>") >> space? }
rule(:comma) { str(',') >> space? }
rule(:colon) { str(':') >> space? }
rule(:semicolon) { str(';') >> space? }

View File

@ -10,6 +10,12 @@ module Parser
rule(:integer => simple(:value)) { Ast::IntegerExpression.new(value.to_i) }
rule(:name => simple(:name)) { Ast::NameExpression.new(name.to_s) }
rule(:array => sequence(:array) ) { Ast::ArrayExpression.new(array) }
rule(:element => simple(:element)) { element }
rule(:hash => sequence(:hash) ) { Ast::HashExpression.new(hash) }
rule(:argument => simple(:argument) , :element => simple(:element)) { Ast::AssociationExpression.new(argument,element) }
rule(:hash_pair => simple(:hash_pair) ) { hash_pair }
rule(:argument => simple(:argument)) { argument }
rule(:argument_list => sequence(:argument_list)) { argument_list }