*/ static void Loop_Number(REBVAL *out, REBVAL *var, REBSER* body, REBVAL *start, REBVAL *end, REBVAL *incr) /* ***********************************************************************/ { REBDEC s; REBDEC e; REBDEC i; if (IS_INTEGER(start)) s = cast(REBDEC, VAL_INT64(start)); else if (IS_DECIMAL(start) || IS_PERCENT(start)) s = VAL_DECIMAL(start); else { Trap_Arg(start); DEAD_END_VOID; } if (IS_INTEGER(end)) e = cast(REBDEC, VAL_INT64(end)); else if (IS_DECIMAL(end) || IS_PERCENT(end)) e = VAL_DECIMAL(end); else { Trap_Arg(end); DEAD_END_VOID; } if (IS_INTEGER(incr)) i = cast(REBDEC, VAL_INT64(incr)); else if (IS_DECIMAL(incr) || IS_PERCENT(incr)) i = VAL_DECIMAL(incr); else { Trap_Arg(incr); DEAD_END_VOID; } VAL_SET(var, REB_DECIMAL); SET_NONE(out); // Default result to NONE if the loop does not run for (; (i > 0.0) ? s <= e : s >= e; s += i) { VAL_DECIMAL(var) = s; if (!DO_BLOCK(out, body, 0) && Check_Error(out) >= 0) break; if (!IS_DECIMAL(var)) Trap_Type(var); s = VAL_DECIMAL(var); } }
*/ static void Loop_Series(REBVAL *out, REBVAL *var, REBSER* body, REBVAL *start, REBINT ei, REBINT ii) /* ***********************************************************************/ { REBINT si = VAL_INDEX(start); REBCNT type = VAL_TYPE(start); *var = *start; if (ei >= cast(REBINT, VAL_TAIL(start))) ei = cast(REBINT, VAL_TAIL(start)); if (ei < 0) ei = 0; SET_NONE(out); // Default result to NONE if the loop does not run for (; (ii > 0) ? si <= ei : si >= ei; si += ii) { VAL_INDEX(var) = si; if (!DO_BLOCK(out, body, 0) && Check_Error(out) >= 0) break; if (VAL_TYPE(var) != type) Trap1(RE_INVALID_TYPE, var); si = VAL_INDEX(var); } }
*/ static void Loop_Number(REBVAL *var, REBSER* body, REBVAL *start, REBVAL *end, REBVAL *incr) /* ***********************************************************************/ { REBVAL *result; REBDEC s; REBDEC e; REBDEC i; if (IS_INTEGER(start)) s = (REBDEC)VAL_INT64(start); else if (IS_DECIMAL(start) || IS_PERCENT(start)) s = VAL_DECIMAL(start); else Trap_Arg(start); if (IS_INTEGER(end)) e = (REBDEC)VAL_INT64(end); else if (IS_DECIMAL(end) || IS_PERCENT(end)) e = VAL_DECIMAL(end); else Trap_Arg(end); if (IS_INTEGER(incr)) i = (REBDEC)VAL_INT64(incr); else if (IS_DECIMAL(incr) || IS_PERCENT(incr)) i = VAL_DECIMAL(incr); else Trap_Arg(incr); VAL_SET(var, REB_DECIMAL); for (; (i > 0.0) ? s <= e : s >= e; s += i) { VAL_DECIMAL(var) = s; result = Do_Blk(body, 0); if (THROWN(result) && Check_Error(result) >= 0) break; if (!IS_DECIMAL(var)) Trap_Type(var); s = VAL_DECIMAL(var); } }
int main() { cpu* the_cpu = Cpu_Construct(); if (the_cpu == NULL) { printf ("Cpu_Construct was failed"); return -1; } FILE* output = fopen ("output.txt", "w"); FILE* the_log = fopen ("the_log.txt", "w"); OUT printf ("# This is an emulator of Intel Core i7\n" "# The developer: Yura Gorishniy <*****@*****.**>\n" "# Version 4.00\n" "# The file: %s\n" "# The compilation time: %s, %s\n\n", strrchr (__FILE__, '\\'), __DATE__, __TIME__); FILE* the_program = fopen ("the_program.txt", "r"); FILE* binary = fopen ("binary.txt", "w"); Check_Error (the_asm (the_program, binary, the_log), the_log); fclose (binary); fclose (the_program); the_program = fopen ("the_program.txt", "r"); binary = fopen ("binary.txt", "w"); Check_Error (the_asm (the_program, binary, the_log), the_log); fclose (binary); binary = fopen ("binary.txt", "r"); Check_Error (Cpu_Load (the_cpu, binary), the_log); Check_Error (Cpu_Run (the_cpu, output, the_log), the_log); fclose (the_log); fclose (the_program); fclose (binary); fclose (output); return 0; }
*/ static void Loop_Integer(REBVAL *var, REBSER* body, REBI64 start, REBI64 end, REBI64 incr) /* ***********************************************************************/ { REBVAL *result; VAL_SET(var, REB_INTEGER); while ((incr > 0) ? start <= end : start >= end) { VAL_INT64(var) = start; result = Do_Blk(body, 0); if (THROWN(result) && Check_Error(result) >= 0) break; if (!IS_INTEGER(var)) Trap_Type(var); start = VAL_INT64(var); if (REB_I64_ADD_OF(start, incr, &start)) { Trap0(RE_OVERFLOW); } } }
*/ static void Loop_Integer(REBVAL *out, REBVAL *var, REBSER* body, REBI64 start, REBI64 end, REBI64 incr) /* ***********************************************************************/ { VAL_SET(var, REB_INTEGER); SET_NONE(out); // Default result to NONE if the loop does not run while ((incr > 0) ? start <= end : start >= end) { VAL_INT64(var) = start; if (!DO_BLOCK(out, body, 0) && Check_Error(out) >= 0) break; if (!IS_INTEGER(var)) Trap_Type(var); start = VAL_INT64(var); if (REB_I64_ADD_OF(start, incr, &start)) { Trap(RE_OVERFLOW); } } }
*/ static void Loop_Series(REBVAL *var, REBSER* body, REBVAL *start, REBINT ei, REBINT ii) /* ***********************************************************************/ { REBVAL *result; REBINT si = VAL_INDEX(start); REBCNT type = VAL_TYPE(start); *var = *start; if (ei >= (REBINT)VAL_TAIL(start)) ei = (REBINT)VAL_TAIL(start); if (ei < 0) ei = 0; for (; (ii > 0) ? si <= ei : si >= ei; si += ii) { VAL_INDEX(var) = si; result = Do_Blk(body, 0); if (THROWN(result) && Check_Error(result) >= 0) break; if (VAL_TYPE(var) != type) Trap1(RE_INVALID_TYPE, var); si = VAL_INDEX(var); } }
int main() { FILE* the_expression = fopen ("the_expression.txt", "r"); assert (THE_LOG); assert (the_expression); node* exp_tree = Node_NEW(); Check_Error (Tree_Read_in (the_expression, exp_tree)); int nTabs = 0; Tree_Dump (exp_tree, nTabs); fprintf (THE_LOG, "\n\n\n"); Tree_Print (exp_tree); Tree_Delete (exp_tree); fclose (the_expression); fclose (THE_LOG); return 0; }
int Node_Dump (node* my_node) { //fprintf (LOG, "\n=================================================="); char tmp_type[TMPLEN] = {}; DEF_TYPE (my_node -> type); fprintf (LOG, "{%s}\t", tmp_type); switch (my_node -> type) { case PGM: case OP: case OP_PRINT: case OP_IF: case OP_WHILE: case OP_ASSIGN: case OP_ELSE: break; case FUNC: case MATH_OP: case CMP: fprintf (LOG, "[%d]", my_node -> op); break; case VAR: case STR: fprintf (LOG, "[%s]", my_node -> word); break; case NUMBER: fprintf (LOG, "[%lg]", my_node -> num); break; } int err_index = Node_OK (my_node); if (err_index == HAPPY) fprintf (LOG, "\t\t\tNode [%.8x] is OK\t", my_node); else { fprintf (LOG, "Node [%.8x] is NOT ok!\t", my_node); Check_Error (err_index); fputc ('\n', LOG); return HAPPY; } fprintf (LOG, "left [%.8x] right [%.8x] prev [%.8x]\n", my_node -> left, my_node -> right, my_node -> prev); return HAPPY; }
*/ static REB_R Loop_Each(struct Reb_Call *call_, REBINT mode) /* ** Supports these natives (modes): ** 0: foreach ** 1: remove-each ** 2: map ** ***********************************************************************/ { REBSER *body; REBVAL *vars; REBVAL *words; REBSER *frame; REBVAL *value; REBSER *series; REBSER *out; // output block (for MAP, mode = 2) REBINT index; // !!!! should these be REBCNT? REBINT tail; REBINT windex; // write REBINT rindex; // read REBINT err; REBCNT i; REBCNT j; REBVAL *ds; assert(mode >= 0 && mode < 3); value = D_ARG(2); // series if (IS_NONE(value)) return R_NONE; body = Init_Loop(D_ARG(1), D_ARG(3), &frame); // vars, body SET_OBJECT(D_ARG(1), frame); // keep GC safe Set_Block(D_ARG(3), body); // keep GC safe SET_NONE(D_OUT); // Default result to NONE if the loop does not run // If it's MAP, create result block: if (mode == 2) { out = Make_Block(VAL_LEN(value)); SAVE_SERIES(out); } // Get series info: if (ANY_OBJECT(value)) { series = VAL_OBJ_FRAME(value); out = FRM_WORD_SERIES(series); // words (the out local reused) index = 1; //if (frame->tail > 3) Trap_Arg_DEAD_END(FRM_WORD(frame, 3)); } else if (IS_MAP(value)) { series = VAL_SERIES(value); index = 0; //if (frame->tail > 3) Trap_Arg_DEAD_END(FRM_WORD(frame, 3)); } else { series = VAL_SERIES(value); index = VAL_INDEX(value); if (index >= cast(REBINT, SERIES_TAIL(series))) { if (mode == 1) { SET_INTEGER(D_OUT, 0); } else if (mode == 2) { Set_Block(D_OUT, out); UNSAVE_SERIES(out); } return R_OUT; } } windex = index; // Iterate over each value in the series block: while (index < (tail = SERIES_TAIL(series))) { rindex = index; // remember starting spot j = 0; // Set the FOREACH loop variables from the series: for (i = 1; i < frame->tail; i++) { vars = FRM_VALUE(frame, i); words = FRM_WORD(frame, i); // var spec is WORD if (IS_WORD(words)) { if (index < tail) { if (ANY_BLOCK(value)) { *vars = *BLK_SKIP(series, index); } else if (ANY_OBJECT(value)) { if (!VAL_GET_EXT(BLK_SKIP(out, index), EXT_WORD_HIDE)) { // Alternate between word and value parts of object: if (j == 0) { Init_Word(vars, REB_WORD, VAL_WORD_SYM(BLK_SKIP(out, index)), series, index); if (NOT_END(vars+1)) index--; // reset index for the value part } else if (j == 1) *vars = *BLK_SKIP(series, index); else Trap_Arg_DEAD_END(words); j++; } else { // Do not evaluate this iteration index++; goto skip_hidden; } } else if (IS_VECTOR(value)) { Set_Vector_Value(vars, series, index); } else if (IS_MAP(value)) { REBVAL *val = BLK_SKIP(series, index | 1); if (!IS_NONE(val)) { if (j == 0) { *vars = *BLK_SKIP(series, index & ~1); if (IS_END(vars+1)) index++; // only words } else if (j == 1) *vars = *BLK_SKIP(series, index); else Trap_Arg_DEAD_END(words); j++; } else { index += 2; goto skip_hidden; } } else { // A string or binary if (IS_BINARY(value)) { SET_INTEGER(vars, (REBI64)(BIN_HEAD(series)[index])); } else if (IS_IMAGE(value)) { Set_Tuple_Pixel(BIN_SKIP(series, index), vars); } else { VAL_SET(vars, REB_CHAR); VAL_CHAR(vars) = GET_ANY_CHAR(series, index); } } index++; } else SET_NONE(vars); } // var spec is SET_WORD: else if (IS_SET_WORD(words)) { if (ANY_OBJECT(value) || IS_MAP(value)) { *vars = *value; } else { VAL_SET(vars, REB_BLOCK); VAL_SERIES(vars) = series; VAL_INDEX(vars) = index; } //if (index < tail) index++; // do not increment block. } else Trap_Arg_DEAD_END(words); } if (index == rindex) index++; //the word block has only set-words: foreach [a:] [1 2 3][] if (!DO_BLOCK(D_OUT, body, 0)) { if ((err = Check_Error(D_OUT)) >= 0) { index = rindex; break; } // else CONTINUE: if (mode == 1) SET_FALSE(D_OUT); // keep the value (for mode == 1) } else { err = 0; // prevent later test against uninitialized value } if (mode > 0) { //if (ANY_OBJECT(value)) Trap_Types_DEAD_END(words, REB_BLOCK, VAL_TYPE(value)); //check not needed // If FALSE return, copy values to the write location: if (mode == 1) { // remove-each if (IS_CONDITIONAL_FALSE(D_OUT)) { REBCNT wide = SERIES_WIDE(series); // memory areas may overlap, so use memmove and not memcpy! memmove(series->data + (windex * wide), series->data + (rindex * wide), (index - rindex) * wide); windex += index - rindex; // old: while (rindex < index) *BLK_SKIP(series, windex++) = *BLK_SKIP(series, rindex++); } } else if (!IS_UNSET(D_OUT)) Append_Value(out, D_OUT); // (mode == 2) } skip_hidden: ; } // Finish up: if (mode == 1) { // Remove hole (updates tail): if (windex < index) Remove_Series(series, windex, index - windex); SET_INTEGER(D_OUT, index - windex); return R_OUT; } // If MAP... if (mode == 2) { UNSAVE_SERIES(out); if (err != 2) { // ...and not BREAK/RETURN: Set_Block(D_OUT, out); return R_OUT; } } return R_OUT; }
*/ static int Loop_All(struct Reb_Call *call_, REBINT mode) /* ** 0: forall ** 1: forskip ** ***********************************************************************/ { REBVAL *var; REBSER *body; REBCNT bodi; REBSER *dat; REBINT idx; REBINT inc = 1; REBCNT type; REBVAL *ds; var = GET_MUTABLE_VAR(D_ARG(1)); if (IS_NONE(var)) return R_NONE; // Save the starting var value: *D_ARG(1) = *var; SET_NONE(D_OUT); if (mode == 1) inc = Int32(D_ARG(2)); type = VAL_TYPE(var); body = VAL_SERIES(D_ARG(mode+2)); bodi = VAL_INDEX(D_ARG(mode+2)); // Starting location when past end with negative skip: if (inc < 0 && VAL_INDEX(var) >= VAL_TAIL(var)) { VAL_INDEX(var) = VAL_TAIL(var) + inc; } // NOTE: This math only works for index in positive ranges! if (ANY_SERIES(var)) { while (TRUE) { dat = VAL_SERIES(var); idx = VAL_INDEX(var); if (idx < 0) break; if (idx >= cast(REBINT, SERIES_TAIL(dat))) { if (inc >= 0) break; idx = SERIES_TAIL(dat) + inc; // negative if (idx < 0) break; VAL_INDEX(var) = idx; } if (!DO_BLOCK(D_OUT, body, bodi)) { // Break, throw, continue, error. if (Check_Error(D_OUT) >= 0) { break; } } if (VAL_TYPE(var) != type) Trap_Arg_DEAD_END(var); VAL_INDEX(var) += inc; } } else Trap_Arg_DEAD_END(var); // !!!!! ???? allowed to write VAR???? *var = *D_ARG(1); return R_OUT; }
//======================================================================================================== int Cpu_Run (cpu* my_cpu, FILE* output) { ASSERT_CPU_OK (my_cpu); int cur = 0; int command = 0; int exit = 0; double a = 0; //temporary value double b = 0; //temporary value for (cur = 0; cur < CODES_SIZE; ++cur) { if (exit) break; command = int (my_cpu -> codes[cur]); OUT printf ("***%d\n", command); switch (command) { case CMD_PUSH: case CMD_PUSH_RX: case CMD_PUSH_VAR: Check_Error (Cpu_Push (my_cpu, &cur, command)); break; case CMD_DUP: Check_Error (Cpu_Dup (my_cpu)); break; case CMD_POP: case CMD_POP_VAR: Check_Error (Cpu_Pop (my_cpu, &cur)); break; case CMD_IN: case CMD_IN_RX: case CMD_IN_VAR: Check_Error (Cpu_In (my_cpu, &cur, command)); break; case CMD_OUT: case CMD_OUT_RX: case CMD_OUT_CH: case CMD_OUT_VAR: Check_Error (Cpu_Out (my_cpu, &cur, command, output)); break; case CMD_MOV: case CMD_MOV_RX: Check_Error (Cpu_Mov (my_cpu, &cur, command)); break; case CMD_ADD: Check_Error (Cpu_Add (my_cpu)); break; case CMD_SUB: Check_Error (Cpu_Sub (my_cpu)); break; case CMD_MUL: Check_Error (Cpu_Mul (my_cpu)); break; case CMD_DIV: Check_Error (Cpu_Div (my_cpu)); break; case CMD_SQR: Check_Error (Cpu_Sqr (my_cpu)); break; case CMD_POW: Check_Error (Cpu_Pow (my_cpu)); break; case CMD_SQRT: Check_Error (Cpu_Sqrt (my_cpu)); break; case CMD_SIN: Check_Error (Cpu_Sin (my_cpu)); break; case CMD_COS: Check_Error (Cpu_Cos (my_cpu)); break; case CMD_TAN: Check_Error (Cpu_Tan (my_cpu)); break; case CMD_CTAN: Check_Error (Cpu_Ctan (my_cpu)); break; case CMD_DUMP: Cpu_Dump (my_cpu); break; case CMD_END: Check_Error (Cpu_End (my_cpu, output, &exit)); break; case CMD_CALL: my_cpu -> call_funcs -> Push (cur + 1); cur = int (my_cpu -> codes[cur + 1] - 1); break; case CMD_RET: my_cpu -> call_funcs -> Pop (&a); cur = int(a); break; case CMD_JMP: cur = int (my_cpu -> codes[cur + 1] - 1); break; case CMD_JB: if (my_cpu -> cpu_stack -> size_now < 2) return ERR_JB; my_cpu -> cpu_stack -> Pop (&b); my_cpu -> cpu_stack -> Pop (&a); if (a < b) cur = int (my_cpu -> codes[cur + 1] - 1); else ++cur; break; case CMD_JBE: if (my_cpu -> cpu_stack -> size_now < 2) return ERR_JBE; my_cpu -> cpu_stack -> Pop (&b); my_cpu -> cpu_stack -> Pop (&a); if (a <= b) cur = int (my_cpu -> codes[cur + 1] - 1); else ++cur; break; case CMD_JE: if (my_cpu -> cpu_stack -> size_now < 2) return ERR_JE; my_cpu -> cpu_stack -> Pop (&b); my_cpu -> cpu_stack -> Pop (&a); if (a == b) cur = int (my_cpu -> codes[cur + 1] - 1); else ++cur; break; case CMD_JAE: if (my_cpu -> cpu_stack -> size_now < 2) return ERR_JAE; my_cpu -> cpu_stack -> Pop (&b); my_cpu -> cpu_stack -> Pop (&a); if (a >= b) cur = int (my_cpu -> codes[cur + 1] - 1); else ++cur; break; case CMD_JA: if (my_cpu -> cpu_stack -> size_now < 2) return ERR_JA; my_cpu -> cpu_stack -> Pop (&b); my_cpu -> cpu_stack -> Pop (&a); if (a > b) cur = int (my_cpu -> codes[cur + 1] - 1); else ++cur; break; case CMD_JUE: if (my_cpu -> cpu_stack -> size_now < 2) return ERR_JUE; my_cpu -> cpu_stack -> Pop (&b); my_cpu -> cpu_stack -> Pop (&a); if (a != b) cur = int (my_cpu -> codes[cur + 1] - 1); else ++cur; break; default: fprintf (LOG, "\nCPU got wrong command\n" "Your command doesn't exist. " "Current number of the command = [%d], the command = [%d]\n", cur, command); return ERR_RUN_WRONG_CMD; break; } } ASSERT_CPU_OK (my_cpu); return HAPPY; }
*/ static int Loop_All(REBVAL *ds, REBINT mode) /* ** 0: forall ** 1: forskip ** ***********************************************************************/ { REBVAL *var; REBSER *body; REBCNT bodi; REBSER *dat; REBINT idx; REBINT inc = 1; REBCNT type; var = Get_Var(D_ARG(1)); if (IS_NONE(var)) return R_NONE; // Save the starting var value: *D_ARG(1) = *var; SET_NONE(D_RET); if (mode == 1) inc = Int32(D_ARG(2)); type = VAL_TYPE(var); body = VAL_SERIES(D_ARG(mode+2)); bodi = VAL_INDEX(D_ARG(mode+2)); // Starting location when past end with negative skip: if (inc < 0 && VAL_INDEX(var) >= (REBINT)VAL_TAIL(var)) { VAL_INDEX(var) = (REBINT)VAL_TAIL(var) + inc; } // NOTE: This math only works for index in positive ranges! if (ANY_SERIES(var)) { while (TRUE) { dat = VAL_SERIES(var); idx = (REBINT)VAL_INDEX(var); if (idx < 0) break; if (idx >= (REBINT)SERIES_TAIL(dat)) { if (inc >= 0) break; idx = (REBINT)SERIES_TAIL(dat) + inc; // negative if (idx < 0) break; VAL_INDEX(var) = idx; } ds = Do_Blk(body, bodi); // (may move stack) if (THROWN(ds)) { // Break, throw, continue, error. if (Check_Error(ds) >= 0) { *DS_RETURN = *DS_NEXT; break; } } *DS_RETURN = *ds; if (VAL_TYPE(var) != type) Trap_Arg(var); VAL_INDEX(var) += inc; } } else Trap_Arg(var); // !!!!! ???? allowed to write VAR???? *var = *DS_ARG(1); return R_RET; }