aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/utils/sexpr.H13
-rw-r--r--src/utils/sexpr.cc33
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++);