зеркало из https://github.com/mozilla/pjs.git
waugh, "..." isn't supported on windows. Added full icode map generated by the new perl script. Added a comment character to the assembler, and required newlines after instructions.
This commit is contained in:
Родитель
0f8daa3979
Коммит
1cb3536755
|
@ -144,13 +144,13 @@ main (int , char **)
|
|||
//testUInt32 (icp, "12123687213612873621873438754387934657834", 0);
|
||||
|
||||
string src =
|
||||
"some_label: \
|
||||
LOAD_STRING R1, 'hello' \
|
||||
CAST R2, R1, 'any' \
|
||||
SAVE_NAME 'x', R2 \
|
||||
LOAD_NAME R1, 'x' \
|
||||
LOAD_NAME R2, 'print' \
|
||||
CALL R3, R2, <NaR>, ('foo':R1) \
|
||||
"some_label:\n\
|
||||
LOAD_STRING R1, 'hello' ;test comment\n\
|
||||
CAST R2, R1, 'any';another test comment\n\
|
||||
SAVE_NAME 'x', R2\n\
|
||||
LOAD_NAME R1, 'x'\n\
|
||||
LOAD_NAME R2, 'print'\n\
|
||||
CALL R3, R2, <NaR>, ('foo':R1)\n\
|
||||
RETURN R3";
|
||||
|
||||
testParse (icp, src);
|
||||
|
|
|
@ -42,7 +42,12 @@ namespace ICodeASM {
|
|||
static char *keyword_binaryops[] = {"add", "subtract", "multiply", "divide",
|
||||
"remainder", "leftshift", "rightshift",
|
||||
"lessorequal", "equal", "identical", 0};
|
||||
|
||||
|
||||
#define IS_ALPHA(ch) ((ch >= 'a' && ch <= 'z') || \
|
||||
(ch >= 'A' && ch <= 'Z') || \
|
||||
(ch == '_'))
|
||||
#define IS_NUMBER(ch) (ch >= '0' && ch <= '9')
|
||||
|
||||
int cmp_nocase (const string& s1, string::const_iterator s2_begin,
|
||||
string::const_iterator s2_end)
|
||||
{
|
||||
|
@ -66,12 +71,12 @@ namespace ICodeASM {
|
|||
iter begin = source.begin();
|
||||
iter end = source.end();
|
||||
|
||||
while (begin != end)
|
||||
while (begin < end)
|
||||
{
|
||||
try
|
||||
{
|
||||
++statementNo;
|
||||
begin = ParseStatement (begin, end);
|
||||
begin = ParseNextStatement (begin, end);
|
||||
}
|
||||
catch (ICodeParseException *e)
|
||||
{
|
||||
|
@ -81,6 +86,9 @@ namespace ICodeASM {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (begin > end)
|
||||
NOT_REACHED ("Overran source buffer!");
|
||||
}
|
||||
|
||||
TokenLocation
|
||||
|
@ -88,75 +96,86 @@ namespace ICodeASM {
|
|||
{
|
||||
TokenLocation tl;
|
||||
iter curpos;
|
||||
bool inComment = false;
|
||||
|
||||
// tl.type = ttUndetermined;
|
||||
|
||||
for (curpos = begin; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
/* look past the whitespace */
|
||||
break;
|
||||
if (!inComment) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
/* look past the whitespace */
|
||||
break;
|
||||
|
||||
case ';':
|
||||
inComment = true;
|
||||
break;
|
||||
|
||||
case 'a'...'z':
|
||||
case 'A'...'Z':
|
||||
case '_':
|
||||
tl.estimate = teAlpha;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '0'...'9':
|
||||
tl.estimate = teNumeric;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '-':
|
||||
tl.estimate = teMinus;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '+':
|
||||
tl.estimate = tePlus;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ',':
|
||||
tl.estimate = teComma;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
tl.estimate = teString;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '<':
|
||||
tl.estimate = teNotARegister;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '(':
|
||||
tl.estimate = teOpenParen;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ')':
|
||||
tl.estimate = teCloseParen;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ':':
|
||||
tl.estimate = teColon;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
default:
|
||||
tl.estimate = teUnknown;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
case '\n':
|
||||
tl.estimate = teNewline;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '-':
|
||||
tl.estimate = teMinus;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '+':
|
||||
tl.estimate = tePlus;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ',':
|
||||
tl.estimate = teComma;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
tl.estimate = teString;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '<':
|
||||
tl.estimate = teNotARegister;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '(':
|
||||
tl.estimate = teOpenParen;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ')':
|
||||
tl.estimate = teCloseParen;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ':':
|
||||
tl.estimate = teColon;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
default:
|
||||
if (IS_ALPHA(*curpos)) {
|
||||
tl.estimate = teAlpha;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
} else if (IS_NUMBER(*curpos)) {
|
||||
tl.estimate = teNumeric;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
} else {
|
||||
tl.estimate = teUnknown;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
}
|
||||
}
|
||||
} else if (*curpos == '\n') {
|
||||
tl.estimate = teNewline;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,20 +195,11 @@ namespace ICodeASM {
|
|||
string *str = new string();
|
||||
|
||||
for (curpos = begin; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case 'a'...'z':
|
||||
case 'A'...'Z':
|
||||
case '0'...'9':
|
||||
case '_':
|
||||
*str += *curpos;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto scan_done;
|
||||
}
|
||||
if (IS_ALPHA(*curpos))
|
||||
*str += *curpos;
|
||||
else
|
||||
break;
|
||||
}
|
||||
scan_done:
|
||||
|
||||
*rval = str;
|
||||
return curpos;
|
||||
|
@ -250,17 +260,11 @@ namespace ICodeASM {
|
|||
int32 position = 0;
|
||||
|
||||
for (; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case '0'...'9':
|
||||
*rval += (*curpos - '0') * (1 / pow (10, ++position));
|
||||
break;
|
||||
|
||||
default:
|
||||
goto scan_done;
|
||||
}
|
||||
if (IS_NUMBER(*curpos))
|
||||
*rval += (*curpos - '0') * (1 / pow (10, ++position));
|
||||
else
|
||||
break;
|
||||
}
|
||||
scan_done:
|
||||
|
||||
*rval *= sign;
|
||||
|
||||
|
@ -424,18 +428,11 @@ namespace ICodeASM {
|
|||
iter curpos;
|
||||
|
||||
for (curpos = begin; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case '0'...'9':
|
||||
position++;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto scan_done;
|
||||
|
||||
}
|
||||
if (IS_NUMBER(*curpos))
|
||||
position++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
scan_done:
|
||||
|
||||
for (curpos = begin; position >= 0; --position)
|
||||
*rval += (*curpos++ - '0') * static_cast<uint32>(pow (10, position));
|
||||
|
@ -682,7 +679,8 @@ namespace ICodeASM {
|
|||
|
||||
fprintf (stderr, "parsing instruction %s\n", icodemap[icodeID].name);
|
||||
|
||||
/* add the node now, so the parse*operand functions can see it */
|
||||
/* add the node now, so the parse*operand functions can see it
|
||||
* (used for label calculations) */
|
||||
mStatementNodes.push_back (node);
|
||||
|
||||
# define CASE_TYPE(T, C, CTYPE) \
|
||||
|
@ -719,6 +717,8 @@ namespace ICodeASM {
|
|||
break;
|
||||
}
|
||||
if (i != 3 && icodemap[icodeID].otype[i + 1] != otNone) {
|
||||
/* if the instruction has more arguments, eat a comma and
|
||||
* locate the next token */
|
||||
TokenLocation tl = SeekTokenStart (curpos, end);
|
||||
if (tl.estimate != teComma)
|
||||
throw new ICodeParseException ("Expected comma");
|
||||
|
@ -729,18 +729,30 @@ namespace ICodeASM {
|
|||
|
||||
# undef CASE_TYPE
|
||||
|
||||
return curpos;
|
||||
TokenLocation tl = SeekTokenStart (curpos, end);
|
||||
if (tl.estimate != teNewline && tl.estimate != teEOF)
|
||||
throw new ICodeParseException ("Expected newline");
|
||||
|
||||
if (tl.estimate == teEOF)
|
||||
return tl.begin;
|
||||
else
|
||||
return tl.begin + 1;
|
||||
}
|
||||
|
||||
iter
|
||||
ICodeParser::ParseStatement (iter begin, iter end)
|
||||
ICodeParser::ParseNextStatement (iter begin, iter end)
|
||||
{
|
||||
bool isLabel = false;
|
||||
iter firstTokenEnd = end;
|
||||
TokenLocation tl = SeekTokenStart (begin, end);
|
||||
|
||||
if (tl.estimate == teNewline) {
|
||||
/* empty statement, do nothing */
|
||||
return tl.begin + 1;
|
||||
}
|
||||
|
||||
if (tl.estimate != teAlpha)
|
||||
throw new ICodeParseException ("Expected an alphanumeric token (like maybe an instruction or a label.)");
|
||||
throw new ICodeParseException ("Expected alphanumeric token");
|
||||
|
||||
for (iter curpos = tl.begin; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
|
@ -750,15 +762,11 @@ namespace ICodeASM {
|
|||
firstTokenEnd = ++curpos;
|
||||
goto scan_done;
|
||||
|
||||
case 'a'...'z':
|
||||
case 'A'...'Z':
|
||||
case '0'...'9':
|
||||
case '_':
|
||||
break;
|
||||
|
||||
default:
|
||||
firstTokenEnd = curpos;
|
||||
goto scan_done;
|
||||
if (!IS_ALPHA(*curpos)) {
|
||||
firstTokenEnd = curpos;
|
||||
goto scan_done;
|
||||
}
|
||||
}
|
||||
}
|
||||
scan_done:
|
||||
|
|
|
@ -54,6 +54,7 @@ namespace ICodeASM {
|
|||
teEOF,
|
||||
teIllegal,
|
||||
teMinus,
|
||||
teNewline,
|
||||
teNotARegister,
|
||||
teNumeric,
|
||||
teOpenParen,
|
||||
|
@ -176,7 +177,7 @@ namespace ICodeASM {
|
|||
|
||||
/* "high level" parse functions */
|
||||
iter ParseInstruction (uint icodeID, iter start, iter end);
|
||||
iter ParseStatement (iter begin, iter end);
|
||||
iter ParseNextStatement (iter begin, iter end);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -43,19 +43,85 @@
|
|||
namespace JavaScript {
|
||||
namespace ICodeASM {
|
||||
|
||||
static uint icodemap_size = 6;
|
||||
static uint icodemap_size = 72;
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
OperandType otype[4];
|
||||
} icodemap [] =
|
||||
{
|
||||
{"LOAD_STRING", {otRegister, otStringAtom}},
|
||||
{"LOAD_NAME", {otRegister, otStringAtom}},
|
||||
{"CAST", {otRegister, otRegister, otJSType}},
|
||||
{"SAVE_NAME", {otJSString, otRegister}},
|
||||
{"ADD", {otRegister, otRegister, otRegister}},
|
||||
{"AND", {otRegister, otRegister, otRegister}},
|
||||
{"BITNOT", {otRegister, otRegister}},
|
||||
{"BRANCH", {otLabel}},
|
||||
{"BRANCH_FALSE", {otLabel, otRegister}},
|
||||
{"BRANCH_INITIALIZED", {otLabel, otRegister}},
|
||||
{"BRANCH_TRUE", {otLabel, otRegister}},
|
||||
{"CALL", {otRegister, otRegister, otRegister, otArgumentList}},
|
||||
{"RETURN", {otRegister}}
|
||||
{"CAST", {otRegister, otRegister, otJSType}},
|
||||
{"COMPARE_EQ", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_GE", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_GT", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_IN", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_LE", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_LT", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_NE", {otRegister, otRegister, otRegister}},
|
||||
{"DEBUGGER", {otNone}},
|
||||
{"DELETE_PROP", {otRegister, otRegister, otStringAtom}},
|
||||
{"DIRECT_CALL", {otRegister, otJSFunction, otArgumentList}},
|
||||
{"DIVIDE", {otRegister, otRegister, otRegister}},
|
||||
{"ELEM_XCR", {otRegister, otRegister, otRegister, otDouble}},
|
||||
{"GENERIC_BINARY_OP", {otRegister, otBinaryOp, otRegister, otRegister}},
|
||||
{"GET_ELEMENT", {otRegister, otRegister, otRegister}},
|
||||
{"GET_METHOD", {otRegister, otRegister, otUInt32}},
|
||||
{"GET_PROP", {otRegister, otRegister, otStringAtom}},
|
||||
{"GET_SLOT", {otRegister, otRegister, otUInt32}},
|
||||
{"GET_STATIC", {otRegister, otJSClass, otUInt32}},
|
||||
{"INSTANCEOF", {otRegister, otRegister, otRegister}},
|
||||
{"JSR", {otLabel}},
|
||||
{"LOAD_BOOLEAN", {otRegister, otBool}},
|
||||
{"LOAD_IMMEDIATE", {otRegister, otDouble}},
|
||||
{"LOAD_NAME", {otRegister, otStringAtom}},
|
||||
{"LOAD_STRING", {otRegister, otJSString}},
|
||||
{"MOVE", {otRegister, otRegister}},
|
||||
{"MULTIPLY", {otRegister, otRegister, otRegister}},
|
||||
{"NAME_XCR", {otRegister, otStringAtom, otDouble}},
|
||||
{"NEGATE", {otRegister, otRegister}},
|
||||
{"NEW_ARRAY", {otRegister}},
|
||||
{"NEW_CLASS", {otRegister, otJSClass}},
|
||||
{"NEW_FUNCTION", {otRegister, otICodeModule}},
|
||||
{"NEW_OBJECT", {otRegister, otRegister}},
|
||||
{"NOP", {otNone}},
|
||||
{"NOT", {otRegister, otRegister}},
|
||||
{"OR", {otRegister, otRegister, otRegister}},
|
||||
{"POSATE", {otRegister, otRegister}},
|
||||
{"PROP_XCR", {otRegister, otRegister, otStringAtom, otDouble}},
|
||||
{"REMAINDER", {otRegister, otRegister, otRegister}},
|
||||
{"RETURN", {otRegister}},
|
||||
{"RETURN_VOID", {otNone}},
|
||||
{"RTS", {otNone}},
|
||||
{"SAVE_NAME", {otStringAtom, otRegister}},
|
||||
{"SET_ELEMENT", {otRegister, otRegister, otRegister}},
|
||||
{"SET_PROP", {otRegister, otStringAtom, otRegister}},
|
||||
{"SET_SLOT", {otRegister, otUInt32, otRegister}},
|
||||
{"SET_STATIC", {otJSClass, otUInt32, otRegister}},
|
||||
{"SHIFTLEFT", {otRegister, otRegister, otRegister}},
|
||||
{"SHIFTRIGHT", {otRegister, otRegister, otRegister}},
|
||||
{"SLOT_XCR", {otRegister, otRegister, otUInt32, otDouble}},
|
||||
{"STATIC_XCR", {otRegister, otJSClass, otUInt32, otDouble}},
|
||||
{"STRICT_EQ", {otRegister, otRegister, otRegister}},
|
||||
{"STRICT_NE", {otRegister, otRegister, otRegister}},
|
||||
{"SUBTRACT", {otRegister, otRegister, otRegister}},
|
||||
{"SUPER", {otRegister}},
|
||||
{"TEST", {otRegister, otRegister}},
|
||||
{"THROW", {otRegister}},
|
||||
{"TRYIN", {otLabel, otLabel}},
|
||||
{"TRYOUT", {otNone}},
|
||||
{"USHIFTRIGHT", {otRegister, otRegister, otRegister}},
|
||||
{"VAR_XCR", {otRegister, otRegister, otDouble}},
|
||||
{"WITHIN", {otRegister}},
|
||||
{"WITHOUT", {otNone}},
|
||||
{"XOR", {otRegister, otRegister, otRegister}},
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -144,13 +144,13 @@ main (int , char **)
|
|||
//testUInt32 (icp, "12123687213612873621873438754387934657834", 0);
|
||||
|
||||
string src =
|
||||
"some_label: \
|
||||
LOAD_STRING R1, 'hello' \
|
||||
CAST R2, R1, 'any' \
|
||||
SAVE_NAME 'x', R2 \
|
||||
LOAD_NAME R1, 'x' \
|
||||
LOAD_NAME R2, 'print' \
|
||||
CALL R3, R2, <NaR>, ('foo':R1) \
|
||||
"some_label:\n\
|
||||
LOAD_STRING R1, 'hello' ;test comment\n\
|
||||
CAST R2, R1, 'any';another test comment\n\
|
||||
SAVE_NAME 'x', R2\n\
|
||||
LOAD_NAME R1, 'x'\n\
|
||||
LOAD_NAME R2, 'print'\n\
|
||||
CALL R3, R2, <NaR>, ('foo':R1)\n\
|
||||
RETURN R3";
|
||||
|
||||
testParse (icp, src);
|
||||
|
|
|
@ -42,7 +42,12 @@ namespace ICodeASM {
|
|||
static char *keyword_binaryops[] = {"add", "subtract", "multiply", "divide",
|
||||
"remainder", "leftshift", "rightshift",
|
||||
"lessorequal", "equal", "identical", 0};
|
||||
|
||||
|
||||
#define IS_ALPHA(ch) ((ch >= 'a' && ch <= 'z') || \
|
||||
(ch >= 'A' && ch <= 'Z') || \
|
||||
(ch == '_'))
|
||||
#define IS_NUMBER(ch) (ch >= '0' && ch <= '9')
|
||||
|
||||
int cmp_nocase (const string& s1, string::const_iterator s2_begin,
|
||||
string::const_iterator s2_end)
|
||||
{
|
||||
|
@ -66,12 +71,12 @@ namespace ICodeASM {
|
|||
iter begin = source.begin();
|
||||
iter end = source.end();
|
||||
|
||||
while (begin != end)
|
||||
while (begin < end)
|
||||
{
|
||||
try
|
||||
{
|
||||
++statementNo;
|
||||
begin = ParseStatement (begin, end);
|
||||
begin = ParseNextStatement (begin, end);
|
||||
}
|
||||
catch (ICodeParseException *e)
|
||||
{
|
||||
|
@ -81,6 +86,9 @@ namespace ICodeASM {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (begin > end)
|
||||
NOT_REACHED ("Overran source buffer!");
|
||||
}
|
||||
|
||||
TokenLocation
|
||||
|
@ -88,75 +96,86 @@ namespace ICodeASM {
|
|||
{
|
||||
TokenLocation tl;
|
||||
iter curpos;
|
||||
bool inComment = false;
|
||||
|
||||
// tl.type = ttUndetermined;
|
||||
|
||||
for (curpos = begin; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
/* look past the whitespace */
|
||||
break;
|
||||
if (!inComment) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
/* look past the whitespace */
|
||||
break;
|
||||
|
||||
case ';':
|
||||
inComment = true;
|
||||
break;
|
||||
|
||||
case 'a'...'z':
|
||||
case 'A'...'Z':
|
||||
case '_':
|
||||
tl.estimate = teAlpha;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '0'...'9':
|
||||
tl.estimate = teNumeric;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '-':
|
||||
tl.estimate = teMinus;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '+':
|
||||
tl.estimate = tePlus;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ',':
|
||||
tl.estimate = teComma;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
tl.estimate = teString;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '<':
|
||||
tl.estimate = teNotARegister;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '(':
|
||||
tl.estimate = teOpenParen;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ')':
|
||||
tl.estimate = teCloseParen;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ':':
|
||||
tl.estimate = teColon;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
default:
|
||||
tl.estimate = teUnknown;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
case '\n':
|
||||
tl.estimate = teNewline;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '-':
|
||||
tl.estimate = teMinus;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '+':
|
||||
tl.estimate = tePlus;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ',':
|
||||
tl.estimate = teComma;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
tl.estimate = teString;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '<':
|
||||
tl.estimate = teNotARegister;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case '(':
|
||||
tl.estimate = teOpenParen;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ')':
|
||||
tl.estimate = teCloseParen;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
case ':':
|
||||
tl.estimate = teColon;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
|
||||
default:
|
||||
if (IS_ALPHA(*curpos)) {
|
||||
tl.estimate = teAlpha;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
} else if (IS_NUMBER(*curpos)) {
|
||||
tl.estimate = teNumeric;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
} else {
|
||||
tl.estimate = teUnknown;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
}
|
||||
}
|
||||
} else if (*curpos == '\n') {
|
||||
tl.estimate = teNewline;
|
||||
tl.begin = curpos;
|
||||
return tl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,20 +195,11 @@ namespace ICodeASM {
|
|||
string *str = new string();
|
||||
|
||||
for (curpos = begin; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case 'a'...'z':
|
||||
case 'A'...'Z':
|
||||
case '0'...'9':
|
||||
case '_':
|
||||
*str += *curpos;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto scan_done;
|
||||
}
|
||||
if (IS_ALPHA(*curpos))
|
||||
*str += *curpos;
|
||||
else
|
||||
break;
|
||||
}
|
||||
scan_done:
|
||||
|
||||
*rval = str;
|
||||
return curpos;
|
||||
|
@ -250,17 +260,11 @@ namespace ICodeASM {
|
|||
int32 position = 0;
|
||||
|
||||
for (; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case '0'...'9':
|
||||
*rval += (*curpos - '0') * (1 / pow (10, ++position));
|
||||
break;
|
||||
|
||||
default:
|
||||
goto scan_done;
|
||||
}
|
||||
if (IS_NUMBER(*curpos))
|
||||
*rval += (*curpos - '0') * (1 / pow (10, ++position));
|
||||
else
|
||||
break;
|
||||
}
|
||||
scan_done:
|
||||
|
||||
*rval *= sign;
|
||||
|
||||
|
@ -424,18 +428,11 @@ namespace ICodeASM {
|
|||
iter curpos;
|
||||
|
||||
for (curpos = begin; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
{
|
||||
case '0'...'9':
|
||||
position++;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto scan_done;
|
||||
|
||||
}
|
||||
if (IS_NUMBER(*curpos))
|
||||
position++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
scan_done:
|
||||
|
||||
for (curpos = begin; position >= 0; --position)
|
||||
*rval += (*curpos++ - '0') * static_cast<uint32>(pow (10, position));
|
||||
|
@ -682,7 +679,8 @@ namespace ICodeASM {
|
|||
|
||||
fprintf (stderr, "parsing instruction %s\n", icodemap[icodeID].name);
|
||||
|
||||
/* add the node now, so the parse*operand functions can see it */
|
||||
/* add the node now, so the parse*operand functions can see it
|
||||
* (used for label calculations) */
|
||||
mStatementNodes.push_back (node);
|
||||
|
||||
# define CASE_TYPE(T, C, CTYPE) \
|
||||
|
@ -719,6 +717,8 @@ namespace ICodeASM {
|
|||
break;
|
||||
}
|
||||
if (i != 3 && icodemap[icodeID].otype[i + 1] != otNone) {
|
||||
/* if the instruction has more arguments, eat a comma and
|
||||
* locate the next token */
|
||||
TokenLocation tl = SeekTokenStart (curpos, end);
|
||||
if (tl.estimate != teComma)
|
||||
throw new ICodeParseException ("Expected comma");
|
||||
|
@ -729,18 +729,30 @@ namespace ICodeASM {
|
|||
|
||||
# undef CASE_TYPE
|
||||
|
||||
return curpos;
|
||||
TokenLocation tl = SeekTokenStart (curpos, end);
|
||||
if (tl.estimate != teNewline && tl.estimate != teEOF)
|
||||
throw new ICodeParseException ("Expected newline");
|
||||
|
||||
if (tl.estimate == teEOF)
|
||||
return tl.begin;
|
||||
else
|
||||
return tl.begin + 1;
|
||||
}
|
||||
|
||||
iter
|
||||
ICodeParser::ParseStatement (iter begin, iter end)
|
||||
ICodeParser::ParseNextStatement (iter begin, iter end)
|
||||
{
|
||||
bool isLabel = false;
|
||||
iter firstTokenEnd = end;
|
||||
TokenLocation tl = SeekTokenStart (begin, end);
|
||||
|
||||
if (tl.estimate == teNewline) {
|
||||
/* empty statement, do nothing */
|
||||
return tl.begin + 1;
|
||||
}
|
||||
|
||||
if (tl.estimate != teAlpha)
|
||||
throw new ICodeParseException ("Expected an alphanumeric token (like maybe an instruction or a label.)");
|
||||
throw new ICodeParseException ("Expected alphanumeric token");
|
||||
|
||||
for (iter curpos = tl.begin; curpos < end; ++curpos) {
|
||||
switch (*curpos)
|
||||
|
@ -750,15 +762,11 @@ namespace ICodeASM {
|
|||
firstTokenEnd = ++curpos;
|
||||
goto scan_done;
|
||||
|
||||
case 'a'...'z':
|
||||
case 'A'...'Z':
|
||||
case '0'...'9':
|
||||
case '_':
|
||||
break;
|
||||
|
||||
default:
|
||||
firstTokenEnd = curpos;
|
||||
goto scan_done;
|
||||
if (!IS_ALPHA(*curpos)) {
|
||||
firstTokenEnd = curpos;
|
||||
goto scan_done;
|
||||
}
|
||||
}
|
||||
}
|
||||
scan_done:
|
||||
|
|
|
@ -54,6 +54,7 @@ namespace ICodeASM {
|
|||
teEOF,
|
||||
teIllegal,
|
||||
teMinus,
|
||||
teNewline,
|
||||
teNotARegister,
|
||||
teNumeric,
|
||||
teOpenParen,
|
||||
|
@ -176,7 +177,7 @@ namespace ICodeASM {
|
|||
|
||||
/* "high level" parse functions */
|
||||
iter ParseInstruction (uint icodeID, iter start, iter end);
|
||||
iter ParseStatement (iter begin, iter end);
|
||||
iter ParseNextStatement (iter begin, iter end);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -43,19 +43,85 @@
|
|||
namespace JavaScript {
|
||||
namespace ICodeASM {
|
||||
|
||||
static uint icodemap_size = 6;
|
||||
static uint icodemap_size = 72;
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
OperandType otype[4];
|
||||
} icodemap [] =
|
||||
{
|
||||
{"LOAD_STRING", {otRegister, otStringAtom}},
|
||||
{"LOAD_NAME", {otRegister, otStringAtom}},
|
||||
{"CAST", {otRegister, otRegister, otJSType}},
|
||||
{"SAVE_NAME", {otJSString, otRegister}},
|
||||
{"ADD", {otRegister, otRegister, otRegister}},
|
||||
{"AND", {otRegister, otRegister, otRegister}},
|
||||
{"BITNOT", {otRegister, otRegister}},
|
||||
{"BRANCH", {otLabel}},
|
||||
{"BRANCH_FALSE", {otLabel, otRegister}},
|
||||
{"BRANCH_INITIALIZED", {otLabel, otRegister}},
|
||||
{"BRANCH_TRUE", {otLabel, otRegister}},
|
||||
{"CALL", {otRegister, otRegister, otRegister, otArgumentList}},
|
||||
{"RETURN", {otRegister}}
|
||||
{"CAST", {otRegister, otRegister, otJSType}},
|
||||
{"COMPARE_EQ", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_GE", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_GT", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_IN", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_LE", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_LT", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_NE", {otRegister, otRegister, otRegister}},
|
||||
{"DEBUGGER", {otNone}},
|
||||
{"DELETE_PROP", {otRegister, otRegister, otStringAtom}},
|
||||
{"DIRECT_CALL", {otRegister, otJSFunction, otArgumentList}},
|
||||
{"DIVIDE", {otRegister, otRegister, otRegister}},
|
||||
{"ELEM_XCR", {otRegister, otRegister, otRegister, otDouble}},
|
||||
{"GENERIC_BINARY_OP", {otRegister, otBinaryOp, otRegister, otRegister}},
|
||||
{"GET_ELEMENT", {otRegister, otRegister, otRegister}},
|
||||
{"GET_METHOD", {otRegister, otRegister, otUInt32}},
|
||||
{"GET_PROP", {otRegister, otRegister, otStringAtom}},
|
||||
{"GET_SLOT", {otRegister, otRegister, otUInt32}},
|
||||
{"GET_STATIC", {otRegister, otJSClass, otUInt32}},
|
||||
{"INSTANCEOF", {otRegister, otRegister, otRegister}},
|
||||
{"JSR", {otLabel}},
|
||||
{"LOAD_BOOLEAN", {otRegister, otBool}},
|
||||
{"LOAD_IMMEDIATE", {otRegister, otDouble}},
|
||||
{"LOAD_NAME", {otRegister, otStringAtom}},
|
||||
{"LOAD_STRING", {otRegister, otJSString}},
|
||||
{"MOVE", {otRegister, otRegister}},
|
||||
{"MULTIPLY", {otRegister, otRegister, otRegister}},
|
||||
{"NAME_XCR", {otRegister, otStringAtom, otDouble}},
|
||||
{"NEGATE", {otRegister, otRegister}},
|
||||
{"NEW_ARRAY", {otRegister}},
|
||||
{"NEW_CLASS", {otRegister, otJSClass}},
|
||||
{"NEW_FUNCTION", {otRegister, otICodeModule}},
|
||||
{"NEW_OBJECT", {otRegister, otRegister}},
|
||||
{"NOP", {otNone}},
|
||||
{"NOT", {otRegister, otRegister}},
|
||||
{"OR", {otRegister, otRegister, otRegister}},
|
||||
{"POSATE", {otRegister, otRegister}},
|
||||
{"PROP_XCR", {otRegister, otRegister, otStringAtom, otDouble}},
|
||||
{"REMAINDER", {otRegister, otRegister, otRegister}},
|
||||
{"RETURN", {otRegister}},
|
||||
{"RETURN_VOID", {otNone}},
|
||||
{"RTS", {otNone}},
|
||||
{"SAVE_NAME", {otStringAtom, otRegister}},
|
||||
{"SET_ELEMENT", {otRegister, otRegister, otRegister}},
|
||||
{"SET_PROP", {otRegister, otStringAtom, otRegister}},
|
||||
{"SET_SLOT", {otRegister, otUInt32, otRegister}},
|
||||
{"SET_STATIC", {otJSClass, otUInt32, otRegister}},
|
||||
{"SHIFTLEFT", {otRegister, otRegister, otRegister}},
|
||||
{"SHIFTRIGHT", {otRegister, otRegister, otRegister}},
|
||||
{"SLOT_XCR", {otRegister, otRegister, otUInt32, otDouble}},
|
||||
{"STATIC_XCR", {otRegister, otJSClass, otUInt32, otDouble}},
|
||||
{"STRICT_EQ", {otRegister, otRegister, otRegister}},
|
||||
{"STRICT_NE", {otRegister, otRegister, otRegister}},
|
||||
{"SUBTRACT", {otRegister, otRegister, otRegister}},
|
||||
{"SUPER", {otRegister}},
|
||||
{"TEST", {otRegister, otRegister}},
|
||||
{"THROW", {otRegister}},
|
||||
{"TRYIN", {otLabel, otLabel}},
|
||||
{"TRYOUT", {otNone}},
|
||||
{"USHIFTRIGHT", {otRegister, otRegister, otRegister}},
|
||||
{"VAR_XCR", {otRegister, otRegister, otDouble}},
|
||||
{"WITHIN", {otRegister}},
|
||||
{"WITHOUT", {otNone}},
|
||||
{"XOR", {otRegister, otRegister, otRegister}},
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче