rewrite compilelookup
parent
416c6ba8fb
commit
c4d39caa61
193
src/cs_parser.cc
193
src/cs_parser.cc
|
@ -400,126 +400,173 @@ static bool compilearg(
|
||||||
parser_state &gs, int wordtype, charbuf *word = nullptr
|
parser_state &gs, int wordtype, charbuf *word = nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
static void compilelookup(parser_state &gs, int ltype) {
|
/* lookups that are invalid but not causing an error */
|
||||||
|
static void lookup_invalid(gen_state &gs, int ltype) {
|
||||||
|
switch (ltype) {
|
||||||
|
case VAL_POP:
|
||||||
|
break;
|
||||||
|
case VAL_NULL:
|
||||||
|
case VAL_ANY:
|
||||||
|
case VAL_WORD:
|
||||||
|
case VAL_COND:
|
||||||
|
gs.gen_val_null();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gs.gen_val(ltype);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* on success, handles non-value return types not handled by type mask */
|
||||||
|
static void lookup_done(gen_state &gs, int ltype) {
|
||||||
|
switch (ltype) {
|
||||||
|
case VAL_POP:
|
||||||
|
gs.gen_pop();
|
||||||
|
break;
|
||||||
|
case VAL_CODE:
|
||||||
|
gs.gen_compile();
|
||||||
|
break;
|
||||||
|
case VAL_COND:
|
||||||
|
gs.gen_compile(true);
|
||||||
|
break;
|
||||||
|
case VAL_IDENT:
|
||||||
|
gs.gen_ident_lookup();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parses $foo */
|
||||||
|
void parser_state::parse_lookup(int ltype) {
|
||||||
charbuf lookup{gs.ts};
|
charbuf lookup{gs.ts};
|
||||||
gs.next_char();
|
next_char(); /* skip $ */
|
||||||
switch (gs.current()) {
|
switch (current()) {
|
||||||
|
/* $(...), $[...] */
|
||||||
case '(':
|
case '(':
|
||||||
case '[':
|
case '[':
|
||||||
if (!compilearg(gs, VAL_STRING)) {
|
if (!compilearg(*this, VAL_STRING)) {
|
||||||
goto invalid;
|
lookup_invalid(gs, ltype);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
break;
|
gs.gen_lookup_ident(ltype);
|
||||||
|
lookup_done(gs, ltype);
|
||||||
|
return;
|
||||||
|
/* $$...; sub-lookup */
|
||||||
case '$':
|
case '$':
|
||||||
compilelookup(gs, VAL_STRING);
|
parse_lookup(VAL_STRING);
|
||||||
break;
|
gs.gen_lookup_ident(ltype);
|
||||||
|
lookup_done(gs, ltype);
|
||||||
|
return;
|
||||||
|
/* $"..."; like $foo but looser */
|
||||||
case '\"':
|
case '\"':
|
||||||
lookup = gs.get_str_dup();
|
lookup = get_str_dup();
|
||||||
lookup.push_back('\0');
|
lookup.push_back('\0');
|
||||||
goto lookupid;
|
goto lookup_id;
|
||||||
default: {
|
/* any other thing, presumably a valid name */
|
||||||
lookup.append(gs.get_word());
|
default:
|
||||||
if (lookup.empty()) goto invalid;
|
break;
|
||||||
|
}
|
||||||
|
lookup.append(get_word());
|
||||||
|
if (lookup.empty()) {
|
||||||
|
lookup_invalid(gs, ltype);
|
||||||
|
return;
|
||||||
|
}
|
||||||
lookup.push_back('\0');
|
lookup.push_back('\0');
|
||||||
lookupid:
|
lookup_id:
|
||||||
ident &id = gs.ts.istate->new_ident(
|
/* fetch an ident or prepare a fresh one */
|
||||||
*gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN
|
ident &id = ts.istate->new_ident(
|
||||||
|
*ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN
|
||||||
);
|
);
|
||||||
switch (id.get_type()) {
|
switch (id.get_type()) {
|
||||||
case ident_type::IVAR:
|
case ident_type::IVAR:
|
||||||
gs.gs.gen_lookup_ivar(id, ltype);
|
|
||||||
switch (ltype) {
|
switch (ltype) {
|
||||||
case VAL_POP:
|
|
||||||
break;
|
|
||||||
case VAL_CODE:
|
case VAL_CODE:
|
||||||
gs.gs.gen_lookup_ivar(id, ltype);
|
|
||||||
gs.gs.gen_compile();
|
|
||||||
break;
|
|
||||||
case VAL_IDENT:
|
case VAL_IDENT:
|
||||||
gs.gs.gen_lookup_ivar(id, ltype);
|
gs.gen_lookup_ivar(id, ltype);
|
||||||
gs.gs.gen_ident_lookup();
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
lookup_done(gs, ltype);
|
||||||
return;
|
return;
|
||||||
case ident_type::FVAR:
|
case ident_type::FVAR:
|
||||||
switch (ltype) {
|
switch (ltype) {
|
||||||
case VAL_POP:
|
|
||||||
break;
|
|
||||||
case VAL_CODE:
|
case VAL_CODE:
|
||||||
gs.gs.gen_lookup_fvar(id, ltype);
|
|
||||||
gs.gs.gen_compile();
|
|
||||||
break;
|
|
||||||
case VAL_IDENT:
|
case VAL_IDENT:
|
||||||
gs.gs.gen_lookup_fvar(id, ltype);
|
gs.gen_lookup_fvar(id, ltype);
|
||||||
gs.gs.gen_ident_lookup();
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
lookup_done(gs, ltype);
|
||||||
return;
|
return;
|
||||||
case ident_type::SVAR:
|
case ident_type::SVAR:
|
||||||
switch (ltype) {
|
switch (ltype) {
|
||||||
case VAL_POP:
|
case VAL_POP:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
gs.gs.gen_lookup_svar(id, ltype);
|
gs.gen_lookup_svar(id, ltype);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
goto done;
|
lookup_done(gs, ltype);
|
||||||
|
return;
|
||||||
case ident_type::ALIAS:
|
case ident_type::ALIAS:
|
||||||
switch (ltype) {
|
switch (ltype) {
|
||||||
case VAL_POP:
|
case VAL_POP:
|
||||||
return;
|
return;
|
||||||
case VAL_COND:
|
case VAL_COND:
|
||||||
gs.gs.gen_lookup_alias(id);
|
gs.gen_lookup_alias(id, ltype);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gs.gs.gen_lookup_alias(id, ltype, VAL_STRING);
|
gs.gen_lookup_alias(id, ltype, VAL_STRING);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
goto done;
|
lookup_done(gs, ltype);
|
||||||
|
return;
|
||||||
case ident_type::COMMAND: {
|
case ident_type::COMMAND: {
|
||||||
std::uint32_t comtype = BC_INST_COM, numargs = 0;
|
std::uint32_t comtype = BC_INST_COM, numargs = 0;
|
||||||
auto fmt = static_cast<command_impl &>(id).get_args();
|
auto fmt = static_cast<command_impl &>(id).get_args();
|
||||||
for (char c: fmt) {
|
for (char c: fmt) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 's':
|
case 's':
|
||||||
gs.gs.gen_val_string(std::string_view{});
|
gs.gen_val_string(std::string_view{});
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
gs.gs.gen_val_integer();
|
gs.gen_val_integer();
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
gs.gs.gen_val_integer(std::numeric_limits<integer_type>::min());
|
gs.gen_val_integer(
|
||||||
|
std::numeric_limits<integer_type>::min()
|
||||||
|
);
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
gs.gs.gen_val_float();
|
gs.gen_val_float();
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
gs.gs.gen_dup(VAL_FLOAT);
|
gs.gen_dup(VAL_FLOAT);
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
case 't':
|
case 't':
|
||||||
gs.gs.gen_val_null();
|
gs.gen_val_null();
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
gs.gs.gen_block();
|
gs.gen_block();
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
gs.gs.gen_val_ident();
|
gs.gen_val_ident();
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case '$':
|
case '$':
|
||||||
gs.gs.gen_val_ident(id);
|
gs.gen_val_ident(id);
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
gs.gs.gen_val_integer(-1);
|
gs.gen_val_integer(-1);
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
|
@ -535,55 +582,15 @@ lookupid:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gs.gs.gen_command_call(id, comtype, ltype, numargs);
|
gs.gen_command_call(id, comtype, ltype, numargs);
|
||||||
gs.gs.gen_push_result(ltype);
|
gs.gen_push_result(ltype);
|
||||||
goto done;
|
lookup_done(gs, ltype);
|
||||||
}
|
|
||||||
default:
|
|
||||||
goto invalid;
|
|
||||||
}
|
|
||||||
gs.gs.gen_val_string(lookup.str_term());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (ltype) {
|
|
||||||
case VAL_COND:
|
|
||||||
gs.gs.gen_lookup_ident();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
gs.gs.gen_lookup_ident(ltype);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
switch (ltype) {
|
|
||||||
case VAL_POP:
|
|
||||||
gs.gs.gen_pop();
|
|
||||||
break;
|
|
||||||
case VAL_CODE:
|
|
||||||
gs.gs.gen_compile();
|
|
||||||
break;
|
|
||||||
case VAL_COND:
|
|
||||||
gs.gs.gen_compile(true);
|
|
||||||
break;
|
|
||||||
case VAL_IDENT:
|
|
||||||
gs.gs.gen_ident_lookup();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
invalid:
|
}
|
||||||
switch (ltype) {
|
|
||||||
case VAL_POP:
|
|
||||||
break;
|
|
||||||
case VAL_NULL:
|
|
||||||
case VAL_ANY:
|
|
||||||
case VAL_WORD:
|
|
||||||
case VAL_COND:
|
|
||||||
gs.gs.gen_val_null();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
gs.gs.gen_val(ltype);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
lookup_invalid(gs, ltype);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compileblocksub(parser_state &gs) {
|
static bool compileblocksub(parser_state &gs) {
|
||||||
|
@ -815,7 +822,7 @@ static bool compilearg(
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case '$':
|
case '$':
|
||||||
compilelookup(gs, wordtype);
|
gs.parse_lookup(wordtype);
|
||||||
return true;
|
return true;
|
||||||
case '(': {
|
case '(': {
|
||||||
gs.next_char();
|
gs.next_char();
|
||||||
|
|
|
@ -67,6 +67,8 @@ struct parser_state {
|
||||||
char skip_until(char cf);
|
char skip_until(char cf);
|
||||||
|
|
||||||
void skip_comments();
|
void skip_comments();
|
||||||
|
|
||||||
|
void parse_lookup(int ltype);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace cubescript */
|
} /* namespace cubescript */
|
||||||
|
|
Loading…
Reference in New Issue