void expected4(tok_kind exp1, tok_kind exp2, tok_kind exp3, tok_kind exp4) { sprintf(expectbuf, "expected '%s', '%s', '%s', or '%s'", toktostr(exp1), toktostr(exp2), toktostr(exp3), toktostr(exp4)); error(expectbuf); }
/* * error, token encountered was not one of 3 expected ones */ void expected3(tok_kind exp1, tok_kind exp2, tok_kind exp3) { s_print(expectbuf, "expected '%s', '%s' or '%s'", toktostr(exp1), toktostr(exp2), toktostr(exp3)); error(expectbuf); }
/* * error, token encountered was not the expected one */ void expected1 (tok_kind exp1) { s_print (expectbuf, "expected '%s'", toktostr (exp1)); error (expectbuf); }
void parseline(list *instructions, list *labels) { start: ;; dcpu16token tok = nexttoken(); if (tok == T_COLON) { /* Label definition */ if ((tok = nexttoken()) == T_IDENTIFIER) { dcpu16label *l = getnewlabel(labels, cur_tok.string); if (l->defined) error("Redefinition of label '%s' (%04X -> %04X) forbidden", l->label, l->pc, pc); l->pc = pc; l->defined = 1; goto start; } else { error("Expected label, got %s", toktostr(tok)); } } else if (is_instruction(tok)) { dcpu16instruction instr, *newinstr; instr.opcode = tok; instr.a = parseoperand(labels); if (!is_nonbasic_instruction(tok)) { if ((tok = nexttoken()) == T_COMMA) { instr.b = parseoperand(labels); } else { error("Expected ',', got %s", toktostr(tok)); } } if ((tok = nexttoken()) != T_NEWLINE) error("Expected EOL, got %s", toktostr(tok)); /* * All tokens valid, store instructions, advance PC */ newinstr = malloc(sizeof(dcpu16instruction)); memcpy(newinstr, &instr, sizeof(dcpu16instruction)); newinstr->pc = pc; newinstr->line = curline; list_push_back(instructions, newinstr); pc += instruction_length(newinstr); } else if (is_macro(tok)) { if (tok == T_ORG) { if ((tok = nexttoken()) == T_NUMBER) { if (flag_paranoid && (cur_tok.number < pc)) { warning("new origin precedes old origin! " "This could cause already written code to be " "overriden."); } pc = cur_tok.number; } else { error("Expected numeric, got %s", toktostr(tok)); } } else if (tok == T_DAT) { /* All of the stuff we are about to read, neatly packed * into words */ list_node *p = NULL; list *data = list_create(); do { if ((tok = nexttoken()) == T_STRING) { char *ptr = cur_tok.string; while (*ptr != '\0') { uint16_t *dat = malloc(sizeof(uint16_t)); *dat = *ptr++; list_push_back(data, dat); } } else if (tok == T_NUMBER) { uint16_t *dat = malloc(sizeof(uint16_t)); *dat = cur_tok.number; list_push_back(data, dat); } else { error("Expected string or numeric, got %s", toktostr(tok)); } if ((tok = nexttoken()) == T_COMMA) continue; else if (tok == T_NEWLINE) break; else error("Expected ',' or EOL, got %s", toktostr(tok)); } while (1); /* ram[pc++] = cur_tok.number; */ for (p = list_get_root(data); p != NULL; p = p->next) { ram[pc++] = *((uint16_t*)p->data); } list_dispose(&data, &free); } } else if (tok == T_NEWLINE) { return; } else { error("Expected label-definition or opcode, got %s", toktostr(tok)); } }
dcpu16operand parseoperand(list *labels) { dcpu16operand op = {0}; dcpu16token tok; op.addressing = IMMEDIATE; if ((tok = nexttoken()) == T_IDENTIFIER) { /* label */ op.type = LABEL; op.label = getnewlabel(labels, cur_tok.string)->label; } else if (tok == T_NUMBER) { /* numeric */ op.type = LITERAL; op.numeric = cur_tok.number; } else if (is_register(tok) || is_status_register(tok) || is_stack_operation(tok)) { /* register */ /* * For all intents and purposes, stack operations, registers and * status registers are equivalent in usage for immediate addressing, * so we might as well classify them all as REGISTER */ op.type = REGISTER; op.token = tok; } else if (tok == T_LBRACK) { /* [reference] */ dcpu16token a = nexttoken(); op.addressing = REFERENCE; if (a == T_NUMBER) { /* [numeric] */ op.type = LITERAL; op.numeric = cur_tok.number; } else if (is_register(a)) { /* [register] */ op.type = REGISTER; op.token = a; } else if (a == T_IDENTIFIER) { /* [label] */ op.type = LABEL; op.label = getnewlabel(labels, cur_tok.string)->label; } else { error("Expected numeric, register or label, got %s", toktostr(a)); } /* First part parsed correctly so far, now either ']' or '+' * follows */ if (((tok = nexttoken()) != T_RBRACK) && (tok != T_PLUS)) error("Expected '+' or ']', got %s", toktostr(tok)); if (tok == T_RBRACK) { /* [numeric], [register], [label] checks out */ return op; } else { dcpu16token b = nexttoken(); op.type = REGISTER_OFFSET; if (is_register(a)) { /* [register + label], [register + numeric] */ if (b == T_IDENTIFIER) { op.register_offset.type = LABEL; op.register_offset.register_index = a; op.register_offset.label = getnewlabel(labels, cur_tok.string)->label; } else if (b == T_NUMBER) { op.register_offset.type = LITERAL; op.register_offset.register_index = a; op.register_offset.offset = cur_tok.number; } else { error("Expected numeric or label, got %s", toktostr(b)); } } else { /* [numeric + register], [label + register] */ if (is_register(b)) { op.register_offset.register_index = b; if (a == T_NUMBER) { op.register_offset.type = LITERAL; op.register_offset.offset = cur_tok.number; } else { op.register_offset.type = LABEL; op.register_offset.label = getnewlabel(labels, cur_tok.string)->label; } } else { error("Expected register, got %s", toktostr(b)); } } if (nexttoken() != T_RBRACK) error("Expected ']'"); } } else { error("Expected register, label, numeric or '[', got %s", toktostr(tok)); } return op; }
static int get_sub_suf (const char *exstr, char **psub, char **psuffix) { int status; // valid sub? Histlist h; // ptr to hist node to be substituted, or NULL char *desig_start; // ptr to after event in exstr int desig_len; // length of desig; 0 if desig not specified // "!!" if (exstr[1] == '!') { get_nthlast(&h, 1); *psub = toktostr(h,exstr+2,&desig_len); *psuffix = malloc (sizeof(char) * (strlen(exstr+2+desig_len) + 1)); strcpy(*psuffix, exstr+2+desig_len); } // "!N" else if (strspn(exstr+1, "0123456789")) { int spn = strspn(exstr+1,"0123456789"); int n = strtol(exstr+1, &desig_start, 10); get_cmd(&h, n); *psub = toktostr(h,exstr+1+spn,&desig_len); *psuffix = malloc (sizeof(char) * (strlen(desig_start+desig_len) + 1)); strcpy(*psuffix, desig_start+desig_len); } // "!-N" else if (exstr[1] == '-' && strspn(exstr+2, "0123456789")) { int n = strtol(exstr+2, &desig_start, 10); int spn = strspn(exstr+2, "0123456789"); get_nthlast(&h, n); *psub = toktostr(h,exstr+2+spn,&desig_len); *psuffix = malloc (sizeof(char) * (strlen(desig_start+desig_len) + 1)); strcpy(*psuffix, desig_start+desig_len); } // "!?[...]" else if (exstr[1] == '?') { int string_len = strcspn(exstr+2, " !?\n"); if (string_len) { // "!?STRING[...]" // "!?STRING\n" or "!?STRING?[...]" if (exstr[2+string_len] == '\n' || exstr[2+string_len] == '?' ) { // extract STRING char *s = malloc(sizeof(char) * (string_len + 1)); strncpy (s, exstr+2, string_len); s[string_len] = '\0'; get_match(&h, s); *psub = toktostr(h,exstr+2+string_len+1,&desig_len); // potentially lose '\n' here... if (exstr[2+string_len] == '?') { *psuffix = malloc (sizeof(char) * (strlen(exstr+2+string_len+1+desig_len) + 1)); strcpy(*psuffix, exstr+2+string_len+1+desig_len); } else if (exstr[2+string_len] == '\n') { // no designator, suffix includes '\n' *psuffix = malloc (sizeof(char) * (strlen(exstr+2+string_len) + 1)); strcpy(*psuffix, exstr+2+string_len); } free(s); } else { // not an event *psub = NULL; *psuffix = malloc (sizeof(char) * (strlen(exstr) + 1)); strcpy (*psuffix, exstr); return 0; } } else { // not an event *psub = NULL; *psuffix = malloc (sizeof(char) * (strlen(exstr) + 1)); strcpy (*psuffix, exstr); return 0; } } // "![...]" not an event else { *psub = NULL; *psuffix = malloc (sizeof(char) * (strlen(exstr) + 1)); strcpy (*psuffix, exstr); return 0; } // if event, return status of substitution status = (*psub == NULL ? -1 : 1); return status; }