/* Return a human-readable representation of this operation code */ static Octstr *operation_name(int operation) { int i; i = operation_find(operation); if (i >= 0) return octstr_create(operations[i].name); if (operation >= RESPONSE) { i = operation_find(operation - RESPONSE); if (i >= 0) { Octstr *name = octstr_create(operations[i].name); octstr_append_cstr(name, " response"); return name; } } /* Put the operation number here when we have octstr_format */ return octstr_create("(unknown)"); }
/* Return true if a OISD server may send this operation */ static int operation_can_receive(int operation) { int i = operation_find(operation); if (i >= 0) return operations[i].can_receive; /* If we can send the request, then we can receive the response. */ if (operation >= RESPONSE) return operation_can_send(operation - RESPONSE); return 0; }
void parser_push(const context_t *ctx, const line_t *line) { position_t *pos = line->position; // is the first block already set? if (p->blk == NULL) { p->blk = block_init(NULL, pos); } statement_t *stmt = new_statement(ctx); const operation_t *op = NULL; const char *name = NULL; label_t *label = NULL; // allow the tokenizer to fold comma into ",x" etc addressing mode tokens int allow_index = 0; // tokenize the line pstate_t state = P_INIT; tokenizer_t *tok = tokenizer_init(line->line); while (tokenizer_next(tok, allow_index)) { switch(state) { case P_OP: if (tok->type == T_TOKEN && tok->vals.op == OP_COLON) { // accept after label // continue to next stmt->type = S_LABEQPC; statement_push(stmt); stmt = new_statement(ctx); state = P_INIT; break; } if (tok->type == T_TOKEN && tok->vals.op == OP_ASSIGN) { // after label, that's a label value definition stmt->type = S_LABDEF; // next define the label from param state = P_PARAM; break; } // fall-through! case P_INIT: switch(tok->type) { case T_NAME: name = mem_alloc_strn(tok->line + tok->ptr, tok->len); op = operation_find(name); if (op != NULL) { // check if the operation is compatible with the current CPU if (0 == (ctx->cpu->isa & op->isa)) { // TODO: config for either no message or error warn_operation_not_for_cpu(pos, name, ctx->cpu->name); op = NULL; } } if (op == NULL) { // label // TODO: redefinition? label = label_init(ctx, name, pos); if (state == P_OP) { // we already had a label stmt->type = S_LABEQPC; statement_push(stmt); stmt = new_statement(ctx); } stmt->label = label; // expect operation next (but accept labels too) state = P_OP; } else { // operation stmt->op = op; state = P_PARAM; } break; default: // syntax error error_syntax(pos); goto end; break; } break; case P_PARAM: // parse parameters arith_parse(tok, allow_index, &stmt->param); break; default: error_syntax(pos); goto end; break; }; } statement_push(stmt); end: tokenizer_free(tok); }