Example #1
0
static int cmd_endremapblock(const char *args)
{
	int ret = ERR_BLOCK_TOO_LARGE;
	unsigned int i, x;
	struct block *block;
	(void)args;

	block = block_alloc();
	if (!block) goto ret;

	fill_block_header(block);
	block_append(block, current_layer);
	block_append(block, (unsigned char)pair_lists[REMAP_LIST].len);

	for (i = 0; i < pair_lists[REMAP_LIST].len; i++) {
		x = pair_lists[REMAP_LIST].list[i];
		block_append(block, (unsigned char)(x >> 8));
		block_append(block, (unsigned char)(x & 0xff));
	}

	block->bytes[0] = block->len;
	block_list_append(block);
	free(block);
	pair_list_clear(REMAP_LIST);
	block_type = BLOCK_NONE;
	ret = 0;

ret:
	return ret;
}
Example #2
0
static void fill_block_header(struct block *block)
{
	/* placeholder for size */
	block_append(block, 0);

	/* flags */
	block_append(block, (unsigned char)(
		block_type | (current_select << 3) |
		((current_scanset != 0) << 6)      |
		((current_keyboard_id != 0) << 7)));

	if (current_scanset)
		block_append(block, current_scanset);

	if (current_keyboard_id) {
		block_append(block, current_keyboard_id & 0xff);
		block_append(block, (current_keyboard_id >> 8) & 0xff);
	}

ret:
	return;
}
Example #3
0
static int cmd_endmacroblock(const char *args)
{
	int ret = ERR_BLOCK_TOO_LARGE;
	unsigned int i, j, x;
	struct block *block;
	(void)args;

	block = block_alloc();
	if (!block) goto ret;

	fill_block_header(block);
	block_append(block, (unsigned char)macro_list_len);

	for (i = 0; i < macro_list_len; i++) {
		block_append(block, macro_list[i].hid_code);
		block_append(block, macro_list[i].desired_meta);
		block_append(block, macro_list[i].matched_meta);
		block_append(block, macro_list[i].press_flags);
		block_append(block, macro_list[i].release_flags);

		for (j = 0; j < macro_list[i].commands.len; j++) {
			x = macro_list[i].commands.list[j];
			block_append(block, (unsigned char)(x >> 8));
			block_append(block, (unsigned char)(x & 0xff));
		}
	}

	block->bytes[0] = block->len;
	block_list_append(block);
	free(block);
	macro_list_clear();
	block_type = BLOCK_NONE;
	ret = 0;

ret:
	return ret;
}
Example #4
0
// Expands call instructions into a calling sequence
static int expand_call_arglist(struct locfile* locations, block* b) {
  int errors = 0;
  block ret = gen_noop();
  for (inst* curr; (curr = block_take(b));) {
    if (opcode_describe(curr->op)->flags & OP_HAS_BINDING) {
      if (!curr->bound_by) {
        locfile_locate(locations, curr->source, "error: %s is not defined", curr->symbol);
        errors++;
        // don't process this instruction if it's not well-defined
        ret = BLOCK(ret, inst_block(curr));
        continue;
      }
    }

    block prelude = gen_noop();
    if (curr->op == CALL_JQ) {
      int actual_args = 0, desired_args = 0;
      // We expand the argument list as a series of instructions
      switch (curr->bound_by->op) {
      default: assert(0 && "Unknown function type"); break;
      case CLOSURE_CREATE: 
      case CLOSURE_PARAM: {
        block callargs = gen_noop();
        for (inst* i; (i = block_take(&curr->arglist));) {
          assert(opcode_describe(i->op)->flags & OP_IS_CALL_PSEUDO);
          block b = inst_block(i);
          switch (i->op) {
          default: assert(0 && "Unknown type of parameter"); break;
          case CLOSURE_REF:
            block_append(&callargs, b);
            break;
          case CLOSURE_CREATE:
            block_append(&prelude, b);
            block_append(&callargs, gen_op_bound(CLOSURE_REF, b));
            break;
          }
          actual_args++;
        }
        curr->imm.intval = actual_args;
        curr->arglist = callargs;

        if (curr->bound_by->op == CLOSURE_CREATE) {
          for (inst* i = curr->bound_by->arglist.first; i; i = i->next) {
            assert(i->op == CLOSURE_PARAM);
            desired_args++;
          }
        }
        break;
      }

      case CLOSURE_CREATE_C: {
        for (inst* i; (i = block_take(&curr->arglist)); ) {
          assert(i->op == CLOSURE_CREATE); // FIXME
          block body = i->subfn;
          i->subfn = gen_noop();
          inst_free(i);
          // arguments should be pushed in reverse order, prepend them to prelude
          errors += expand_call_arglist(locations, &body);
          prelude = BLOCK(gen_subexp(body), prelude);
          actual_args++;
        }
        assert(curr->op == CALL_JQ);
        curr->op = CALL_BUILTIN;
        curr->imm.intval = actual_args + 1 /* include the implicit input in arg count */;
        assert(curr->bound_by->op == CLOSURE_CREATE_C);
        desired_args = curr->bound_by->imm.cfunc->nargs - 1;
        assert(!curr->arglist.first);
        break;
      }
      }

      if (actual_args != desired_args) {
        locfile_locate(locations, curr->source, 
                       "error: %s arguments to %s (expected %d but got %d)",
                       actual_args > desired_args ? "too many" : "too few",
                       curr->symbol, desired_args, actual_args);
        errors++;
      }

    }
    ret = BLOCK(ret, prelude, inst_block(curr));
  }
  *b = ret;
  return errors;
}
Example #5
0
block block_join(block a, block b) {
  block c = a;
  block_append(&c, b);
  return c;
}