splitting the parser up more

This commit is contained in:
Torsten Ruger 2014-05-10 11:14:34 +03:00
parent af1df1a104
commit b266bb84ba
6 changed files with 76 additions and 45 deletions

10
lib/parser/conditional.rb Normal file
View File

@ -0,0 +1,10 @@
module Parser
module Conditional
include Parslet
rule(:conditional) {
keyword_if >> left_parenthesis >> expression.as(:conditional) >> right_parenthesis >> newline >>
delimited_expressions(keyword_else).as(:if_true) >>
delimited_expressions(keyword_end).as(:if_false)
}
end
end

View File

@ -1,59 +1,30 @@
require_relative "basic_types"
require_relative "tokens"
require_relative "keywords"
require_relative "conditional"
require_relative "expression"
require_relative "function_call"
require_relative "function_definition"
module Parser
# obviously a work in progress !!
# We "compose" the parser from bits, divide and hopefully conquer
# a note about .maybe : .maybe is almost every respect the same as .repeat(0,1)
# so either 0, or 1, in other words maybe. Nice feature, but there are strings attached:
# a maybe removes the 0 a sequence (array) to a single (hash). Thus 2 transformations are needed
# More work than the prettiness is worth, so only use .maybe on something that does not need capturing
class Crystal < Parslet::Parser
include BasicTypes
include Tokens
include Keywords
# a note about .maybe : .maybe is almost every respect the same as .repeat(0,1)
# so either 0, or 1, in other words maybe. Nice feature, but there are strings attached:
# a maybe removes the 0 a sequence (array) to a single (hash). Thus 2 transformations are needed
# More work than the prettiness is worth, so only use .maybe on something that does not need capturing
include FunctionCall
include FunctionDefinition
include Conditional
include Expression
rule(:argument_list) {
left_parenthesis >>
( (simple_expression.as(:argument) >> space? >>
(comma >> space? >> simple_expression.as(:argument)).repeat(0)).repeat(0,1)).as(:argument_list) >>
space? >> right_parenthesis
}
rule(:function_call) { name.as(:function_call) >> argument_list }
rule(:assignment) { name.as(:asignee) >> equal_sign >> expression.as(:asigned) }
#| (name >> space? >> equal_sign.absent?)
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
end
rule(:conditional) {
keyword_if >> left_parenthesis >> expression.as(:conditional) >> right_parenthesis >> newline >>
delimited_expressions(keyword_else).as(:if_true) >>
delimited_expressions(keyword_end).as(:if_false)
}
rule(:expressions_else) { delimited_expressions(keyword_else) }
rule(:expressions_end) { delimited_expressions(keyword_end) }
rule(:function_definition) {
keyword_def >> name.as(:function_definition) >> parmeter_list >> newline >> expressions_end
}
rule(:parmeter_list) {
left_parenthesis >>
((name.as(:parmeter) >> (comma >> name.as(:parmeter)).repeat(0)).repeat(0,1)).as(:parmeter_list) >>
right_parenthesis
}
rule(:root){ function_definition | expression | assignment | function_call }
end
end

18
lib/parser/expression.rb Normal file
View File

@ -0,0 +1,18 @@
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
end
rule(:expressions_else) { delimited_expressions(keyword_else) }
rule(:expressions_end) { delimited_expressions(keyword_end) }
end
end

View File

@ -0,0 +1,16 @@
module Parser
module FunctionCall
include Parslet
rule(:argument_list) {
left_parenthesis >>
( (simple_expression.as(:argument) >> space? >>
(comma >> space? >> simple_expression.as(:argument)).repeat(0)).repeat(0,1)).as(:argument_list) >>
space? >> right_parenthesis
}
rule(:function_call) { name.as(:function_call) >> argument_list }
end
end

View File

@ -0,0 +1,16 @@
module Parser
module FunctionDefinition
include Parslet
rule(:function_definition) {
keyword_def >> name.as(:function_definition) >> parmeter_list >> newline >> expressions_end
}
rule(:parmeter_list) {
left_parenthesis >>
((name.as(:parmeter) >> (comma >> name.as(:parmeter)).repeat(0)).repeat(0,1)).as(:parmeter_list) >>
right_parenthesis
}
end
end

View File

@ -70,7 +70,7 @@ module Vm
# rounding up to the next 4 (always adding one for zero pad)
pad = ((length / 4 ) + 1 ) * 4 - length
raise "#{pad} #{self}" unless pad >= 1
@string = str + "\x00" * pad
@value = str + "\x00" * pad
end
def string
@value
@ -82,12 +82,12 @@ module Vm
# the strings length plus padding
def length
@string.length
string.length
end
# just writing the string
def assemble(io)
io << @string
io << string
end
end
end