#include "Token.hpp"
#include "Serialize.hpp"
#include <iostream>
#include <errno.h>
// These must appear as sequential token numbers
string fm_reserved[22] = {
"break",
"case",
"catch",
"continue",
"dbstep",
"dbtrace",
"else",
"elseif",
"end",
"for",
"function",
"global",
"if",
"keyboard",
"otherwise",
"persistent",
"quit",
"retall",
"return",
"switch",
"try",
"while"
};
int fm_reserved_count = sizeof(fm_reserved)/sizeof(fm_reserved[0]);
Token::Token(byte tok, unsigned pos, string text) :
m_tok(tok), m_pos(pos), m_text(text) {
}
Token::Token() {
m_tok = TOK_INVALID;
}
bool Token::IsBinaryOperator() const {
return ((m_tok == '+') || (m_tok == '-') ||
(m_tok == '*') || (m_tok == '/') ||
(m_tok == '\\') || (m_tok == '^') ||
(m_tok == '>') || (m_tok == '<') ||
(m_tok == ':') || (m_tok == TOK_LE) ||
(m_tok == TOK_GE) || (m_tok == TOK_EQ) ||
(m_tok == TOK_NE) || (m_tok == TOK_SOR) ||
(m_tok == TOK_SAND) || (m_tok == TOK_DOTTIMES) ||
(m_tok == TOK_DOTRDIV) || (m_tok == TOK_DOTLDIV) ||
(m_tok == TOK_DOTPOWER) || (m_tok == '|') ||
(m_tok == '&'));
}
bool Token::IsUnaryOperator() const {
return ((m_tok == '+') || (m_tok == '-') || (m_tok == '~')
|| (m_tok == TOK_UNARY_MINUS) ||
(m_tok == TOK_UNARY_PLUS));
}
bool Token::IsRightAssociative() const {
return (m_tok == '^');
}
ostream& operator<<(ostream& o, const Token& b) {
o << TokenToString(b) << " (" << (b.Position() >> 16)
<< "," << (b.Position() & 0xffff) << ")\r\n";
return o;
}
string TokenToString(const Token& b) {
switch(b.Value()) {
case TOK_IDENT: return "(ident)"+b.Text();
case TOK_NUMBER: return b.Text();
case TOK_SPACE: return "space";
case TOK_STRING: return "(string)"+b.Text();
case TOK_KEYWORD: return "keyword";
case TOK_BREAK: return "break";
case TOK_CASE: return "case";
case TOK_CATCH: return "catch";
case TOK_CONTINUE: return "continue";
case TOK_DBSTEP: return "dbstep";
case TOK_ELSE: return "else";
case TOK_ELSEIF: return "elseif";
case TOK_END: return "end";
case TOK_FOR: return "for";
case TOK_FUNCTION: return "function";
case TOK_GLOBAL: return "global";
case TOK_IF: return "if";
case TOK_KEYBOARD: return "keyboard";
case TOK_OTHERWISE: return "otherwise";
case TOK_PERSISTENT: return "persistent";
case TOK_QUIT: return "quit";
case TOK_RETALL: return "retall";
case TOK_RETURN: return "return";
case TOK_SWITCH: return "switch";
case TOK_TRY: return "try";
case TOK_WHILE: return "while";
// Generated (synthetic) token;
case TOK_MULTI: return "multi";
case TOK_SPECIAL: return "special";
case TOK_VARIABLE: return "variable";
case TOK_DYN: return "dyn";
case TOK_BLOCK: return "block";
case TOK_EOF: return "eof";
case TOK_MATDEF: return "matdef";
case TOK_CELLDEF: return "celldef";
case TOK_PARENS: return "()";
case TOK_BRACES: return "{}";
case TOK_BRACKETS: return "[]";
case TOK_ROWDEF: return "row";
case TOK_UNARY_MINUS: return "u-";
case TOK_UNARY_PLUS: return "u+";
case TOK_EXPR: return "expr";
case TOK_DOTTIMES: return ".*";
case TOK_DOTRDIV: return "./";
case TOK_DOTLDIV: return ".\\";
case TOK_DOTPOWER: return ".^";
case TOK_DOTTRANSPOSE: return ".'";
case TOK_LE: return "<=";
case TOK_GE: return ">=";
case TOK_EQ: return "==";
case TOK_NE: return "~=";
case TOK_SOR: return "||";
case TOK_SAND: return "&&";
case TOK_QSTATEMENT: return "qstmnt";
case TOK_STATEMENT: return "stmnt";
case TOK_INTEGER: return "(int)" + b.Text();
case TOK_FLOAT: return "(float)" + b.Text();
case TOK_DOUBLE: return "(double)" + b.Text();
case TOK_COMPLEX: return "(complex)" + b.Text();
case TOK_DCOMPLEX: return "(dcomplex)" + b.Text();
case TOK_FUNCTION_DEFS: return "functions:";
case TOK_SCRIPT: return "script:";
case TOK_DBTRACE: return "dbtrace";
case TOK_ANONYMOUS_FUNC: return "anon func";
case TOK_NEST_FUNC: return "nest func";
}
return string(1,(char) b.Value());
}
void FreezeToken(const Token& a, Serialize *s) {
s->putByte(a.m_tok);
s->putInt(a.m_pos);
s->putString(a.m_text.c_str());
}
Token ThawToken(Serialize *s) {
Token a;
a.m_tok = s->getByte();
a.m_pos = s->getInt();
a.m_text = s->getString();
a.FillArray();
return a;
}
void Token::FillArray() {
Array retval;
switch(m_tok) {
case TOK_INTEGER:
long iv;
double fv;
iv = strtol(m_text.c_str(),NULL,10);
if ((errno == ERANGE) && ((iv == LONG_MAX) || (iv == LONG_MIN))) {
fv = strtod(m_text.c_str(),NULL);
retval = Array::doubleConstructor(fv);
} else {
retval = Array::int32Constructor((int32)iv);
}
break;
case TOK_FLOAT:
retval = Array::floatConstructor(atof(m_text.c_str()));
break;
case TOK_DOUBLE:
retval = Array::doubleConstructor(atof(m_text.c_str()));
break;
case TOK_COMPLEX:
retval = Array::complexConstructor(0,atof(m_text.c_str()));
break;
case TOK_DCOMPLEX:
retval = Array::dcomplexConstructor(0,atof(m_text.c_str()));
break;
case TOK_STRING:
retval = Array::stringConstructor(m_text);
break;
}
m_array = retval;
}
syntax highlighted by Code2HTML, v. 0.9.1