Permalink
Browse files

Cleaned up the parser some more by moving more of the data-translatin…

…g code into match mixins. Also moved the escape sequences code out of Lupin::AST::String and into a match mixin to decouple the file format from the AST.
  • Loading branch information...
1 parent f995fd4 commit ce2527212ec49556277fa50cb65045f9a0f99718 @Twisol committed Dec 5, 2010
Showing with 69 additions and 44 deletions.
  1. +0 −27 lib/lupin/ast/literals.rb
  2. +1 −1 lib/lupin/ast/unary_ops.rb
  3. +53 −0 lib/lupin/parser/operators.rb
  4. +10 −16 lib/lupin/parser/parser.citrus
  5. +5 −0 spec/parser_spec.rb
View
27 lib/lupin/ast/literals.rb
@@ -17,33 +17,6 @@ def sexp
class String < Literal
def initialize (str)
- str.gsub! /\\(\d{1,3}|\D)/m do
- seq = $1
- case seq
- when 'a' then "\a"
- when 'b' then "\b"
- when 'f' then "\f"
- when 'n' then "\n"
- when 'r' then "\r"
- when 't' then "\t"
- when 'v' then "\v"
- when "\r" then "\n"
- when /\d{1,3}/ then seq.to_i.chr
- else seq
- end
- end
-
- super(str)
- end
-
- def bytecode (g)
- g.push_literal Lupin::Library::String.new(@value)
- end
- end
-
- class LongString < Literal
- def initialize (str)
- str = str[1..-1] if str[0,1] == "\n"
super(str)
end
View
2 lib/lupin/ast/unary_ops.rb
@@ -20,7 +20,7 @@ def bytecode (g)
end
def sexp
- [:"@-", @operand.sexp]
+ [:"-@", @operand.sexp]
end
end
View
53 lib/lupin/parser/operators.rb
@@ -37,4 +37,57 @@ def value
[self].concat(list.matches).map {|m| m.item.value}
end
end
+
+ module StringLiteral
+ def value
+ s = str.to_s
+ s.gsub! /\\(\d{1,3}|\D)/m do
+ seq = $1
+ case seq
+ when 'a' then "\a"
+ when 'b' then "\b"
+ when 'f' then "\f"
+ when 'n' then "\n"
+ when 'r' then "\r"
+ when 't' then "\t"
+ when 'v' then "\v"
+ when "\r" then "\n"
+ when /\d{1,3}/ then seq.to_i.chr
+ else seq
+ end
+ end
+
+ Lupin::AST::String.new(s)
+ end
+ end
+
+ module LongStringLiteral
+ def value
+ Lupin::AST::String.new(match(/\[(=*)\[\n?(.*?)\]\1\]/m)[2])
+ end
+ end
+
+ module HexLiteral
+ def value
+ Lupin::AST::Number.new(to_i(16))
+ end
+ end
+
+ module DecimalLiteral
+ def value
+ Lupin::AST::Number.new(base.value, exponent == '' ? 0 : exponent.value)
+ end
+ end
+
+ module TableLiteral
+ def value
+ Lupin::AST::Table.new(list == '' ? [] : list.value)
+ end
+ end
+
+ module Pair
+ def value
+ [k == '' ? Lupin::AST::Nil.new : k.value, v.value]
+ end
+ end
end
View
26 lib/lupin/parser/parser.citrus
@@ -184,9 +184,7 @@ grammar Lupin::Parser::Lua
### Table
rule table
- ( ('{' WS? fieldlist WS? '}') { Lupin::AST::Table.new(fieldlist.value) }
- | ('{' WS? '}') { Lupin::AST::Table.new }
- )
+ ('{' WS? list:(fieldlist|'') WS? '}') <Lupin::Parser::TableLiteral>
end
rule fieldlist
@@ -197,13 +195,10 @@ grammar Lupin::Parser::Lua
end
rule field
- ( ('[' WS? k:expression WS? ']' WS? '=' WS? v:expression)
- { [k.value, v.value] }
- | (k:identifier WS? '=' WS? v:expression)
- { [k.value, v.value] }
- | (v:expression '')
- { [Lupin::AST::Nil.new, v.value] }
- )
+ ( '[' WS? k:expression WS? ']' WS? '=' WS? v:expression
+ | k:identifier WS? '=' WS? v:expression
+ | k:'' v:expression
+ ) <Lupin::Parser::Pair>
end
rule fieldsep
@@ -212,9 +207,8 @@ grammar Lupin::Parser::Lua
### Number
rule number
- ( /0x[A-Fa-f0-9]+/ { Lupin::AST::Number.new(to_i(16)) }
- | (base exponent) { Lupin::AST::Number.new(base.value, exponent.value) }
- | (base '') { Lupin::AST::Number.new(base.value) }
+ ( /0x[A-Fa-f0-9]+/ <Lupin::Parser::HexLiteral>
+ | (base exponent:(exponent|'')) <Lupin::Parser::DecimalLiteral>
)
end
@@ -228,9 +222,9 @@ grammar Lupin::Parser::Lua
### String
rule string
- ( ("\"" s:/(\\.|[^\"\n])*/m "\"") { Lupin::AST::String.new(s.value) }
- | ('\'' s:/(\\.|[^\'\n])*/m '\'') { Lupin::AST::String.new(s.value) }
- | /\[(=*)\[.*?\]\1\]/m { Lupin::AST::LongString.new(match(/\[(=*)\[(.*?)\]\1\]/m)[2]) }
+ ( ("\"" str:/(\\.|[^\"\n])*/m "\"") <Lupin::Parser::StringLiteral>
+ | ('\'' str:/(\\.|[^\'\n])*/m '\'') <Lupin::Parser::StringLiteral>
+ | str: /\[(=*)\[.*?\]\1\]/m <Lupin::Parser::LongStringLiteral>
)
end
View
5 spec/parser_spec.rb
@@ -53,4 +53,9 @@ def check (type, text)
check(:expression, "1%2%3") { [:%, [:%, 1.0, 2.0], 3.0] }
check(:expression, "1^2^3") { [:**, 1.0, [:**, 2.0, 3.0]] }
end
+
+ it "matches unary operations" do
+ check(:expression, "--1") { [:"-@", [:"-@", 1.0]] }
+ check(:expression, "not not true") { [:not, [:not, true]] }
+ end
end

0 comments on commit ce25272

Please sign in to comment.