Compare commits
2 Commits
f8f063a68c
...
5819be7fa5
| Author | SHA1 | Date | |
|---|---|---|---|
| 5819be7fa5 | |||
| 013dbb9e5c |
@@ -579,7 +579,7 @@ static int on_fed_cnode_in_batch_mode (hak_t* hak, hak_cnode_t* obj)
|
||||
#if defined(USE_ISOCLINE)
|
||||
static int get_line (hak_t* hak, xtn_t* xtn, FILE* fp)
|
||||
{
|
||||
char* inp, * p;
|
||||
char* inp;
|
||||
static int inited = 0;
|
||||
|
||||
if (!inited)
|
||||
@@ -742,9 +742,13 @@ static int feed_loop (hak_t* hak, xtn_t* xtn, int verbose)
|
||||
}
|
||||
else
|
||||
{
|
||||
HAK_ASSERT(hak, hak_getbclen(hak) == 0);
|
||||
/* usually this part is reached if the input string is
|
||||
* one or more whilespaces and/or comments only */
|
||||
* one or more whilespaces and/or comments only.
|
||||
* ------------------------------------------------------
|
||||
* if the previous compiled code has not been cleared (e.g.
|
||||
* hcl_compile() ever called with HCL_COMPILE_CLEAR_CODE
|
||||
* or hcl_clearcode() explicitly called), hak_getbcllen(hak)
|
||||
* may still return a positive number greater than 0. */
|
||||
}
|
||||
show_prompt (hak, 0); /* show prompt after execution */
|
||||
}
|
||||
|
||||
@@ -135,6 +135,11 @@ hak_cnode_t* hak_makecnodedsymbol (hak_t* hak, int flags, const hak_loc_t* loc,
|
||||
return c;
|
||||
}
|
||||
|
||||
hak_cnode_t* hak_makecnodebinop (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok)
|
||||
{
|
||||
return hak_makecnode(hak, HAK_CNODE_BINOP, flags, loc, tok);
|
||||
}
|
||||
|
||||
hak_cnode_t* hak_makecnodestrlit (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok)
|
||||
{
|
||||
return hak_makecnode(hak, HAK_CNODE_STRLIT, flags, loc, tok);
|
||||
|
||||
+75
-58
@@ -71,26 +71,25 @@ enum
|
||||
|
||||
/* --------------------------------------------
|
||||
|
||||
fun plus(x y) {
|
||||
printf "plus %d %d\n" x y
|
||||
fun minus(x y) {
|
||||
printf "minus %d %d\n" x y
|
||||
- x y
|
||||
}
|
||||
+ x y
|
||||
}
|
||||
|
||||
(fun plus(x y)
|
||||
(printf "plus %d %d\n" x y)
|
||||
(fun minus(x y)
|
||||
(printf "minus %d %d\n" x y)
|
||||
(- x y)
|
||||
)
|
||||
(+ x y)
|
||||
)
|
||||
fun dummy(q) {
|
||||
printf "%s\n" q
|
||||
}
|
||||
|
||||
(fun dummy(q)
|
||||
(printf "%s\n" q)
|
||||
)
|
||||
plus 10 20 ## minus is now available after plus is executed
|
||||
minus 10 1
|
||||
|
||||
(plus 10 20)
|
||||
<---- minus is now available
|
||||
(minus 10 1)
|
||||
literals -->
|
||||
//
|
||||
// characeter 'A'
|
||||
// character 'A'
|
||||
// "string"
|
||||
// B"byte string" <-- not yet implemented
|
||||
// array ---> #[ ] or [ ] ? constant or not? dynamic???
|
||||
@@ -459,7 +458,7 @@ HAK_INFO6(hak, "FOUND CLASS VAR [%.*js]...[%.*js]................ ===> ctx_offse
|
||||
/* this condition indicates that the current function level contains a class defintion
|
||||
* and this variable is looked up inside the class defintion */
|
||||
HAK_INFO2(hak, "CLASS NAMED VAR [%.*js]\n", name->len, name->ptr);
|
||||
vi->type = VAR_CLASS;//_NAMED; // TODO: create VAR_CLASS_NAMED???
|
||||
vi->type = VAR_CLASS;/*_NAMED;*/ // TODO: create VAR_CLASS_NAMED???
|
||||
vi->ctx_offset = 0;
|
||||
vi->index_in_ctx = 0;
|
||||
}
|
||||
@@ -1546,7 +1545,7 @@ static int collect_vardcl_for_class (hak_t* hak, hak_cnode_t* obj, hak_cnode_t**
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!HAK_CNODE_IS_SYMBOL(var) || HAK_CNODE_IS_SYMBOL_BINOP(var)) goto synerr_varname;
|
||||
if (!HAK_CNODE_IS_SYMBOL(var) /*|| HAK_CNODE_IS_SYMBOL_BINOP(var)*/) goto synerr_varname;
|
||||
|
||||
checkpoint = hak->c->tv.s.len;
|
||||
n = add_temporary_variable(hak, var, tv_slen_saved, desc[enclosed], HAK_NULL);
|
||||
@@ -1790,7 +1789,9 @@ enum
|
||||
COP_EMIT_POP_INTO_CONS_CDR,
|
||||
|
||||
COP_EMIT_FUN,
|
||||
#if defined(USE_KW_PLUS)
|
||||
COP_EMIT_PLUS,
|
||||
#endif
|
||||
COP_EMIT_POP_STACKTOP,
|
||||
COP_EMIT_RETURN,
|
||||
COP_EMIT_SET,
|
||||
@@ -2004,6 +2005,7 @@ static HAK_INLINE int compile_or_p2 (hak_t* hak)
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if defined(USE_KW_PLUS)
|
||||
/* EXPERIMENT WITH BINOP */
|
||||
static int compile_plus (hak_t* hak, hak_cnode_t* src)
|
||||
{
|
||||
@@ -2068,6 +2070,7 @@ static HAK_INLINE int emit_plus (hak_t* hak)
|
||||
POP_CFRAME(hak);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
@@ -2819,7 +2822,7 @@ static int compile_class (hak_t* hak, hak_cnode_t* src)
|
||||
check_class_name:
|
||||
if (HAK_CNODE_IS_FOR_DATA_SIMPLE(tmp) || HAK_CNODE_IS_FOR_LANG(tmp))
|
||||
{
|
||||
if (!HAK_CNODE_IS_SYMBOL_IDENT(tmp))
|
||||
if (!HAK_CNODE_IS_SYMBOL(tmp))
|
||||
{
|
||||
hak_setsynerrbfmt(
|
||||
hak, HAK_SYNERR_CLASS, HAK_CNODE_GET_LOC(tmp), HAK_NULL,
|
||||
@@ -3295,7 +3298,7 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
||||
tmp = HAK_CNODE_CONS_CAR(next);
|
||||
}
|
||||
|
||||
if (HAK_CNODE_IS_SYMBOL(tmp))
|
||||
if (HAK_CNODE_IS_SYMBOL(tmp) || HAK_CNODE_IS_BINOP(tmp))
|
||||
{
|
||||
/* 'fun' followed by name */
|
||||
fun_got_name:
|
||||
@@ -3332,7 +3335,7 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
||||
}
|
||||
|
||||
tmp = HAK_CNODE_CONS_CAR(next);
|
||||
if (!HAK_CNODE_IS_SYMBOL(tmp))
|
||||
if (!HAK_CNODE_IS_SYMBOL(tmp) && !HAK_CNODE_IS_BINOP(tmp))
|
||||
{
|
||||
hak_setsynerrbfmt(
|
||||
hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(tmp), HAK_NULL,
|
||||
@@ -3543,7 +3546,7 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
||||
|
||||
if (in_ret_args)
|
||||
{
|
||||
if (!HAK_CNODE_IS_SYMBOL_IDENT(arg))
|
||||
if (!HAK_CNODE_IS_SYMBOL(arg))
|
||||
{
|
||||
/* in 'fun x (x :: 20) { }', '20' is not a valid return variable name.
|
||||
* in 'fun x (x :: if) { }', 'if' is not a valid return variable name. */
|
||||
@@ -3586,7 +3589,7 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
||||
{
|
||||
va = 1;
|
||||
}
|
||||
else if (!HAK_CNODE_IS_SYMBOL_IDENT(arg))
|
||||
else if (!HAK_CNODE_IS_SYMBOL(arg))
|
||||
{
|
||||
hak_setsynerrbfmt(
|
||||
hak, HAK_SYNERR_ARGNAME, HAK_CNODE_GET_LOC(arg), HAK_NULL,
|
||||
@@ -3615,6 +3618,18 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
||||
while (1);
|
||||
}
|
||||
|
||||
if ((fun_type & 0xFF) == FUN_IM && fun_name && HAK_CNODE_IS_BINOP(fun_name) && (is_in_class_init_scope(hak) || class_name) && nargs != 1)
|
||||
{
|
||||
hak_setsynerrbfmt(
|
||||
hak, HAK_SYNERR_ARGCOUNT, HAK_CNODE_GET_LOC(arg_list), HAK_NULL,
|
||||
"only one argument expected for '%.*js%hs%.*js'",
|
||||
(class_name? HAK_CNODE_GET_TOKLEN(class_name): 0),
|
||||
(class_name? HAK_CNODE_GET_TOKPTR(class_name): HAK_NULL),
|
||||
(class_name? ":": ""),
|
||||
HAK_CNODE_GET_TOKLEN(fun_name), HAK_CNODE_GET_TOKPTR(fun_name));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nargs > MAX_CODE_NBLKARGS) /*TODO: change this limit to max call argument count */
|
||||
{
|
||||
/* while an integer object is pused to indicate the number of
|
||||
@@ -3860,7 +3875,7 @@ static int compile_var (hak_t* hak, hak_cnode_t* src)
|
||||
tmp = HAK_CNODE_CONS_CAR(next);
|
||||
}
|
||||
|
||||
if (HAK_CNODE_IS_SYMBOL_IDENT(tmp))
|
||||
if (HAK_CNODE_IS_SYMBOL(tmp))
|
||||
{
|
||||
unsigned int var_type = VAR_INST;
|
||||
|
||||
@@ -3901,7 +3916,7 @@ static int compile_var (hak_t* hak, hak_cnode_t* src)
|
||||
next = HAK_CNODE_CONS_CDR(next);
|
||||
if (!next) break;
|
||||
tmp = HAK_CNODE_CONS_CAR(next);
|
||||
if (!HAK_CNODE_IS_SYMBOL_IDENT(tmp)) goto not_ident;
|
||||
if (!HAK_CNODE_IS_SYMBOL(tmp)) goto not_ident;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -4136,7 +4151,7 @@ static int compile_set_r (hak_t* hak, hak_cnode_t* src)
|
||||
do
|
||||
{
|
||||
var = HAK_CNODE_CONS_CAR(obj);
|
||||
if (!HAK_CNODE_IS_SYMBOL(var)) /* TODO: should this be HAK_CNODE_IS_SYMBOL(var)?? */
|
||||
if (!HAK_CNODE_IS_SYMBOL(var))
|
||||
{
|
||||
if (nvars > 0) break;
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_VARNAME, HAK_CNODE_GET_LOC(var), HAK_CNODE_GET_TOK(var), "variable name not symbol in %.*js", HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd));
|
||||
@@ -4883,9 +4898,11 @@ static int compile_cons_xlist_expression (hak_t* hak, hak_cnode_t* obj, int nret
|
||||
if (compile_or(hak, obj) <= -1) return -1;
|
||||
goto done;
|
||||
|
||||
#if defined(USE_KW_PLUS)
|
||||
case HAK_CNODE_PLUS:
|
||||
if (compile_plus(hak, obj) <= -1) return -1;
|
||||
goto done;
|
||||
#endif
|
||||
|
||||
case HAK_CNODE_SET:
|
||||
if (compile_set(hak, obj) <= -1) return -1;
|
||||
@@ -4896,7 +4913,9 @@ static int compile_cons_xlist_expression (hak_t* hak, hak_cnode_t* obj, int nret
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (HAK_CNODE_IS_SYMBOL(car) || HAK_CNODE_IS_DSYMBOL(car) ||
|
||||
if (HAK_CNODE_IS_SYMBOL(car) || HAK_CNODE_IS_DSYMBOL(car) || HAK_CNODE_IS_BINOP(car) ||
|
||||
HAK_CNODE_IS_STRLIT(car) || /* this condition to represent an external program TODO: change this to a dedicated cnode */
|
||||
HAK_CNODE_IS_SYMLIT(car) || /* this condition to represent an external program TODO: change this to a dedicated cnode */
|
||||
HAK_CNODE_IS_CONS_CONCODED(car, HAK_CONCODE_XLIST) ||
|
||||
HAK_CNODE_IS_CONS_CONCODED(car, HAK_CONCODE_MLIST) ||
|
||||
HAK_CNODE_IS_CONS_CONCODED(car, HAK_CONCODE_BLIST) ||
|
||||
@@ -4947,7 +4966,7 @@ static int compile_cons_xlist_expression (hak_t* hak, hak_cnode_t* obj, int nret
|
||||
}
|
||||
}
|
||||
|
||||
if (HAK_CNODE_IS_SYMBOL(car) || HAK_CNODE_IS_DSYMBOL(car))
|
||||
if (HAK_CNODE_IS_SYMBOL(car) || HAK_CNODE_IS_DSYMBOL(car) || HAK_CNODE_IS_BINOP(car))
|
||||
{
|
||||
hak_oop_cons_t sdc;
|
||||
|
||||
@@ -5038,14 +5057,34 @@ static int compile_cons_mlist_expression (hak_t* hak, hak_cnode_t* obj, hak_ooi_
|
||||
return -1;
|
||||
}
|
||||
car = HAK_CNODE_CONS_CAR(cdr);
|
||||
if (HAK_CNODE_IS_SYMBOL(car))
|
||||
if (HAK_CNODE_IS_SYMBOL(car) || HAK_CNODE_IS_BINOP(car))
|
||||
{
|
||||
/* do not resolve the message itself to an associated value.
|
||||
* treat it as if it's a literal.
|
||||
* the actual message sending can be written with a symbol
|
||||
* as well as a symbol literal in that sense.
|
||||
*
|
||||
* For this class definition
|
||||
* class X { fun[#ci] new() {} }
|
||||
* X:new is equivalent to X:#new
|
||||
*
|
||||
* If the method is a binop selector,
|
||||
* class X { fun[#ci] +(a) {} } ## one argument is guaranteed by the reader
|
||||
* the followings are equivalent.
|
||||
* X + 20
|
||||
* X:#+ 20
|
||||
*/
|
||||
PUSH_CFRAME(hak, COP_EMIT_PUSH_SYMBOL, car);
|
||||
}
|
||||
else if (HAK_CNODE_IS_SYMLIT(car) || HAK_CNODE_IS_STRLIT(car))
|
||||
{
|
||||
PUSH_CFRAME(hak, COP_COMPILE_OBJECT, car);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: more sanity check on what can be used as a method */
|
||||
PUSH_CFRAME(hak, COP_COMPILE_OBJECT, car);
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_MESSAGE, HAK_CNODE_GET_LOC(car), HAK_NULL,
|
||||
"invalid message '%.*js'", HAK_CNODE_GET_TOKLEN(car), HAK_CNODE_GET_TOKPTR(car));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* compile <operand1> ... etc */
|
||||
@@ -5071,31 +5110,6 @@ static int compile_cons_mlist_expression (hak_t* hak, hak_cnode_t* obj, hak_ooi_
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (HAK_CNODE_IS_SYMBOL(car) || HAK_CNODE_IS_DSYMBOL(car))
|
||||
{
|
||||
hak_oop_cons_t sdc;
|
||||
|
||||
/* only symbols are added to the system dictionary.
|
||||
* perform this lookup only if car is a symbol */
|
||||
sdc = hak_lookupsysdicforsymbol_noseterr(hak, HAK_CNODE_GET_TOK(car));
|
||||
if (sdc)
|
||||
{
|
||||
hak_oop_word_t sdv;
|
||||
sdv = (hak_oop_word_t)HAK_CONS_CDR(sdc);
|
||||
if (HAK_IS_PRIM(hak, sdv))
|
||||
{
|
||||
if (nargs < sdv->slot[1] || nargs > sdv->slot[2])
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_ARGCOUNT, HAK_CNODE_GET_LOC(car), HAK_NULL,
|
||||
"parameters count(%zd) mismatch in function call - %.*js - expecting %zu-%zu parameters", nargs, HAK_CNODE_GET_TOKLEN(car), HAK_CNODE_GET_TOKPTR(car), sdv->slot[1], sdv->slot[2]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* redundant cdr check is performed inside compile_object_list() */
|
||||
PUSH_SUBCFRAME(hak, COP_COMPILE_ARGUMENT_LIST, cdr);
|
||||
|
||||
@@ -5120,7 +5134,7 @@ static HAK_INLINE int compile_symbol (hak_t* hak, hak_cnode_t* obj)
|
||||
hak_var_info_t vi;
|
||||
int x;
|
||||
|
||||
HAK_ASSERT(hak, HAK_CNODE_IS_SYMBOL(obj));
|
||||
HAK_ASSERT(hak, HAK_CNODE_IS_SYMBOL(obj) || HAK_CNODE_IS_BINOP(obj));
|
||||
|
||||
/* check if a symbol is a local variable */
|
||||
x = find_variable_backward_with_token(hak, obj, &vi);
|
||||
@@ -5598,6 +5612,7 @@ redo:
|
||||
lit = HAK_ERROR_TO_OOP(oprnd->u.errlit.v);
|
||||
goto literal;
|
||||
|
||||
case HAK_CNODE_BINOP: /* binop symbol. treat it like a normal symbol in the object context */
|
||||
case HAK_CNODE_SYMBOL: /* symbol. but not a literal. usually a variable */
|
||||
if (compile_symbol(hak, oprnd) <= -1) return -1;
|
||||
goto done;
|
||||
@@ -6626,7 +6641,7 @@ static HAK_INLINE int post_fun (hak_t* hak)
|
||||
hak_var_info_t vi;
|
||||
int x;
|
||||
|
||||
HAK_ASSERT(hak, HAK_CNODE_IS_SYMBOL(fun_name));
|
||||
HAK_ASSERT(hak, HAK_CNODE_IS_SYMBOL(fun_name) || HAK_CNODE_IS_BINOP(fun_name));
|
||||
|
||||
if (is_in_class_init_scope(hak))
|
||||
{
|
||||
@@ -6804,7 +6819,7 @@ static HAK_INLINE int emit_set (hak_t* hak)
|
||||
hak_oow_t index;
|
||||
hak_oop_t cons, sym;
|
||||
|
||||
HAK_ASSERT(hak, HAK_CNODE_IS_SYMBOL(cf->operand));
|
||||
HAK_ASSERT(hak, HAK_CNODE_IS_SYMBOL(cf->operand) || HAK_CNODE_IS_BINOP(cf->operand));
|
||||
|
||||
sym = hak_makesymbol(hak, HAK_CNODE_GET_TOKPTR(cf->operand), HAK_CNODE_GET_TOKLEN(cf->operand));
|
||||
if (HAK_UNLIKELY(!sym)) return -1;
|
||||
@@ -7171,9 +7186,11 @@ int hak_compile (hak_t* hak, hak_cnode_t* obj, int flags)
|
||||
if (emit_fun(hak) <= -1) goto oops;
|
||||
break;
|
||||
|
||||
#if defined(USE_KW_PLUS)
|
||||
case COP_EMIT_PLUS:
|
||||
if (emit_plus(hak) <= -1) goto oops;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case COP_EMIT_POP_STACKTOP:
|
||||
if (emit_pop_stacktop(hak) <= -1) goto oops;
|
||||
|
||||
@@ -115,6 +115,7 @@ static const char* synerrstr[] =
|
||||
"} expected",
|
||||
"| expected",
|
||||
|
||||
"identifier expected",
|
||||
"string expected",
|
||||
"byte too small or too large",
|
||||
"nesting level too deep",
|
||||
@@ -161,6 +162,7 @@ static const char* synerrstr[] =
|
||||
"break outside loop",
|
||||
|
||||
"invalid callable",
|
||||
"invalid message",
|
||||
"unbalanced key/value pair",
|
||||
"unbalanced parenthesis/brace/bracket",
|
||||
"unexpected semicolon",
|
||||
|
||||
+34
-20
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "hak-prv.h"
|
||||
|
||||
#define ENABLE_SYSCMD
|
||||
|
||||
static const char* io_type_str[] =
|
||||
{
|
||||
"input",
|
||||
@@ -2145,23 +2147,23 @@ static HAK_INLINE int activate_function (hak_t* hak, hak_ooi_t nargs)
|
||||
/* ------------------------------------------------------------------------- */
|
||||
static HAK_INLINE int call_primitive (hak_t* hak, hak_ooi_t nargs)
|
||||
{
|
||||
hak_oop_prim_t rcv;
|
||||
hak_oop_prim_t op_prim;
|
||||
|
||||
rcv = (hak_oop_prim_t)HAK_STACK_GETOP(hak, nargs);
|
||||
HAK_ASSERT(hak, HAK_IS_PRIM(hak, rcv));
|
||||
HAK_ASSERT(hak, HAK_OBJ_GET_SIZE(rcv) == HAK_PRIM_NAMED_INSTVARS);
|
||||
op_prim = (hak_oop_prim_t)HAK_STACK_GETOP(hak, nargs);
|
||||
HAK_ASSERT(hak, HAK_IS_PRIM(hak, op_prim));
|
||||
HAK_ASSERT(hak, HAK_OBJ_GET_SIZE(op_prim) == HAK_PRIM_NAMED_INSTVARS);
|
||||
|
||||
if (nargs < rcv->min_nargs && nargs > rcv->max_nargs)
|
||||
if (nargs < op_prim->min_nargs && nargs > op_prim->max_nargs)
|
||||
{
|
||||
/* TODO: include a primitive name... */
|
||||
HAK_LOG3(hak, HAK_LOG_IC | HAK_LOG_ERROR,
|
||||
"Error - wrong number of arguments to a primitive - expecting %zd-%zd, got %zd\n",
|
||||
rcv->min_nargs, rcv->max_nargs, nargs);
|
||||
op_prim->min_nargs, op_prim->max_nargs, nargs);
|
||||
hak_seterrnum(hak, HAK_ECALLARG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ((hak_pfimpl_t)rcv->impl)(hak, (hak_mod_t*)rcv->mod, nargs);
|
||||
return ((hak_pfimpl_t)op_prim->impl)(hak, (hak_mod_t*)op_prim->mod, nargs);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -2495,6 +2497,7 @@ static void supplement_errmsg (hak_t* hak, hak_ooi_t ip)
|
||||
HAK_ASSERT(hak, HAK_IS_BYTEARRAY(hak, hak->active_function->dbgi));
|
||||
dbgi = (hak_dbgi_t*)HAK_OBJ_GET_BYTE_SLOT(hak->active_function->dbgi);
|
||||
|
||||
orgloc.line = dbgi[ip].sline; /* update the line of the location at least */
|
||||
hak_seterrbfmtloc(hak, orgnum, &orgloc, "%js (%js:%zu)", orgmsg,
|
||||
(dbgi[ip].fname? dbgi[ip].fname: oocstr_dash), dbgi[ip].sline);
|
||||
|
||||
@@ -2515,7 +2518,7 @@ static int do_throw_with_internal_errmsg (hak_t* hak, hak_ooi_t ip)
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#if 0
|
||||
#if defined(ENABLE_SYSCMD)
|
||||
/* EXPERIMENTAL CODE INTEGRATING EXTERNAL COMMANDS */
|
||||
|
||||
#include <unistd.h>
|
||||
@@ -2595,29 +2598,29 @@ done:
|
||||
|
||||
static HAK_INLINE int exec_syscmd (hak_t* hak, hak_ooi_t nargs)
|
||||
{
|
||||
hak_oop_word_t rcv;
|
||||
hak_oop_word_t op_cmd;
|
||||
hak_bch_t* cmd = HAK_NULL;
|
||||
hak_bch_t* xcmd = HAK_NULL;
|
||||
|
||||
rcv = (hak_oop_word_t)HAK_STACK_GETOP(hak, nargs);
|
||||
/*HAK_ASSERT(hak, HAK_IS_STRING(hak, rcv) || HAK_IS_SYMBOL(hak, rcv));*/
|
||||
HAK_ASSERT(hak, HAK_OBJ_IS_CHAR_POINTER(rcv));
|
||||
op_cmd = (hak_oop_word_t)HAK_STACK_GETOP(hak, nargs);
|
||||
/*HAK_ASSERT(hak, HAK_IS_STRING(hak, op_cmd) || HAK_IS_SYMBOL(hak, op_cmd));*/
|
||||
HAK_ASSERT(hak, HAK_OBJ_IS_CHAR_POINTER(op_cmd));
|
||||
|
||||
if (HAK_OBJ_GET_SIZE(rcv) == 0 || hak_count_oocstr(HAK_OBJ_GET_CHAR_SLOT(rcv)) != HAK_OBJ_GET_SIZE(rcv))
|
||||
if (HAK_OBJ_GET_SIZE(op_cmd) == 0 || hak_count_oocstr(HAK_OBJ_GET_CHAR_SLOT(op_cmd)) != HAK_OBJ_GET_SIZE(op_cmd))
|
||||
{
|
||||
/* '\0' is contained in the middle */
|
||||
hak_seterrbfmt(hak, HAK_EINVAL, "invalid callable %O", rcv);
|
||||
hak_seterrbfmt(hak, HAK_EINVAL, "invalid callable %O", op_cmd);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
cmd = hak_dupootobcstr(hak, HAK_OBJ_GET_CHAR_SLOT(rcv), HAK_NULL);
|
||||
cmd = hak_dupootobcstr(hak, HAK_OBJ_GET_CHAR_SLOT(op_cmd), HAK_NULL);
|
||||
if (!cmd) goto oops;
|
||||
|
||||
if (hak_find_bchar_in_bcstr(cmd, '/'))
|
||||
{
|
||||
if (!is_regular_executable_file_by_me(cmd))
|
||||
{
|
||||
hak_seterrbfmt(hak, HAK_ECALL, "cannot execute %O", rcv);
|
||||
hak_seterrbfmt(hak, HAK_ECALL, "cannot execute %O", op_cmd);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
@@ -3636,7 +3639,7 @@ static int execute (hak_t* hak)
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
#if 0
|
||||
// the compiler never emits these instructions. reuse these instructions for other purposes
|
||||
/* the compiler never emits these instructions. reuse these instructions for other purposes */
|
||||
case HAK_CODE_PUSH_TEMPVAR_X:
|
||||
case HAK_CODE_STORE_INTO_TEMPVAR_X:
|
||||
case HAK_CODE_POP_INTO_TEMPVAR_X:
|
||||
@@ -4007,6 +4010,17 @@ static int execute (hak_t* hak)
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(ENABLE_SYSCMD)
|
||||
case HAK_BRAND_STRING:
|
||||
case HAK_BRAND_SYMBOL:
|
||||
if (exec_syscmd(hak, b1) <= -1)
|
||||
{
|
||||
if (do_throw_with_internal_errmsg(hak, fetched_instruction_pointer) >= 0) break;
|
||||
goto call_failed;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
goto cannot_call;
|
||||
}
|
||||
@@ -4786,7 +4800,7 @@ hak_logbfmt(hak, HAK_LOG_STDERR, ">>>%O c->sc=%O sc=%O b2=%d b3=%d nivars=%d ncv
|
||||
t2 = HAK_STACK_GETTOP(hak); /* key */
|
||||
HAK_STACK_POP(hak);
|
||||
t3 = HAK_STACK_GETTOP(hak); /* dictionary */
|
||||
if (!hak_putatdic(hak, (hak_oop_dic_t)t3, t2, t1)) goto oops;
|
||||
if (!hak_putatdic(hak, (hak_oop_dic_t)t3, t2, t1)) goto oops_with_errmsg_supplement;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4834,7 +4848,7 @@ hak_logbfmt(hak, HAK_LOG_STDERR, ">>>%O c->sc=%O sc=%O b2=%d b3=%d nivars=%d ncv
|
||||
hak_pushvolat(hak, &t3);
|
||||
t = hak_makecons(hak, t1, hak->_nil);
|
||||
hak_popvolat(hak);
|
||||
if (HAK_UNLIKELY(!t)) goto oops;
|
||||
if (HAK_UNLIKELY(!t)) goto oops_with_errmsg_supplement;
|
||||
|
||||
((hak_oop_oop_t)t3)->slot[1] = t;
|
||||
HAK_STACK_PUSH(hak, t);
|
||||
@@ -4872,7 +4886,7 @@ hak_logbfmt(hak, HAK_LOG_STDERR, ">>>%O c->sc=%O sc=%O b2=%d b3=%d nivars=%d ncv
|
||||
hak_pushvolat(hak, &t3);
|
||||
t = hak_makecons(hak, t1, hak->_nil);
|
||||
hak_popvolat(hak);
|
||||
if (HAK_UNLIKELY(!t)) goto oops;
|
||||
if (HAK_UNLIKELY(!t)) goto oops_with_errmsg_supplement;
|
||||
|
||||
((hak_oop_oop_t)t3)->slot[1] = t;
|
||||
}
|
||||
|
||||
+11
-2
@@ -326,7 +326,9 @@ enum hak_tok_type_t
|
||||
HAK_TOK_REVERT,
|
||||
HAK_TOK_AND,
|
||||
HAK_TOK_OR,
|
||||
#if defined(USE_KW_PLUS)
|
||||
HAK_TOK_PLUS,
|
||||
#endif
|
||||
HAK_TOK_SET,
|
||||
HAK_TOK_SET_R,
|
||||
|
||||
@@ -396,6 +398,7 @@ enum hak_cnode_type_t
|
||||
HAK_CNODE_BCHRLIT,
|
||||
HAK_CNODE_SYMBOL,
|
||||
HAK_CNODE_DSYMBOL, /* dotted symbol */
|
||||
HAK_CNODE_BINOP,
|
||||
HAK_CNODE_STRLIT,
|
||||
HAK_CNODE_BSTRLIT,
|
||||
HAK_CNODE_SYMLIT,
|
||||
@@ -439,7 +442,9 @@ enum hak_cnode_type_t
|
||||
HAK_CNODE_REVERT,
|
||||
HAK_CNODE_AND,
|
||||
HAK_CNODE_OR,
|
||||
#if defined(USE_KW_PLUS)
|
||||
HAK_CNODE_PLUS,
|
||||
#endif
|
||||
HAK_CNODE_SET,
|
||||
HAK_CNODE_SET_R, /* language item for HAK_CODE_IS_FOR_LANG */
|
||||
|
||||
@@ -483,8 +488,9 @@ typedef enum hak_cnode_flag_t hak_cnode_flag_t;
|
||||
#define HAK_CNODE_IS_COLONLT(x) ((x)->cn_type == HAK_CNODE_COLONLT)
|
||||
|
||||
#define HAK_CNODE_IS_SYMBOL(x) ((x)->cn_type == HAK_CNODE_SYMBOL)
|
||||
#define HAK_CNODE_IS_SYMBOL_IDENT(x) (HAK_CNODE_IS_SYMBOL(x) && !hak_is_binop_char((x)->cn_tok.ptr[0]))
|
||||
#define HAK_CNODE_IS_SYMBOL_BINOP(x) (HAK_CNODE_IS_SYMBOL(x) && hak_is_binop_char((x)->cn_tok.ptr[0]))
|
||||
#define HAK_CNODE_IS_BINOP(x) ((x)->cn_type == HAK_CNODE_BINOP)
|
||||
#define HAK_CNODE_IS_STRLIT(x) ((x)->cn_type == HAK_CNODE_STRLIT)
|
||||
#define HAK_CNODE_IS_SYMLIT(x) ((x)->cn_type == HAK_CNODE_SYMLIT)
|
||||
|
||||
#define HAK_CNODE_IS_DSYMBOL(x) ((x)->cn_type == HAK_CNODE_DSYMBOL)
|
||||
#define HAK_CNODE_IS_DSYMBOL_CLA(x) ((x)->cn_type == HAK_CNODE_DSYMBOL && (x)->u.dsymbol.is_cla)
|
||||
@@ -900,6 +906,7 @@ struct hak_frd_t
|
||||
{
|
||||
int level;
|
||||
int flagv;
|
||||
int expect_pragma_item;
|
||||
int expect_include_file;
|
||||
int expect_vlist_item;
|
||||
int do_include_file;
|
||||
@@ -1357,6 +1364,7 @@ enum hak_bcode_t
|
||||
HAK_CODE_PUSH_NEGINTLIT = 0xB3, /* 179 */
|
||||
HAK_CODE_PUSH_CHARLIT = 0xB4, /* 180 */
|
||||
|
||||
/* TODO: generalize it to support binops, not just plus */
|
||||
HAK_CODE_PLUS = 0xB5, /* 181 TOOD: move it to a lower code number later after killing OBJVAR instructions */
|
||||
/* UNUSED - 0xB6-0xB7 */
|
||||
|
||||
@@ -2022,6 +2030,7 @@ hak_cnode_t* hak_makecnodecharlit (hak_t* hak, int flags, const hak_loc_t* loc,
|
||||
hak_cnode_t* hak_makecnodebchrlit (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok, hak_oob_t v);
|
||||
hak_cnode_t* hak_makecnodesymbol (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok);
|
||||
hak_cnode_t* hak_makecnodedsymbol (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok, int is_cla);
|
||||
hak_cnode_t* hak_makecnodebinop (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok);
|
||||
hak_cnode_t* hak_makecnodestrlit (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok);
|
||||
hak_cnode_t* hak_makecnodebstrlit (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok);
|
||||
hak_cnode_t* hak_makecnodesymlit (hak_t* hak, int flags, const hak_loc_t* loc, const hak_oocs_t* tok);
|
||||
|
||||
@@ -119,6 +119,7 @@ enum hak_synerrnum_t
|
||||
HAK_SYNERR_RBRACE, /* } expected */
|
||||
HAK_SYNERR_VBAR, /* | expected */
|
||||
|
||||
HAK_SYNERR_IDENT, /* identifier expected */
|
||||
HAK_SYNERR_STRING, /* string expected */
|
||||
HAK_SYNERR_BYTERANGE, /* byte too small or too large */
|
||||
HAK_SYNERR_NESTING, /* nesting level too deep */
|
||||
@@ -165,6 +166,7 @@ enum hak_synerrnum_t
|
||||
HAK_SYNERR_BREAK, /* break outside loop */
|
||||
|
||||
HAK_SYNERR_CALLABLE, /* invalid callable */
|
||||
HAK_SYNERR_MESSAGE, /* invalid message */
|
||||
HAK_SYNERR_UNBALKV, /* unbalanced key/value pair */
|
||||
HAK_SYNERR_UNBALPBB, /* unbalanced parenthesis/brace/bracket */
|
||||
HAK_SYNERR_SEMICOLON, /* unexpected semicolon */
|
||||
|
||||
+1
-1
@@ -891,7 +891,7 @@ static int feed_json_data_u (hak_json_t* json, const hak_uch_t* data, hak_oow_t
|
||||
hak_oow_t n, i;
|
||||
|
||||
n = json->_gem.cmgr->uctobc(*ptr++, bcsbuf, HAK_COUNTOF(bcsbuf));
|
||||
if (n == 0) goto oops; // illegal character
|
||||
if (n == 0) goto oops; /* illegal character */
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
|
||||
@@ -957,7 +957,9 @@ void hak_dumpcnode (hak_t* hak, hak_cnode_t* cnode, int newline)
|
||||
case HAK_CNODE_REVERT:
|
||||
case HAK_CNODE_AND:
|
||||
case HAK_CNODE_OR:
|
||||
#if defined(USE_KW_PLUS)
|
||||
case HAK_CNODE_PLUS:
|
||||
#endif
|
||||
case HAK_CNODE_SET:
|
||||
case HAK_CNODE_SET_R:
|
||||
|
||||
|
||||
+147
-27
@@ -76,7 +76,9 @@ static struct voca_t
|
||||
{ 6, { 'r','e','v','e','r','t' } },
|
||||
{ 3, { 'a','n','d' } },
|
||||
{ 2, { 'o','r', } },
|
||||
#if defined(USE_KW_PLUS)
|
||||
{ 4, { 'p','l','u','s' } },
|
||||
#endif
|
||||
{ 3, { 's','e','t' } },
|
||||
{ 5, { 's','e','t','-','r' } },
|
||||
|
||||
@@ -137,7 +139,9 @@ enum voca_id_t
|
||||
VOCA_KW_REVERT,
|
||||
VOCA_KW_AND,
|
||||
VOCA_KW_OR,
|
||||
#if defined(USE_KW_PLUS)
|
||||
VOCA_KW_PLUS,
|
||||
#endif
|
||||
VOCA_KW_SET,
|
||||
VOCA_KW_SET_R,
|
||||
|
||||
@@ -285,7 +289,6 @@ static HAK_INLINE int is_delim_char (hak_ooci_t c)
|
||||
c == '#' || c == '\"' || c == '\'' || c == '\\' || is_spacechar(c) || c == HAK_OOCI_EOF;
|
||||
}
|
||||
|
||||
|
||||
int hak_is_binop_char (hak_ooci_t c) /* not static HAK_INLINE for shared use with comp.c via HAK_CNODE_IS_SYMBOL() */
|
||||
{
|
||||
return c == '&' || c == '*' || c == '+' || c == '-' || c == '/' || c == '%' ||
|
||||
@@ -293,9 +296,23 @@ int hak_is_binop_char (hak_ooci_t c) /* not static HAK_INLINE for shared use wit
|
||||
}
|
||||
#define is_binop_char(c) hak_is_binop_char(c)
|
||||
|
||||
static HAK_INLINE int is_pure_lead_ident_char (hak_ooci_t c)
|
||||
{
|
||||
return hak_is_ooch_alnum(c) || c == '_';
|
||||
}
|
||||
|
||||
static HAK_INLINE int is_pure_ident_char (hak_ooci_t c)
|
||||
{
|
||||
return hak_is_ooch_alnum(c) || c == '_' || c == '-';
|
||||
}
|
||||
|
||||
static HAK_INLINE int is_lead_ident_char (hak_ooci_t c)
|
||||
{
|
||||
#if defined(STRICT_BINOP)
|
||||
return hak_is_ooch_alpha(c) || c == '_';
|
||||
#else
|
||||
return hak_is_ooch_alnum(c) || c == '_' || c == '-' || c == '?' || is_binop_char(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
static HAK_INLINE int is_ident_char (hak_ooci_t c)
|
||||
@@ -304,7 +321,11 @@ static HAK_INLINE int is_ident_char (hak_ooci_t c)
|
||||
* '-' is prohibited as the last character of an identifier or an identifier segment.
|
||||
* see flx_plain_ident().
|
||||
*/
|
||||
#if defined(STRICT_BINOP)
|
||||
return hak_is_ooch_alnum(c) || c == '_' || c == '-' || c == '?';
|
||||
#else
|
||||
return hak_is_ooch_alnum(c) || c == '_' || c == '-' || c == '?' || is_binop_char(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* TODO: remove GET_CHAR(), GET_CHAR_TO(), get_char(), _get_char() */
|
||||
@@ -458,6 +479,7 @@ static int get_char (hak_t* hak)
|
||||
static hak_tok_type_t classify_ident_token (hak_t* hak, const hak_oocs_t* v)
|
||||
{
|
||||
hak_oow_t i;
|
||||
int is_binop;
|
||||
static struct
|
||||
{
|
||||
int voca_id;
|
||||
@@ -488,7 +510,9 @@ static hak_tok_type_t classify_ident_token (hak_t* hak, const hak_oocs_t* v)
|
||||
{ VOCA_KW_REVERT, HAK_TOK_REVERT },
|
||||
{ VOCA_KW_AND, HAK_TOK_AND },
|
||||
{ VOCA_KW_OR, HAK_TOK_OR },
|
||||
#if defined(USE_KW_PLUS)
|
||||
{ VOCA_KW_PLUS, HAK_TOK_PLUS },
|
||||
#endif
|
||||
{ VOCA_KW_SET, HAK_TOK_SET },
|
||||
{ VOCA_KW_SET_R, HAK_TOK_SET_R }
|
||||
};
|
||||
@@ -499,7 +523,44 @@ static hak_tok_type_t classify_ident_token (hak_t* hak, const hak_oocs_t* v)
|
||||
if (hak_comp_oochars(v->ptr, v->len, vocas[vid].str, vocas[vid].len) == 0) return tab[i].type;
|
||||
}
|
||||
|
||||
return HAK_TOK_IDENT;
|
||||
if (is_pure_lead_ident_char(v->ptr[0]))
|
||||
{
|
||||
/* check if the word conforms to pure identifier rules:
|
||||
* begins with alnum or _
|
||||
* may contains a dash or dashes in between
|
||||
* ends with alnum or _ or ?
|
||||
*/
|
||||
hak_oow_t wc = 1;
|
||||
int q = 0;
|
||||
for (i = 1; i < v->len; i++)
|
||||
{
|
||||
if (q && v->ptr[i] != '?') goto not_ident;
|
||||
|
||||
if (v->ptr[i] == '-')
|
||||
{
|
||||
/*if (wc == 0) goto not_ident;*/
|
||||
wc = 0;
|
||||
}
|
||||
else if (v->ptr[i] == '?') q = 1;
|
||||
else if (!is_pure_ident_char(v->ptr[i])) goto not_ident;
|
||||
else wc++;
|
||||
}
|
||||
|
||||
if (wc > 0) return HAK_TOK_IDENT;
|
||||
}
|
||||
|
||||
not_ident:
|
||||
is_binop = 1;
|
||||
for (i = 0; i < v->len; i++)
|
||||
{
|
||||
if (!is_binop_char(v->ptr[i]))
|
||||
{
|
||||
is_binop = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return is_binop? HAK_TOK_BINOP: HAK_TOK_SYMLIT;
|
||||
}
|
||||
|
||||
static int is_sr_name_in_use (hak_t* hak, const hak_ooch_t* sr_name)
|
||||
@@ -692,7 +753,7 @@ static HAK_INLINE hak_cnode_t* leave_list (hak_t* hak, hak_loc_t* list_loc, int*
|
||||
/* check in advance if the array members are all plain symbols */
|
||||
hak_cnode_t* lcar;
|
||||
lcar = HAK_CNODE_CONS_CAR(tmp);
|
||||
if (!HAK_CNODE_IS_SYMBOL_IDENT(lcar) && !HAK_CNODE_IS_DSYMBOL_CLA(lcar))
|
||||
if (!HAK_CNODE_IS_SYMBOL(lcar) && !HAK_CNODE_IS_DSYMBOL_CLA(lcar))
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_LVALUE, HAK_CNODE_GET_LOC(lval), HAK_CNODE_GET_TOK(lval), "bad lvalue - invalid element in tuple");
|
||||
goto oops;
|
||||
@@ -718,7 +779,7 @@ static HAK_INLINE hak_cnode_t* leave_list (hak_t* hak, hak_loc_t* list_loc, int*
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!HAK_CNODE_IS_SYMBOL_IDENT(lval) && !HAK_CNODE_IS_DSYMBOL_CLA(lval))
|
||||
if (!HAK_CNODE_IS_SYMBOL(lval) && !HAK_CNODE_IS_DSYMBOL_CLA(lval))
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_LVALUE, HAK_CNODE_GET_LOC(lval), HAK_CNODE_GET_TOK(lval), "bad lvalue - invalid element");
|
||||
goto oops;
|
||||
@@ -1457,7 +1518,9 @@ static hak_cnode_type_t kw_to_cnode_type (int tok_type)
|
||||
HAK_CNODE_REVERT,
|
||||
HAK_CNODE_AND,
|
||||
HAK_CNODE_OR,
|
||||
#if defined(USE_KW_PLUS)
|
||||
HAK_CNODE_PLUS,
|
||||
#endif
|
||||
HAK_CNODE_SET,
|
||||
HAK_CNODE_SET_R
|
||||
};
|
||||
@@ -1477,22 +1540,68 @@ static int feed_process_token (hak_t* hak)
|
||||
* by manipulating its own stack. */
|
||||
|
||||
/*hak_logbfmt(hak, HAK_LOG_STDERR, "TOKEN [%d] EOL[%d]=> [%.*js] type=%d LOC=%d.%d\n", TOKEN_TYPE(hak), HAK_TOK_EOL, TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak), TOKEN_TYPE(hak), TOKEN_LOC(hak)->line, TOKEN_LOC(hak)->colm);*/
|
||||
if (frd->expect_pragma_item)
|
||||
{
|
||||
/* the pragmas changes the behavior of the reader and the compiler */
|
||||
if (frd->expect_pragma_item >= 3) /* eol expected */
|
||||
{
|
||||
if (TOKEN_TYPE(hak) != HAK_TOK_EOL)
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), HAK_NULL,
|
||||
"redundant token '%.*js' for '%.*js'",
|
||||
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak),
|
||||
vocas[VOCA_PRAGMA].len, vocas[VOCA_PRAGMA].str);
|
||||
goto oops;
|
||||
}
|
||||
frd->expect_pragma_item = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TOKEN_TYPE(hak) == HAK_TOK_EOL)
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_IDENT, TOKEN_LOC(hak), HAK_NULL,
|
||||
"'%.*js' %hs not specified",
|
||||
vocas[VOCA_PRAGMA].len, vocas[VOCA_PRAGMA].str,
|
||||
(frd->expect_pragma_item == 1? "name": "value"));
|
||||
goto oops;
|
||||
}
|
||||
else if (TOKEN_TYPE(hak) != HAK_TOK_IDENT)
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_IDENT, TOKEN_LOC(hak), HAK_NULL,
|
||||
"'%.*js' %hs expected in place of '%.*js'",
|
||||
vocas[VOCA_INCLUDE].len, vocas[VOCA_INCLUDE].str,
|
||||
(frd->expect_pragma_item == 1? "name": "value"),
|
||||
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (frd->expect_pragma_item == 1)
|
||||
{
|
||||
frd->expect_pragma_item = 2; /* expect value */
|
||||
}
|
||||
else
|
||||
{
|
||||
frd->expect_pragma_item = 3; /* expect eol */
|
||||
}
|
||||
}
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (frd->expect_include_file)
|
||||
{
|
||||
/* the #include directive is an exception to the general expression rule.
|
||||
* use this exceptional code block to divert the major token processing */
|
||||
|
||||
if (TOKEN_TYPE(hak) == HAK_TOK_EOL)
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_STRING, TOKEN_LOC(hak), HAK_NULL,
|
||||
"%.*js target not specified",
|
||||
"'%.*js' target not specified",
|
||||
vocas[VOCA_INCLUDE].len, vocas[VOCA_INCLUDE].str);
|
||||
goto oops;
|
||||
}
|
||||
else if (TOKEN_TYPE(hak) != HAK_TOK_STRLIT)
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_STRING, TOKEN_LOC(hak), HAK_NULL,
|
||||
"%.*js target expected in place of '%.*js'",
|
||||
"'%.*js' target expected in place of '%.*js'",
|
||||
vocas[VOCA_INCLUDE].len, vocas[VOCA_INCLUDE].str,
|
||||
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
||||
goto oops;
|
||||
@@ -1542,9 +1651,11 @@ static int feed_process_token (hak_t* hak)
|
||||
goto ok;
|
||||
|
||||
case HAK_TOK_PRAGMA:
|
||||
/* TODO: implement this */
|
||||
hak_setsynerr(hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), TOKEN_NAME(hak));
|
||||
goto oops;
|
||||
/*hak_setsynerr(hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), TOKEN_NAME(hak));
|
||||
goto oops;*/
|
||||
/* TODO: check if pragma is the first word in the line */
|
||||
frd->expect_pragma_item = 1;
|
||||
goto ok;
|
||||
|
||||
case HAK_TOK_VBAR:
|
||||
if (frd->expect_vlist_item)
|
||||
@@ -1729,15 +1840,14 @@ static int feed_process_token (hak_t* hak)
|
||||
goto oops;
|
||||
}
|
||||
else if (can <= -1) goto oops;
|
||||
if (can == 1) goto ident; /* if binop is the first in the list */
|
||||
|
||||
HAK_ASSERT(hak, can == 2);
|
||||
|
||||
#if 0
|
||||
/* TODO: ... */
|
||||
#if 1
|
||||
HAK_ASSERT(hak, can == 1 || can == 2);
|
||||
frd->obj = hak_makecnodebinop(hak, 0, TOKEN_LOC(hak), TOKEN_NAME(hak));
|
||||
goto ok;
|
||||
goto auto_xlist;
|
||||
#else
|
||||
if (can == 1) goto ident; /* if binop is the first in the list */
|
||||
HAK_ASSERT(hak, can == 2);
|
||||
goto ident;
|
||||
#endif
|
||||
}
|
||||
@@ -1897,7 +2007,9 @@ static int feed_process_token (hak_t* hak)
|
||||
case HAK_TOK_REVERT:
|
||||
case HAK_TOK_AND:
|
||||
case HAK_TOK_OR:
|
||||
#if defined(USE_KW_PLUS)
|
||||
case HAK_TOK_PLUS:
|
||||
#endif
|
||||
case HAK_TOK_SET:
|
||||
case HAK_TOK_SET_R:
|
||||
frd->obj = hak_makecnode(hak, kw_to_cnode_type(TOKEN_TYPE(hak)), 0, TOKEN_LOC(hak), TOKEN_NAME(hak));
|
||||
@@ -2411,12 +2523,15 @@ static int flx_start (hak_t* hak, hak_ooci_t c)
|
||||
goto consumed;
|
||||
|
||||
default:
|
||||
#if defined(STRICT_BINOP)
|
||||
if (is_binop_char(c))
|
||||
{
|
||||
init_flx_binop(FLX_BINOP(hak));
|
||||
FEED_CONTINUE(hak, HAK_FLX_BINOP);
|
||||
}
|
||||
else if (is_lead_ident_char(c))
|
||||
else
|
||||
#endif
|
||||
if (is_lead_ident_char(c))
|
||||
{
|
||||
init_flx_pi(FLX_PI(hak));
|
||||
FEED_CONTINUE(hak, HAK_FLX_PLAIN_IDENT);
|
||||
@@ -2528,6 +2643,7 @@ static int flx_dollared_ident (hak_t* hak, hak_ooci_t c)
|
||||
{
|
||||
if (!is_lead_ident_char(c))
|
||||
{
|
||||
/* some character can't placed immediately after '$'. e.g '?' */
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), HAK_NULL,
|
||||
"'%c' prohibited as first character after '%.*js'",
|
||||
c, TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
||||
@@ -2586,12 +2702,14 @@ static int flx_hmarked_token (hak_t* hak, hak_ooci_t c)
|
||||
* #"..." symbol literal
|
||||
*/
|
||||
|
||||
#if defined(STRICT_BINOP)
|
||||
if (is_binop_char(c))
|
||||
{
|
||||
reset_flx_token(hak);
|
||||
FEED_CONTINUE_WITH_CHAR(hak, c, HAK_FLX_HMARKED_BINOP);
|
||||
goto consumed;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (c)
|
||||
{
|
||||
@@ -2889,6 +3007,7 @@ static int flx_plain_ident (hak_t* hak, hak_ooci_t c) /* identifier */
|
||||
start = TOKEN_NAME_LEN(hak) - pi->seg_len;
|
||||
seg.ptr = &TOKEN_NAME_CHAR(hak, start);
|
||||
seg.len = pi->seg_len;
|
||||
#if defined(STRICT_BINOP)
|
||||
if (seg.ptr[seg.len - 1] == '-')
|
||||
{
|
||||
hak_setsynerrbfmt(hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), TOKEN_NAME(hak),
|
||||
@@ -2896,6 +3015,7 @@ static int flx_plain_ident (hak_t* hak, hak_ooci_t c) /* identifier */
|
||||
seg.ptr[seg.len - 1]);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
tok_type = classify_ident_token(hak, &seg);
|
||||
if (tok_type != HAK_TOK_IDENT)
|
||||
{
|
||||
@@ -3328,7 +3448,16 @@ static int flx_signed_token (hak_t* hak, hak_ooci_t c)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
#if defined(STRICT_BINOP)
|
||||
/* the leading sign must be + or - and must be one of the binop chars. */
|
||||
HAK_ASSERT(hak, is_binop_char(st->sign_c));/* must be + or - and they must be one of the binop chars. */
|
||||
|
||||
/* switch to binop mode */
|
||||
init_flx_binop(FLX_BINOP(hak));
|
||||
HAK_ASSERT(hak, TOKEN_NAME_LEN(hak) == 1);
|
||||
FEED_CONTINUE(hak, HAK_FLX_BINOP);
|
||||
goto not_consumed;
|
||||
#else
|
||||
init_flx_pi(FLX_PI(hak));
|
||||
|
||||
/* the sign is already in the token name buffer.
|
||||
@@ -3340,15 +3469,6 @@ static int flx_signed_token (hak_t* hak, hak_ooci_t c)
|
||||
/* let refeeding of 'c' happen at the next iteration */
|
||||
FEED_CONTINUE(hak, HAK_FLX_PLAIN_IDENT);
|
||||
goto not_consumed;
|
||||
#else
|
||||
/* the leading sign must be + or - and must be one of the binop chars. */
|
||||
HAK_ASSERT(hak, is_binop_char(st->sign_c));/* must be + or - and they must be one of the binop chars. */
|
||||
|
||||
/* switch to binop mode */
|
||||
init_flx_binop(FLX_BINOP(hak));
|
||||
HAK_ASSERT(hak, TOKEN_NAME_LEN(hak) == 1);
|
||||
FEED_CONTINUE(hak, HAK_FLX_BINOP);
|
||||
goto not_consumed;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -6,12 +6,12 @@ class Apex {
|
||||
return (core.basicNew self size)
|
||||
}
|
||||
|
||||
fun[#class] respondsTo(mth) {
|
||||
return (core.classRespondsTo self mth)
|
||||
fun[#class] respondsTo(mthname) {
|
||||
return (core.classRespondsTo self mthname)
|
||||
}
|
||||
|
||||
fun respondsTo(mth) {
|
||||
return (core.instRespondsTo self mth)
|
||||
fun respondsTo(mthname) {
|
||||
return (core.instRespondsTo self mthname)
|
||||
}
|
||||
|
||||
fun primAt(pos) {
|
||||
|
||||
@@ -105,3 +105,33 @@ core.basicAtPut "xbcdefghiklmnl" 4 k ##ERROR: exception not handled - "receiver
|
||||
|
||||
k := (core.basicAt #abcdefg 1)
|
||||
core.basicAtPut #xbcdefghiklmnl 4 k ##ERROR: exception not handled - "receiver immutable - xbcdefghiklmnl"
|
||||
|
||||
---
|
||||
|
||||
## the compiler/runtime needs to improve on this although this is an error for now.
|
||||
fun + (a b) {}
|
||||
printf "%O\n" #{+: 20} ##ERROR: no builtin hash implemented for #<BLOCK>
|
||||
|
||||
---
|
||||
|
||||
class X {
|
||||
fun + () {} ##ERROR: syntax error - only one argument expected for '+'
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
## the binop method defined for a class must have one argument
|
||||
class X {
|
||||
fun + (t) {}
|
||||
fun f1 (t1 t2) {}
|
||||
}
|
||||
|
||||
fun X:- (a b) {} ##ERROR: syntax error - only one argument expected for 'X:-'
|
||||
|
||||
---
|
||||
|
||||
class X {
|
||||
fun[#ci] +(a b c) { printf "jjj\n" } ## the one argument rule applies to binary instance methods only.
|
||||
fun +(c d) { printf "jjj\n" } ##ERROR: syntax error - only one argument expected for '+'
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ if (== i k) { printf "OK: i is %d\n" i k } \
|
||||
else { printf "ERROR: i is not equal to %d\n" k }
|
||||
|
||||
|
||||
## dictionary
|
||||
a := #{
|
||||
(if (> 10 20) true else false ): 10,
|
||||
(if (< 10 20) true else false ): 20
|
||||
|
||||
@@ -166,6 +166,7 @@ abc.? := 20 ##ERROR: syntax error - '?' prohibited as first character of identif
|
||||
|
||||
|
||||
---
|
||||
|
||||
- := 20 ##ERROR: syntax error - bad lvalue - invalid element - -
|
||||
|
||||
---
|
||||
|
||||
@@ -126,3 +126,22 @@ if (== v 30) { printf "OK - %d\n" v } else { printf "ERROR - %d, not 30\n" v };
|
||||
fun k(x) (+ x 30) ## (+ x 30) is valid function body
|
||||
v := (k 10)
|
||||
if (== v 40) { printf "OK - %d\n" v } else { printf "ERROR - %d, not 40\n" v };
|
||||
|
||||
|
||||
## ----------------------------------------
|
||||
fun plus(x y) {
|
||||
##printf "plus %d %d\n" x y
|
||||
fun minus(x y) {
|
||||
##printf "minus %d %d\n" x y
|
||||
- x y
|
||||
}
|
||||
+ x y
|
||||
}
|
||||
|
||||
fun dummy(q) {
|
||||
printf "%s\n" q
|
||||
}
|
||||
|
||||
plus 10 20 ## minus is now available after plus is executed
|
||||
v := (minus 10 1)
|
||||
if (== v 9) { printf "OK - %d\n" v } else { printf "ERROR - %d, not 9\n" v }
|
||||
|
||||
Reference in New Issue
Block a user