home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
-
- /* Copyright Herve' Touati, Aquarius Project, UC Berkeley */
-
- #include <stream.h>
- #include "tags.h"
- #include "instr.h"
- #include "hash_table.h"
- #include "string_table.h"
- #include "scan.h"
- #include "inst_args.h"
- #include "inst_table.h"
- #include "memory.h"
- #include "basics.h"
- #include "top_level.h"
- #ifdef WITH_GC
- #include "gc.h"
- #endif
-
- #define max(a,b) (((a) > (b)) ? (a) : (b))
-
- inline void get_variable(Cell& Arg1, Cell Arg2) {
- Arg1 = Arg2;
- }
-
- inline void get_value(Cell Arg1, Cell Arg2) {
- if (! unify(Arg1, Arg2))
- P = FP0;
- }
-
- inline void get_constant(Cell Arg1, Cell Arg2) {
- Arg2 = deref(Arg2);
- if (Arg1 != Arg2) {
- if (get_tag(Arg2) == TAGREF)
- Bind(Arg2, Arg1);
- else
- (P = FP0);
- }
- }
-
-
- /* PUT INSTRUCTIONS */
-
-
- inline void put_variable_X(Cell& Arg1, Cell& Arg2)
- {
- *H = make_ptr(TAGREF, H);
- Arg2 = Arg1 = *H++;
- }
-
- inline void put_variable_Y(Cell& Arg1, Cell& Arg2)
- {
- Arg2 = Arg1 = make_cell(TAGREF, &Arg1);
- }
-
- inline void put_value(Cell Arg1, Cell& Arg2)
- {
- Arg2 = Arg1;
- }
-
- inline void put_unsafe_value(Cell Arg1, Cell& Arg2)
- {
- Arg1 = deref(Arg1);
- if (get_tag(Arg1) == TAGREF && cellp(Arg1) >= E0) {
- *H = make_ptr(TAGREF, H);
- Bind(Arg1, *H++);
- }
- Arg2 = Arg1;
- }
-
- inline void put_structure(Cell atom, Cell& Var, Cell arity)
- {
- Var = make_ptr(TAGSTRUCT, H);
- *H++ = atom;
- *H++ = make_int(arity);
- }
-
- inline void put_list(Cell& Arg1)
- {
- Arg1 = make_ptr(TAGLIST, H);
- }
-
-
-
- /* UNIFY INSTRUCTIONS */
-
-
- inline void unify_void_write()
- {
- *H = make_ptr(TAGREF, H); H++;
- }
-
- inline void unify_void()
- {
- if (MODE == MODE_READ) {
- S++;
- } else {
- unify_void_write();
- }
- }
-
- inline void unify_value_write(Cell Arg1)
- {
- Arg1 = deref(Arg1);
- if (get_tag(Arg1) == TAGREF && cellp(Arg1) >= E0) {
- *H = make_ptr(TAGREF, H);
- Bind(Arg1, *H++);
- } else {
- *H++ = Arg1;
- }
- }
-
- inline void unify_value(Cell Arg1)
- {
- if (MODE == MODE_READ) {
- if (! unify(Arg1, *S++)) {
- P = FP0;
- }
- } else {
- unify_value_write(Arg1);
- }
- }
-
-
- inline void unify_variable_write(Cell& Var)
- {
- *H = make_ptr(TAGREF, H);
- Var = *H++;
- }
-
- inline void unify_variable(Cell& Var)
- {
- if (MODE == MODE_READ)
- Var = *S++;
- else
- unify_variable_write(Var);
- }
-
-
- inline void unify_constant_write(Cell cst)
- {
- *H++ = cst;
- }
-
- inline void unify_constant(Cell Arg1)
- {
- if (MODE == MODE_READ)
- get_constant(Arg1, *S++);
- else
- unify_constant_write(Arg1);
- }
-
-
- /* unify_cdr is no different from unify_variable */
-
-
- inline void get_cdr_list_write()
- {
- *H = make_ptr(TAGLIST, H + 1); H++;
- }
-
- extern HashTable* table_of_tables;
-
- void fast_execute()
- {
- for (;; P++) {
- switch (P->ID) {
- case SWITCH_ON_TERM:
- {
- Cell X0 = deref(X[0]);
- switch(get_tag(X0)) {
- case TAGCONST:
- P = instrp(P->arg1);
- break;
- case TAGLIST:
- P = instrp(P->arg2);
- break;
- case TAGSTRUCT:
- P = instrp(P->arg3);
- break;
- case TAGREF:
- break;
- }
- }
- break;
- case SWITCH_ON_CONSTANT:
- {
- HashTable* table = (HashTable*) table_of_tables->get(P->arg1);
- P = instrp(table->get(deref(X[0])));
- if (table->status == HASH_MISS)
- P = FP0;
- }
- break;
- case SWITCH_ON_STRUCTURE:
- {
- HashTable* table = (HashTable*) table_of_tables->get(P->arg1);
- P = instrp(table->get(*addr(deref(X[0]))));
- if (table->status == HASH_MISS)
- P = FP0;
- }
- break;
- case TRY:
- {
- int number_of_registers = P->arg2;
- B -= FIXED_CP_SIZE + number_of_registers;
- B[E_CP_OFFSET] = cell(E);
- B[H_CP_OFFSET] = cell(H);
- B[TR_CP_OFFSET] = cell(TR);
- B[P_CP_OFFSET] = cell(P);
- B[SIZE_CP_OFFSET] = number_of_registers;
- for (int i = 0; i < number_of_registers; i++)
- B[X1_CP_OFFSET + i] = X[i];
- P = instrp(P->arg1);
- }
- break;
- case RETRY:
- {
- B[P_CP_OFFSET] = cell(P);
- P = instrp(P->arg1);
- }
- break;
- case TRUST:
- {
- B = cellp(E[B_ENV_OFFSET]);
- P = instrp(P->arg1);
- }
- break;
- case TRY_ME_ELSE:
- {
- int number_of_registers = P->arg2;
- B -= FIXED_CP_SIZE + number_of_registers;
- B[E_CP_OFFSET] = cell(E);
- B[H_CP_OFFSET] = cell(H);
- B[TR_CP_OFFSET] = cell(TR);
- B[P_CP_OFFSET] = P->arg1;
- B[SIZE_CP_OFFSET] = number_of_registers;
- for (int i = 0; i < number_of_registers; i++)
- B[X1_CP_OFFSET + i] = X[i];
- }
- break;
- case RETRY_ME_ELSE:
- {
- B[P_CP_OFFSET] = P->arg1;
- }
- break;
- case TRUST_ME_ELSE:
- {
- B = cellp(E[B_ENV_OFFSET]);
- }
- break;
- case FAIL:
- Fail();
- break;
- case CUT:
- {
- B = cellp(E[B_ENV_OFFSET]);
- }
- break;
- case PROCEED:
- {
- P = instrp(E[P_ENV_OFFSET]);
- E = cellp(E[E_ENV_OFFSET]);
- #ifdef WITH_GC
- if (E < E2)
- E2 = E;
- #endif
- }
- break;
- case EXECUTE_PROC:
- {
- if (cellp(B[E_CP_OFFSET]) >= E) {
- Cell* NewE = cellp(B[E_CP_OFFSET]) + E_TOP_OFFSET;
- NewE[B_ENV_OFFSET] = cell(B);
- NewE[E_ENV_OFFSET] = E[E_ENV_OFFSET];
- NewE[P_ENV_OFFSET] = E[P_ENV_OFFSET];
- E = NewE;
- }
-
- #ifdef WITH_GC
- if (H >= HMAXSOFT)
- garbage_collector();
- #else
- if (H > TR)
- top_level_error("Heap Overflow");
- #endif
-
- P = instrp(P->arg1);
- }
- break;
- case EXECUTE_LABEL:
- {
- P = instrp(P->arg1);
- }
- break;
- case CALL:
- {
- Cell* top_for_E = E + P->arg2;
- Cell* top_for_B = cellp(B[E_CP_OFFSET]);
- Cell* NewE = max(top_for_E, top_for_B) + E_TOP_OFFSET;
- NewE[B_ENV_OFFSET] = cell(B);
- NewE[E_ENV_OFFSET] = cell(E);
- NewE[P_ENV_OFFSET] = cell(P);
- E = NewE;
-
- #ifdef WITH_GC
- if (H >= HMAXSOFT)
- garbage_collector();
- #else
- if (H > TR)
- top_level_error("Heap Overflow");
- #endif
-
- P = instrp(P->arg1);
- }
- break;
- case ESCAPE:
- {
- (*procp(P->arg1))();
- }
- break;
- case INIT:
- {
- Cell* var = &E[P->arg1];
- *var = make_cell(TAGREF, var);
- }
- break;
- case GET_VARIABLE_X:
- {
- get_variable(X[P->arg1], X[P->arg2]);
- }
- break;
- case GET_VARIABLE_Y:
- {
- get_variable(E[P->arg1], X[P->arg2]);
- }
- break;
- case GET_VALUE_X:
- {
- get_value(X[P->arg1], X[P->arg2]);
- }
- break;
- case GET_VALUE_Y:
- {
- get_value(E[P->arg1], X[P->arg2]);
- }
- break;
- case GET_CONSTANT:
- {
- get_constant(P->arg1, X[P->arg2]);
- }
- break;
- case GET_NIL:
- {
- get_constant(NIL, X[P->arg1]);
- }
- break;
- case GET_STRUCTURE:
- {
- Cell var = deref(X[P->arg2]);
- if (get_tag(var) == TAGREF) {
- MODE = MODE_WRITE;
- Bind(var, make_ptr(TAGSTRUCT, H));
- *H++ = P->arg1;
- *H++ = make_int(P->arg3);
- } else if (get_tag(var) == TAGSTRUCT && rvalue(var) == P->arg1) {
- MODE = MODE_READ;
- S = addr(var) + 2;
- } else {
- P = FP0;
- }
- }
- break;
- case GET_LIST:
- {
- Cell Var = deref(X[P->arg1]);
- switch (get_tag(Var)) {
- case TAGREF:
- MODE = MODE_WRITE;
- Bind(Var, make_ptr(TAGLIST, H));
- break;
- case TAGLIST:
- MODE = MODE_READ;
- S = addr(Var);
- break;
- default:
- P = FP0;
- break;
- }
- }
- break;
- case GET_CDR_LIST:
- {
- if (MODE == MODE_READ) {
- Cell Var = deref(*S++);
- if (get_tag(Var) == TAGLIST) {
- S = addr(Var);
- } else if (get_tag(Var) == TAGREF) {
- MODE = MODE_WRITE;
- Bind(Var, make_ptr(TAGLIST, H));
- } else {
- P = FP0;
- }
- } else {
- get_cdr_list_write();
- }
- }
- break;
- case GET_CDR_LIST_WRITE:
- {
- get_cdr_list_write();
- }
- break;
- case PUT_VARIABLE_X:
- {
- put_variable_X(X[P->arg1], X[P->arg2]);
- }
- break;
- case PUT_VARIABLE_Y:
- {
- put_variable_Y(E[P->arg1], X[P->arg2]);
- }
- break;
- case PUT_VALUE_X:
- {
- put_value(X[P->arg1], X[P->arg2]);
- }
- break;
- case PUT_VALUE_Y:
- {
- put_value(E[P->arg1], X[P->arg2]);
- }
- break;
- case PUT_UNSAFE_VALUE:
- {
- put_unsafe_value(E[P->arg1], X[P->arg2]);
- }
- break;
- case PUT_CONSTANT:
- {
- put_value(P->arg1, X[P->arg2]);
- }
- break;
- case PUT_NIL:
- {
- put_value(NIL, X[P->arg1]);
- }
- break;
- case PUT_STRUCTURE:
- {
- put_structure(P->arg1, X[P->arg2], P->arg3);
- }
- break;
- case PUT_LIST:
- {
- put_list(X[P->arg1]);
- }
- break;
- case UNIFY_VOID:
- {
- unify_void();
- }
- break;
- case UNIFY_VOID_WRITE:
- {
- unify_void_write();
- }
- break;
- case UNIFY_VALUE_X:
- {
- unify_value(X[P->arg1]);
- }
- break;
- case UNIFY_VALUE_Y:
- {
- unify_value(E[P->arg1]);
- }
- break;
- case UNIFY_VALUE_WRITE_X:
- {
- unify_value_write(X[P->arg1]);
- }
- break;
- case UNIFY_VALUE_WRITE_Y:
- {
- unify_value_write(E[P->arg1]);
- }
- break;
- case UNIFY_VARIABLE_X:
- {
- unify_variable(X[P->arg1]);
- }
- break;
- case UNIFY_VARIABLE_Y:
- {
- unify_variable(E[P->arg1]);
- }
- break;
- case UNIFY_VARIABLE_WRITE_X:
- {
- unify_variable_write(X[P->arg1]);
- }
- break;
- case UNIFY_VARIABLE_WRITE_Y:
- {
- unify_variable_write(E[P->arg1]);
- }
- break;
- case UNIFY_UNSAFE_VALUE:
- {
- unify_value(E[P->arg1]);
- }
- break;
- case UNIFY_UNSAFE_VALUE_WRITE:
- {
- unify_value_write(E[P->arg1]);
- }
- break;
- case UNIFY_CONSTANT:
- {
- unify_constant(P->arg1);
- }
- break;
- case UNIFY_CONSTANT_WRITE:
- {
- unify_constant_write(P->arg1);
- }
- break;
- case UNIFY_NIL:
- {
- unify_constant(NIL);
- }
- break;
- case UNIFY_NIL_WRITE:
- {
- unify_constant_write(NIL);
- }
- break;
- case HALT:
- Halt();
- break;
- }
- }
- }
-