aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2013-08-06 12:58:21 +0800
committerTeddy <ted.sybil@gmail.com>2013-08-06 12:58:21 +0800
commit033b938b22c7947992195e380fb2f7d1ca200f05 (patch)
treefd6628c9f376ee289d7bd6621fe4b8fc3d717ce4
parent9e76d377dad809f4aa3faa700883dbfc9b2fa769 (diff)
boolean and char are now supported
-rw-r--r--consts.cpp3
-rw-r--r--consts.h3
-rw-r--r--model.cpp31
-rw-r--r--model.h17
-rw-r--r--parser.cpp2
5 files changed, 54 insertions, 2 deletions
diff --git a/consts.cpp b/consts.cpp
index 51267a1..db2a4d5 100644
--- a/consts.cpp
+++ b/consts.cpp
@@ -11,5 +11,6 @@ const char *ERR_MSG[] = {
"Unexpected \")\"",
"Wrong type (expecting %s)",
"Internal Error !!! File a bug please!",
- "Illegal character in escape sequence: #\\%s"
+ "Illegal character in escape sequence: #\\%s",
+ "Unknown character name: %s"
};
diff --git a/consts.h b/consts.h
index cf07edb..4bfd6b7 100644
--- a/consts.h
+++ b/consts.h
@@ -12,7 +12,8 @@ enum ErrCode {
READ_ERR_UNEXPECTED_RIGHT_BRACKET,
RUN_ERR_WRONG_TYPE,
INT_ERR,
- PAR_ERR_ILLEGAL_CHAR_IN_ESC
+ PAR_ERR_ILLEGAL_CHAR_IN_ESC,
+ RUN_ERR_UNKNOWN_CHAR_NAME
};
extern const char *ERR_MSG[];
diff --git a/model.cpp b/model.cpp
index bb5b855..4a3c22a 100644
--- a/model.cpp
+++ b/model.cpp
@@ -169,6 +169,16 @@ bool BoolObj::is_true() { return val; }
string BoolObj::ext_repr() { return string(val ? "#t" : "#f"); }
+BoolObj *BoolObj::from_string(string repr) {
+ if (repr.length() != 2 || repr[0] != '#')
+ return NULL;
+ if (repr[1] == 't')
+ return new BoolObj(true);
+ else if (repr[1] == 'f')
+ return new BoolObj(false);
+ return NULL;
+}
+
NumObj::NumObj(NumLvl _level, bool _exactness) :
EvalObj(CLS_SIM_OBJ | CLS_NUM_OBJ), level(_level), exactness(_exactness) {}
@@ -178,6 +188,27 @@ StrObj::StrObj(string _str) : EvalObj(CLS_SIM_OBJ), str(_str) {}
string StrObj::ext_repr() { return str; }
+CharObj::CharObj(char _ch) : EvalObj(CLS_SIM_OBJ), ch(_ch) {}
+
+CharObj *CharObj::from_string(string repr) {
+ int len = repr.length();
+ if (len < 2) return NULL;
+ if (repr[0] != '#' || repr[1] != '\\') return NULL;
+ if (len == 3) return new CharObj(repr[2]);
+ string char_name = repr.substr(2, len - 2);
+ if (char_name == "newline") return new CharObj('\n');
+ if (char_name == "space") return new CharObj(' ');
+ throw TokenError(char_name, RUN_ERR_UNKNOWN_CHAR_NAME);
+}
+
+string CharObj::ext_repr() {
+ string val = "";
+ if (ch == ' ') val = "space";
+ else if (ch == '\n') val = "newline";
+ else val += ch;
+ return "#\\" + val;
+}
+
VecObj::VecObj() : EvalObj(CLS_SIM_OBJ) {}
void VecObj::resize(int new_size) {
diff --git a/model.h b/model.h
index 4dcdc59..0fcf5d3 100644
--- a/model.h
+++ b/model.h
@@ -331,6 +331,23 @@ class StrObj: public EvalObj {
string ext_repr();
};
+/** @class CharObj
+ * Character type support
+ */
+class CharObj: public EvalObj {
+ public:
+ char ch;
+
+ /** Construct a string object */
+ CharObj(char ch);
+ /** Try to construct an CharObj object
+ * @return NULL if failed
+ */
+ static CharObj *from_string(string repr);
+ string ext_repr();
+};
+
+
typedef vector<EvalObj*> EvalObjVec;
/**
* @class VecObj
diff --git a/parser.cpp b/parser.cpp
index cd9eacb..05806f1 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -117,6 +117,8 @@ ASTGenerator::ASTGenerator() {}
EvalObj *ASTGenerator::to_obj(const string &str) {
EvalObj *res = NULL;
+ if ((res = BoolObj::from_string(str))) return res;
+ if ((res = CharObj::from_string(str))) return res;
if ((res = IntNumObj::from_string(str))) return res;
if ((res = RatNumObj::from_string(str))) return res;
if ((res = RealNumObj::from_string(str))) return res;