--- /dev/null
+list::iota1 130_000
+ | _.filter => n { not (n %% 2) }
+ | _.map => n { n * n }
+ | _.reduce 0, => a, b { a + b }
+ | println
case AST_OP_GT: EMIT(BC_OP_LE, BC_OP_NOT); break;
case AST_OP_LE: EMIT(BC_OP_LE); break;
case AST_OP_GE: EMIT(BC_OP_LT, BC_OP_NOT); break;
+ case AST_OP_NOT: EMIT(BC_OP_NOT); break;
case AST_OP_AND: EMIT(BC_OP_AND); break;
case AST_OP_OR: EMIT(BC_OP_OR); break;
case AST_OP_INDEX: EMIT(BC_OP_INDEX); break;
i->sign_bit = 1;
value *= -1;
}
- i->buf.data[0] = (value % BIGINT_PIECE_MAX);
- i->buf.data[1] = (value / BIGINT_PIECE_MAX);
+ ((piece*)(i->buf.data))[0] = (value % BIGINT_PIECE_MAX);
+ ((piece*)(i->buf.data))[1] = (value / BIGINT_PIECE_MAX);
return i->handle;
}
sbLibTable g_list_module;
-static void iota(hVm vm, usize argc) {
+static void do_iota(hVm vm, usize argc, i32 offset) {
if (argc != 1 && argc != 2) {
- PANIC("list::iota takes 1 or 2 arguments");
+ if (offset == 1) {
+ PANIC("list::iota1 takes 1 or 2 arguments");
+ } else {
+ PANIC("list::iota takes 1 or 2 arguments");
+ }
}
hV *first = sbVm_pop(vm);
hInteger min, max;
if (argc == 1) {
if (first->type != IT_INTEGER) {
- PANIC("list::iota's argument must be an integer!");
+ if (offset == 1) {
+ PANIC("list::iota1's argument must be an integer!");
+ } else {
+ PANIC("list::iota's argument must be an integer!");
+ }
}
- min = 0;
- max = first->integer;
+ min = offset;
+ max = first->integer + offset;
} else {
hV *second = sbVm_pop(vm);
if (first->type != IT_INTEGER || second->type != IT_INTEGER) {
- PANIC("list::iota's arguments must be integers!");
+ if (offset == 1) {
+ PANIC("list::iota1's arguments must be integers!");
+ } else {
+ PANIC("list::iota's arguments must be integers!");
+ }
}
- min = first->integer;
- max = second->integer;
+ min = first->integer + offset;
+ max = second->integer + offset;
}
hList result = sbList_new((usize)sbInteger_diff(max, min));
sbVm_push_immediate(vm, &HVLIST(result));
}
+static void iota(hVm vm, usize argc) {
+ do_iota(vm, argc, 0);
+}
+
+static void iota1(hVm vm, usize argc) {
+ do_iota(vm, argc, 1);
+}
+
void sbLib_loadmodule_list() {
sbLibTable_initialize(&g_list_module, 16, FALSE);
REGISTER_VALUE(&g_list_module, "iota", &HVBUILTIN(iota));
+ REGISTER_VALUE(&g_list_module, "iota1", &HVBUILTIN(iota1));
REGISTER_VALUE(&g_list_module, "convert", &HVSYM(S_OP_TO_LIST));
}
/* header keywords that introduce a block and go until a { */
static flag begins_brace_terminated_state(sbTokenType type) {
return type == T_rDEF
- || type == T_rIF
- || type == T_rUNLESS
|| type == T_rWHILE
|| type == T_rUNTIL
|| type == T_rDO
|| type == T_SQUIGARROW; /* squiggle arrow ~> a, b { ... } introduces block header also */
}
+/* only starts BTS at start of line, not in middle of line */
+static flag begins_brace_terminated_state_at_line_start(sbTokenType type) {
+ return type == T_rIF
+ || type == T_rUNLESS;
+}
+
/* things we can potentially insert a ( after because they may be a call */
static flag can_open_paren_after(sbTokenType type) {
return type == T_IDENTIFIER
|| type == T_rDO;
}
-/* these are operators that look weird if they get captured inside
- * of parentheses, and also if and unless in postfix form */
+/* close invisible parentheses before we see this token */
static flag close_invisible_parens_before(sbTokenType type) {
- return type == T_rAND
- || type == T_rOR
+ return type == T_SEMICOLON
|| type == T_rIF
|| type == T_rUNLESS
- || type == T_DOUBLEEQUALS
- || type == T_NOTEQUALS
- || type == T_LESS
- || type == T_GREATER
- || type == T_LESSEQUALS
- || type == T_GREATEREQUALS
|| type == T_PIPE;
}
unstack_all_invisible_parentheses(lx);
}
- if (begins_brace_terminated_state(token.type)) {
+ if (begins_brace_terminated_state(token.type)
+ || (begins_brace_terminated_state_at_line_start(token.type) && lx->last_token_seen.type == ';')) {
/* don't start brace-terminated state if we are directly after a '}' (otherwise it gets
* confused by things like repeat..until */
if (lx->last_token_seen.type != '}') {