splitting the parser up more
This commit is contained in:
parent
af1df1a104
commit
b266bb84ba
10
lib/parser/conditional.rb
Normal file
10
lib/parser/conditional.rb
Normal 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
|
@ -1,59 +1,30 @@
|
|||||||
require_relative "basic_types"
|
require_relative "basic_types"
|
||||||
require_relative "tokens"
|
require_relative "tokens"
|
||||||
require_relative "keywords"
|
require_relative "keywords"
|
||||||
|
require_relative "conditional"
|
||||||
|
require_relative "expression"
|
||||||
|
require_relative "function_call"
|
||||||
|
require_relative "function_definition"
|
||||||
|
|
||||||
module Parser
|
module Parser
|
||||||
|
|
||||||
# obviously a work in progress !!
|
# obviously a work in progress !!
|
||||||
# We "compose" the parser from bits, divide and hopefully conquer
|
# 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
|
class Crystal < Parslet::Parser
|
||||||
include BasicTypes
|
include BasicTypes
|
||||||
include Tokens
|
include Tokens
|
||||||
include Keywords
|
include Keywords
|
||||||
|
include FunctionCall
|
||||||
# a note about .maybe : .maybe is almost every respect the same as .repeat(0,1)
|
include FunctionDefinition
|
||||||
# so either 0, or 1, in other words maybe. Nice feature, but there are strings attached:
|
include Conditional
|
||||||
# a maybe removes the 0 a sequence (array) to a single (hash). Thus 2 transformations are needed
|
include Expression
|
||||||
# More work than the prettiness is worth, so only use .maybe on something that does not need capturing
|
|
||||||
|
|
||||||
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 }
|
rule(:root){ function_definition | expression | assignment | function_call }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
18
lib/parser/expression.rb
Normal file
18
lib/parser/expression.rb
Normal 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
|
16
lib/parser/function_call.rb
Normal file
16
lib/parser/function_call.rb
Normal 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
|
16
lib/parser/function_definition.rb
Normal file
16
lib/parser/function_definition.rb
Normal 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
|
@ -70,7 +70,7 @@ module Vm
|
|||||||
# rounding up to the next 4 (always adding one for zero pad)
|
# rounding up to the next 4 (always adding one for zero pad)
|
||||||
pad = ((length / 4 ) + 1 ) * 4 - length
|
pad = ((length / 4 ) + 1 ) * 4 - length
|
||||||
raise "#{pad} #{self}" unless pad >= 1
|
raise "#{pad} #{self}" unless pad >= 1
|
||||||
@string = str + "\x00" * pad
|
@value = str + "\x00" * pad
|
||||||
end
|
end
|
||||||
def string
|
def string
|
||||||
@value
|
@value
|
||||||
@ -82,12 +82,12 @@ module Vm
|
|||||||
|
|
||||||
# the strings length plus padding
|
# the strings length plus padding
|
||||||
def length
|
def length
|
||||||
@string.length
|
string.length
|
||||||
end
|
end
|
||||||
|
|
||||||
# just writing the string
|
# just writing the string
|
||||||
def assemble(io)
|
def assemble(io)
|
||||||
io << @string
|
io << string
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user