bytecode progress

master
Daniel Kolesa 2015-08-07 20:14:31 +01:00
parent c8b560d646
commit 861e3991ca
1 changed files with 82 additions and 80 deletions

View File

@ -949,7 +949,7 @@ struct GenState {
void gen_str(ostd::ConstCharRange word, bool macro = false) { void gen_str(ostd::ConstCharRange word, bool macro = false) {
if (word.size() <= 3 && !macro) { if (word.size() <= 3 && !macro) {
ostd::uint op = CODE_VALI | RET_STR; ostd::uint op = CODE_VALI | RET_STR;
for (ostd::Size i = 0; i < word.size(); ++i) for (ostd::Size i = 0; i < word.size(); ++i)
op |= ostd::uint(ostd::byte(word[i])) << ((i + 1) * 8); op |= ostd::uint(ostd::byte(word[i])) << ((i + 1) * 8);
code.push(op); code.push(op);
@ -971,6 +971,55 @@ struct GenState {
code.push(CODE_VALI | RET_STR); code.push(CODE_VALI | RET_STR);
} }
void gen_null() {
code.push(CODE_VALI | RET_NULL);
}
void gen_int(int i = 0) {
if (i >= -0x800000 && i <= 0x7FFFFF)
code.push(CODE_VALI | RET_INT | (i << 8));
else {
code.push(CODE_VAL | RET_INT);
code.push(i);
}
}
void gen_int(ostd::ConstCharRange word) {
gen_int(!word.empty() ? parseint(word.data()) : 0);
}
void gen_float(float f = 0.0f) {
if (int(f) == f && f >= -0x800000 && f <= 0x7FFFFF)
code.push(CODE_VALI | RET_FLOAT | (int(f) << 8));
else {
union {
float f;
ostd::uint u;
} c;
c.f = f;
code.push(CODE_VAL | RET_FLOAT);
code.push(c.u);
}
}
void gen_float(ostd::ConstCharRange word) {
gen_float(!word.empty() ? parsefloat(word.data()) : 0.0f);
}
void gen_ident(Ident *id) {
code.push(((id->index < MAX_ARGUMENTS) ? CODE_IDENTARG
: CODE_IDENT) |
(id->index << 8));
}
void gen_ident() {
gen_ident(cs.dummy);
}
void gen_ident(ostd::ConstCharRange word) {
gen_ident(cs.new_ident(word, IDF_UNKNOWN));
}
void gen_main(const char *p, int ret_type = VAL_ANY); void gen_main(const char *p, int ret_type = VAL_ANY);
}; };
@ -988,19 +1037,6 @@ static inline void compileunescapestring(GenState &gs, const char *&p, bool macr
if (*p == '\"') p++; if (*p == '\"') p++;
} }
static inline void compileint(GenState &gs, int i = 0) {
if (i >= -0x800000 && i <= 0x7FFFFF)
gs.code.push(CODE_VALI | RET_INT | (i << 8));
else {
gs.code.push(CODE_VAL | RET_INT);
gs.code.push(i);
}
}
static inline void compilenull(GenState &gs) {
gs.code.push(CODE_VALI | RET_NULL);
}
static ostd::uint emptyblock[VAL_ANY][2] = { static ostd::uint emptyblock[VAL_ANY][2] = {
{ CODE_START + 0x100, CODE_EXIT | RET_NULL }, { CODE_START + 0x100, CODE_EXIT | RET_NULL },
{ CODE_START + 0x100, CODE_EXIT | RET_INT }, { CODE_START + 0x100, CODE_EXIT | RET_INT },
@ -1029,40 +1065,6 @@ static inline const char *compileblock(GenState &gs, const char *p, int rettype
return p; return p;
} }
static inline void compileident(GenState &gs, Ident *id) {
gs.code.push((id->index < MAX_ARGUMENTS ? CODE_IDENTARG : CODE_IDENT) | (id->index << 8));
}
static inline void compileident(GenState &gs) {
compileident(gs, gs.cs.dummy);
}
static inline void compileident(GenState &gs, ostd::ConstCharRange word) {
compileident(gs, gs.cs.new_ident(word, IDF_UNKNOWN));
}
static inline void compileint(GenState &gs, ostd::ConstCharRange word) {
compileint(gs, word.size() ? parseint(word.data()) : 0);
}
static inline void compilefloat(GenState &gs, float f = 0.0f) {
if (int(f) == f && f >= -0x800000 && f <= 0x7FFFFF)
gs.code.push(CODE_VALI | RET_FLOAT | (int(f) << 8));
else {
union {
float f;
ostd::uint u;
} conv;
conv.f = f;
gs.code.push(CODE_VAL | RET_FLOAT);
gs.code.push(conv.u);
}
}
static inline void compilefloat(GenState &gs, ostd::ConstCharRange &word) {
compilefloat(gs, word.size() ? parsefloat(word.data()) : 0.0f);
}
static inline bool getbool(const char *s) { static inline bool getbool(const char *s) {
switch (s[0]) { switch (s[0]) {
case '+': case '+':
@ -1116,33 +1118,33 @@ static inline void compileval(GenState &gs, int wordtype, ostd::ConstCharRange w
switch (wordtype) { switch (wordtype) {
case VAL_CANY: case VAL_CANY:
if (word.size()) gs.gen_str(word, true); if (word.size()) gs.gen_str(word, true);
else compilenull(gs); else gs.gen_null();
break; break;
case VAL_CSTR: case VAL_CSTR:
gs.gen_str(word, true); gs.gen_str(word, true);
break; break;
case VAL_ANY: case VAL_ANY:
if (word.size()) gs.gen_str(word); if (word.size()) gs.gen_str(word);
else compilenull(gs); else gs.gen_null();
break; break;
case VAL_STR: case VAL_STR:
gs.gen_str(word); gs.gen_str(word);
break; break;
case VAL_FLOAT: case VAL_FLOAT:
compilefloat(gs, word); gs.gen_float(word);
break; break;
case VAL_INT: case VAL_INT:
compileint(gs, word); gs.gen_int(word);
break; break;
case VAL_COND: case VAL_COND:
if (word.size()) compileblock(gs, word.data()); if (word.size()) compileblock(gs, word.data());
else compilenull(gs); else gs.gen_null();
break; break;
case VAL_CODE: case VAL_CODE:
compileblock(gs, word.data()); compileblock(gs, word.data());
break; break;
case VAL_IDENT: case VAL_IDENT:
compileident(gs, word); gs.gen_ident(word);
break; break;
default: default:
break; break;
@ -1246,15 +1248,15 @@ lookupid:
numargs++; numargs++;
break; break;
case 'i': case 'i':
compileint(gs); gs.gen_int();
numargs++; numargs++;
break; break;
case 'b': case 'b':
compileint(gs, INT_MIN); gs.gen_int(INT_MIN);
numargs++; numargs++;
break; break;
case 'f': case 'f':
compilefloat(gs); gs.gen_float();
numargs++; numargs++;
break; break;
case 'F': case 'F':
@ -1264,7 +1266,7 @@ lookupid:
case 'E': case 'E':
case 'T': case 'T':
case 't': case 't':
compilenull(gs); gs.gen_null();
numargs++; numargs++;
break; break;
case 'e': case 'e':
@ -1272,15 +1274,15 @@ lookupid:
numargs++; numargs++;
break; break;
case 'r': case 'r':
compileident(gs); gs.gen_ident();
numargs++; numargs++;
break; break;
case '$': case '$':
compileident(gs, id); gs.gen_ident(id);
numargs++; numargs++;
break; break;
case 'N': case 'N':
compileint(gs, -1); gs.gen_int(-1);
numargs++; numargs++;
break; break;
case 'C': case 'C':
@ -1349,7 +1351,7 @@ invalid:
case VAL_CANY: case VAL_CANY:
case VAL_WORD: case VAL_WORD:
case VAL_COND: case VAL_COND:
compilenull(gs); gs.gen_null();
break; break;
default: default:
compileval(gs, ltype); compileval(gs, ltype);
@ -1498,7 +1500,7 @@ done:
p = compileblock(gs, start, RET_NULL, ']'); p = compileblock(gs, start, RET_NULL, ']');
return; return;
case VAL_IDENT: case VAL_IDENT:
compileident(gs, ostd::ConstCharRange(start, p - 1)); gs.gen_ident(ostd::ConstCharRange(start, p - 1));
return; return;
} }
switch (wordtype) { switch (wordtype) {
@ -1526,7 +1528,7 @@ done:
if (concs || p - 1 > start) gs.code.push(CODE_POP); if (concs || p - 1 > start) gs.code.push(CODE_POP);
break; break;
case VAL_COND: case VAL_COND:
if (!concs && p - 1 <= start) compilenull(gs); if (!concs && p - 1 <= start) gs.gen_null();
else gs.code.push(CODE_COND); else gs.code.push(CODE_COND);
break; break;
case VAL_CODE: case VAL_CODE:
@ -1534,7 +1536,7 @@ done:
else gs.code.push(CODE_COMPILE); else gs.code.push(CODE_COMPILE);
break; break;
case VAL_IDENT: case VAL_IDENT:
if (!concs && p - 1 <= start) compileident(gs); if (!concs && p - 1 <= start) gs.gen_ident();
else gs.code.push(CODE_IDENTU); else gs.code.push(CODE_IDENTU);
break; break;
case VAL_CSTR: case VAL_CSTR:
@ -1568,7 +1570,7 @@ static bool compilearg(GenState &gs, const char *&p, int wordtype, int prevargs,
case VAL_COND: { case VAL_COND: {
char *s = cutstring(p); char *s = cutstring(p);
if (s[0]) compileblock(gs, s); if (s[0]) compileblock(gs, s);
else compilenull(gs); else gs.gen_null();
delete[] s; delete[] s;
break; break;
} }
@ -1697,11 +1699,11 @@ static void compilestatements(GenState &gs, const char *&p, int rettype, int bra
gs.code.push((id->index < MAX_ARGUMENTS ? CODE_ALIASARG : CODE_ALIAS) | (id->index << 8)); gs.code.push((id->index < MAX_ARGUMENTS ? CODE_ALIASARG : CODE_ALIAS) | (id->index << 8));
goto endstatement; goto endstatement;
case ID_VAR: case ID_VAR:
if (!(more = compilearg(gs, p, VAL_INT, prevargs))) compileint(gs); if (!(more = compilearg(gs, p, VAL_INT, prevargs))) gs.gen_int();
gs.code.push(CODE_IVAR1 | (id->index << 8)); gs.code.push(CODE_IVAR1 | (id->index << 8));
goto endstatement; goto endstatement;
case ID_FVAR: case ID_FVAR:
if (!(more = compilearg(gs, p, VAL_FLOAT, prevargs))) compilefloat(gs); if (!(more = compilearg(gs, p, VAL_FLOAT, prevargs))) gs.gen_float();
gs.code.push(CODE_FVAR1 | (id->index << 8)); gs.code.push(CODE_FVAR1 | (id->index << 8));
goto endstatement; goto endstatement;
case ID_SVAR: case ID_SVAR:
@ -1733,7 +1735,7 @@ noid:
char *end = (char *)idname.data(); char *end = (char *)idname.data();
int val = int(strtoul(idname.data(), &end, 0)); int val = int(strtoul(idname.data(), &end, 0));
if (end < &idname[idname.size()]) gs.gen_str(idname, rettype == VAL_CANY); if (end < &idname[idname.size()]) gs.gen_str(idname, rettype == VAL_CANY);
else compileint(gs, val); else gs.gen_int(val);
break; break;
} }
default: default:
@ -1768,7 +1770,7 @@ noid:
if (more) more = compilearg(gs, p, VAL_INT, prevargs + numargs); if (more) more = compilearg(gs, p, VAL_INT, prevargs + numargs);
if (!more) { if (!more) {
if (rep) break; if (rep) break;
compileint(gs); gs.gen_int();
fakeargs++; fakeargs++;
} }
numargs++; numargs++;
@ -1777,7 +1779,7 @@ noid:
if (more) more = compilearg(gs, p, VAL_INT, prevargs + numargs); if (more) more = compilearg(gs, p, VAL_INT, prevargs + numargs);
if (!more) { if (!more) {
if (rep) break; if (rep) break;
compileint(gs, INT_MIN); gs.gen_int(INT_MIN);
fakeargs++; fakeargs++;
} }
numargs++; numargs++;
@ -1786,7 +1788,7 @@ noid:
if (more) more = compilearg(gs, p, VAL_FLOAT, prevargs + numargs); if (more) more = compilearg(gs, p, VAL_FLOAT, prevargs + numargs);
if (!more) { if (!more) {
if (rep) break; if (rep) break;
compilefloat(gs); gs.gen_float();
fakeargs++; fakeargs++;
} }
numargs++; numargs++;
@ -1805,7 +1807,7 @@ noid:
if (more) more = compilearg(gs, p, *fmt == 't' ? VAL_CANY : VAL_ANY, prevargs + numargs); if (more) more = compilearg(gs, p, *fmt == 't' ? VAL_CANY : VAL_ANY, prevargs + numargs);
if (!more) { if (!more) {
if (rep) break; if (rep) break;
compilenull(gs); gs.gen_null();
fakeargs++; fakeargs++;
} }
numargs++; numargs++;
@ -1814,7 +1816,7 @@ noid:
if (more) more = compilearg(gs, p, VAL_COND, prevargs + numargs); if (more) more = compilearg(gs, p, VAL_COND, prevargs + numargs);
if (!more) { if (!more) {
if (rep) break; if (rep) break;
compilenull(gs); gs.gen_null();
fakeargs++; fakeargs++;
} }
numargs++; numargs++;
@ -1832,17 +1834,17 @@ noid:
if (more) more = compilearg(gs, p, VAL_IDENT, prevargs + numargs); if (more) more = compilearg(gs, p, VAL_IDENT, prevargs + numargs);
if (!more) { if (!more) {
if (rep) break; if (rep) break;
compileident(gs); gs.gen_ident();
fakeargs++; fakeargs++;
} }
numargs++; numargs++;
break; break;
case '$': case '$':
compileident(gs, id); gs.gen_ident(id);
numargs++; numargs++;
break; break;
case 'N': case 'N':
compileint(gs, numargs - fakeargs); gs.gen_int(numargs - fakeargs);
numargs++; numargs++;
break; break;
case 'C': case 'C':
@ -2555,14 +2557,14 @@ static const ostd::uint *runcode(const ostd::uint *code, TaggedValue &result) {
case VAL_INT: case VAL_INT:
gs.code.reserve(8); gs.code.reserve(8);
gs.code.push(CODE_START); gs.code.push(CODE_START);
compileint(gs, arg.i); gs.gen_int(arg.i);
gs.code.push(CODE_RESULT); gs.code.push(CODE_RESULT);
gs.code.push(CODE_EXIT); gs.code.push(CODE_EXIT);
break; break;
case VAL_FLOAT: case VAL_FLOAT:
gs.code.reserve(8); gs.code.reserve(8);
gs.code.push(CODE_START); gs.code.push(CODE_START);
compilefloat(gs, arg.f); gs.gen_float(arg.f);
gs.code.push(CODE_RESULT); gs.code.push(CODE_RESULT);
gs.code.push(CODE_EXIT); gs.code.push(CODE_EXIT);
break; break;
@ -2576,7 +2578,7 @@ static const ostd::uint *runcode(const ostd::uint *code, TaggedValue &result) {
default: default:
gs.code.reserve(8); gs.code.reserve(8);
gs.code.push(CODE_START); gs.code.push(CODE_START);
compilenull(gs); gs.gen_null();
gs.code.push(CODE_RESULT); gs.code.push(CODE_RESULT);
gs.code.push(CODE_EXIT); gs.code.push(CODE_EXIT);
break; break;