diff options
-rw-r--r-- | src/ChangeLog | 12 | ||||
-rw-r--r-- | src/utils/sexpr.H | 13 | ||||
-rw-r--r-- | src/utils/sexpr.cc | 33 |
3 files changed, 58 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2ce1b27a..cd2d23aa 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2010-09-11 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * utils/sexpr.H (Token::character): New token type. + (Character): New. + (Syntax::Visitor::visit): Overload for Character. + (Allocator::make_character): Declare. + (Parser::parse_character): Likewise. + * utils/sexpr.cc (operator<<) [Token::character]: Print data for + character token. + (Lexer::tokenize): Recognize a character literal. + (Parser::parse_character): Define. + 2010-09-07 Gabriel Dos Reis <gdr@cs.tamu.edu> * interp/c-util.boot (massageBackendCode): Remove conditional on diff --git a/src/utils/sexpr.H b/src/utils/sexpr.H index f7c9f766..e81fe096 100644 --- a/src/utils/sexpr.H +++ b/src/utils/sexpr.H @@ -71,6 +71,7 @@ namespace OpenAxiom { sharp_colon = OPENAXIOM_SEXPR_TOKEN2('#',':'), // "#:" digraph_end = OPENAXIOM_SEXPR_TOKEN2(256,256), integer, // integer literal + character, // character literal string, // string literal identifier, // plain identifier sharp_integer_equal, // anchor definition, #n=<form> @@ -136,6 +137,14 @@ namespace OpenAxiom { void accept(Visitor&) const; }; + // --------------- + // -- Character -- + // --------------- + struct Character : Atom { + explicit Character(const Token&); + void accept(Visitor&) const; + }; + // ------------ // -- String -- // ------------ @@ -259,6 +268,7 @@ namespace OpenAxiom { struct Syntax::Visitor { virtual void visit(const Atom&) = 0; virtual void visit(const Integer&); + virtual void visit(const Character&); virtual void visit(const String&); virtual void visit(const Symbol&); virtual void visit(const Reference&); @@ -329,6 +339,7 @@ namespace OpenAxiom { ~Allocator(); const Integer* make_integer(const Token&); + const Character* make_character(const Token&); const String* make_string(const Token&); const Symbol* make_symbol(const Token&, Symbol::Kind); const Reference* make_reference(const Token&, size_t); @@ -341,6 +352,7 @@ namespace OpenAxiom { private: UniqueAllocator<Integer> ints; + UniqueAllocator<Character> chars; UniqueAllocator<String> strs; UniqueAllocator<Symbol> syms; UniqueAllocator<Anchor> ancs; @@ -370,6 +382,7 @@ namespace OpenAxiom { std::vector<const Syntax*>& syns; const Symbol* parse_symbol(const Token*&, const Token*); + const Character* parse_character(const Token*&, const Token*); const Anchor* parse_anchor(const Token*&, const Token*); const Reference* parse_reference(const Token*&, const Token*); const Symbol* parse_uninterned(const Token*&, const Token*); diff --git a/src/utils/sexpr.cc b/src/utils/sexpr.cc index 4910f053..db822410 100644 --- a/src/utils/sexpr.cc +++ b/src/utils/sexpr.cc @@ -52,6 +52,7 @@ namespace OpenAxiom { case Token::sharp_apostrophe: os << "SHARP_APOSTROPHE"; break; case Token::sharp_colon: os << "SHARP_COLON"; break; case Token::integer: os << "INTEGER"; break; + case Token::character: os << "CHARACTER"; break; case Token::string: os << "STRING"; break; case Token::identifier: os << "IDENTIFIER"; break; case Token::sharp_integer_sharp: @@ -200,6 +201,12 @@ namespace OpenAxiom { t.lexeme = strings.intern(start, cur - start + 1); ++cur; } + else if (cur + 1 < end and cur[1] == '\\') { + start = cur += 2; + skip_to_word_boundary(cur, end); + t.type = Token::character; + t.lexeme = strings.intern(start, cur - start); + } else { skip_to_word_boundary(cur, end); t.lexeme = strings.intern(start, cur - start); @@ -263,6 +270,16 @@ namespace OpenAxiom { v.visit(*this); } + // --------------- + // -- Character -- + // --------------- + Character::Character(const Token& t) : Atom(t) { } + + void + Character::accept(Visitor& v) const { + v.visit(*this); + } + // ------------ // -- String -- // ------------ @@ -378,6 +395,11 @@ namespace OpenAxiom { } void + Syntax::Visitor::visit(const Character& c) { + visit(as<Atom>(c)); + } + + void Syntax::Visitor::visit(const String& s) { visit(as<Atom>(s)); } @@ -504,6 +526,14 @@ namespace OpenAxiom { return alloc.make_symbol(*cur++, kind); } + const Character* + Parser::parse_character(const Token*& cur, const Token* last) { + // NOTE: For the time being, accept only simple characters. + if (cur->lexeme->size() != 1) + parse_error("invalid literal character syntax"); + return alloc.make_character(*cur++); + } + // Parse an anchor definition of the form #n=<syntax> const Anchor* Parser::parse_anchor(const Token*& cur, const Token* last) { @@ -596,6 +626,9 @@ namespace OpenAxiom { switch (cur->type) { case Token::integer: return alloc.make_integer(*cur++); + + case Token::character: + return parse_character(cur, last); case Token::string: return alloc.make_string(*cur++); |