package doglet.edge;
import nova.Machine;
import nova.Store;
import nova.special;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.math.BigInteger;
/**
* Warranty & Liability
* To the extent permitted by applicable law and unless explicitly
* otherwise agreed upon, XLOG Technologies AG makes no warranties
* regarding the provided information. XLOG Technologies AG assumes
* no liability that any problems might be solved with the information
* provided by XLOG Technologies AG.
*
* Rights & License
* All industrial property rights regarding the information - copyright
* and patent rights in particular - are the sole property of XLOG
* Technologies AG. If the company was not the originator of some
* excerpts, XLOG Technologies AG has at least obtained the right to
* reproduce, change and translate the information.
*
* Reproduction is restricted to the whole unaltered document. Reproduction
* of the information is only allowed for non-commercial uses. Selling,
* giving away or letting of the execution of the library is prohibited.
* The library can be distributed as part of your applications and libraries
* for execution provided this comment remains unchanged.
*
* Restrictions
* Only to be distributed with programs that add significant and primary
* functionality to the library. Not to be distributed with additional
* software intended to replace any components of the library.
*
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies AG.
*/
public class piwamlib {
private static final class PiWam {
private int[] code;
private int[] state;
}
private static void run(PiWam pi) {
int pc = 0;
int accu = 0;
while (pc < pi.code.length) {
int instr = pi.code[pc++];
int value = run_get(pi, instr);
accu = run_fun(instr, accu, value);
run_set(pi, instr, accu);
pc += run_jump(instr, accu);
}
}
private static int run_get(PiWam pi, int instr) {
int act = instr>>20;
int obj = ((instr>>10) & 0x03FF) - 512;
switch ((act>>4) & 0x0F) {
case 0: /* get */
return pi.state[obj];
case 1: /* cst */
return obj;
case 2: /* set */
return 0;
case 4: /* out */
return 0;
case 5: /* in */
System.out.print(": ");
System.out.flush();
return readBig().intValue();
default:
throw new IllegalArgumentException("illegal mode");
}
}
private static int run_fun(int instr, int accu, int value) {
int act = instr>>20;
switch (act>>8) {
case 0: /* val */
return value;
case 1: /* acc */
return accu;
case 2: /* add */
return value + accu;
case 3: /* sub */
return value - accu;
case 4: /* mul */
return value * accu;
case 8: /* nil */
/* t.b.d. */
return 0;
case 9: /* cons */
/* t.b.d. */
return 0;
case 10: /* car */
/* t.b.d. */
return 0;
case 11: /* cdr */
/* t.b.d. */
return 0;
default:
throw new IllegalArgumentException("illegal fun");
}
}
private static void run_set(PiWam pi, int instr, int accu) {
int act = instr>>20;
int obj = ((instr>>10) & 0x03FF) - 512;
switch ((act>>4) & 0x0F) {
case 0: /* get */
return;
case 1: /* cst */
return;
case 2: /* set */
pi.state[obj] = accu;
return;
case 4: /* out */
System.out.println(accu);
return;
case 5: /* in */
return;
default:
throw new IllegalArgumentException("illegal mode");
}
}
private static int run_jump(int instr, int accu) {
int act = instr>>20;
int rel = (instr & 0x03FF) - 512;
switch (act & 0x0F) {
case 0: /* eq */
return (accu == 0 ? rel : 0);
case 1: /* nq */
return (accu != 0 ? rel : 0);
case 2: /* ls */
return (accu < 0 ? rel : 0);
case 3: /* gr */
return (accu > 0 ? rel : 0);
case 4: /* lq */
return (accu <= 0 ? rel : 0);
case 5: /* gq */
return (accu >= 0 ? rel : 0);
case 8: /* unit */
/* t.b.d. */
return 0;
case 9: /* pair */
/* t.b.d. */
return 0;
case 15: /* true */
return rel;
default:
throw new IllegalArgumentException("illegal cond");
}
}
/******************************************************************/
/* π-WAM Input */
/******************************************************************/
private static BigInteger readBig() {
try {
return new BigInteger(
new LineNumberReader(
new InputStreamReader(System.in)).readLine());
} catch (IOException e) {
throw new IllegalArgumentException("read aborted");
} catch (NumberFormatException e) {
throw new IllegalArgumentException("read aborted");
}
}
/******************************************************************/
/* π-WAM Interface */
/******************************************************************/
/**
* test_ir_piwam_new(C, S, P): internal only
* The predicate succeeds in P with a CPU backed π-WAM for
* the code C and the state S.
*/
private static boolean test_ir_piwam_new(Object[] args) {
PiWam pi = new PiWam();
Object alpha = Machine.exec_build(args[0]);
pi.code = list_ints(alpha);
Object beta = Machine.exec_build(args[1]);
pi.state = list_ints(beta);
return Machine.exec_unify(args[2], pi);
}
private static int[] list_ints(Object obj) {
Object peek = obj;
int i = 0;
while (Store.is_structure(peek) &&
".".equals(((Store.Structure) peek).functor) &&
((Store.Structure) peek).args.length == 2 &&
i < special.MAX_ARITY) {
i++;
peek = Store.deref(((Store.Structure) peek).args[1]);
}
special.check_nil(peek);
int[] args = new int[i];
peek = obj;
i = 0;
while (Store.is_structure(peek) &&
".".equals(((Store.Structure) peek).functor) &&
((Store.Structure) peek).args.length == 2) {
Object val = Store.deref(((Store.Structure) peek).args[0]);
special.check_integer(val);
if (val instanceof Integer) {
args[i++] = ((Integer)val).intValue();
} else {
args[i++] = ((BigInteger)val).intValue();
}
peek = Store.deref(((Store.Structure) peek).args[1]);
}
return args;
}
/**
* test_ir_piwam_run(P): internal only
* The predicate fails. As a side effect it will run the
* π-WAM P in the current thread. The predicate terminates
* when the π-WAM P terminates.
*/
private static boolean test_ir_piwam_run(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
run((PiWam)alpha);
return false;
}
/******************************************************************/
/* π-WAM Lib Init */
/******************************************************************/
public static void main() {
Store.set("ir_piwam_new", 3, special.make_check(piwamlib::test_ir_piwam_new));
Store.set("ir_piwam_run", 1, special.make_check(piwamlib::test_ir_piwam_run));
}
}