mpdm_t mpsl_mkins(wchar_t * opcode, int args, mpdm_t a1, mpdm_t a2, mpdm_t a3, mpdm_t a4) /* creates an instruction */ { mpdm_t o; mpdm_t v; v = MPDM_A(args + 1); mpdm_ref(v); /* inserts the opcode */ o = mpdm_hget_s(mpsl_opcodes, opcode); mpdm_aset(v, o, 0); switch (args) { case 4: mpdm_aset(v, a4, 4); /* no break */ case 3: mpdm_aset(v, a3, 3); /* no break */ case 2: mpdm_aset(v, a2, 2); /* no break */ case 1: mpdm_aset(v, a1, 1); /* no break */ } mpdm_unrefnd(v); v = constant_fold(v); return v; }
O_TYPE O_blkframe(O_ARGS) /* runs an instruction under a block frame */ { mpdm_t ret; /* no context? create one */ if (l == NULL) l = MPDM_A(0); RF(l); /* create a new local symbol table */ mpdm_push(l, MPDM_H(0)); /* creates the arguments (if any) as local variables */ set_local_symbols(M2, a, l); /* execute instruction */ ret = RF(M1); /* destroy the local symbol table */ mpdm_adel(l, -1); UF(l); return UFND(ret); }
O_TYPE O_list(O_ARGS) /* build list from instructions */ { mpdm_t ret = RF(mpdm_size(c) == 2 ? MPDM_A(0) : M(2)); mpdm_push(ret, M(1)); return UFND(ret); }
O_TYPE O_ilist(O_ARGS) /* build and inverse list from instructions */ { mpdm_t ret = RF(mpdm_size(c) == 2 ? MPDM_A(0) : M(2)); mpdm_ins(ret, M(1), 0); return UFND(ret); }
/** * mpsl_argv - Fills the ARGV global array. * @argc: number of arguments * @argv: array of string values * * Fills the ARGV global MPSL array with an array of arguments. These * are usually the ones sent to main(). */ void mpsl_argv(int argc, char *argv[]) { int n; mpdm_t ARGV; /* create the ARGV array */ ARGV = mpdm_hset_s(mpdm_root(), L"ARGV", MPDM_A(0)); for (n = 0; n < argc; n++) mpdm_push(ARGV, MPDM_MBS(argv[n])); }
/** * mpdm_set_o - Sets a value in an object. * @o: the object * @v: the value * @i: the index * * Sets the value @v inside the object @o, accesible by index @i. * Returns @v. * [Objects] */ mpdm_t mpdm_set_o(mpdm_t o, mpdm_t v, mpdm_t i) /* do not use it; use mpdm_set() */ { mpdm_t b, r; int n; mpdm_ref(i); mpdm_ref(v); /* if hash is empty, create an optimal number of buckets */ if (mpdm_size(o) == 0) mpdm_expand(o, 0, mpdm_hash_buckets); n = HASH_BUCKET(o, i); if ((b = mpdm_get_i(o, n)) != NULL) { int pos; /* bucket exists; try to find the key there */ n = mpdm_bseek(b, i, 2, &pos); if (n < 0) { /* the pair does not exist: create it */ n = pos; mpdm_expand(b, n, 2); mpdm_set_i(b, i, n); } } else { /* the bucket does not exist; create it */ b = MPDM_A(2); /* put the bucket into the hash */ mpdm_set_i(o, b, n); /* offset 0 */ n = 0; /* insert the key */ mpdm_set_i(b, i, n); } r = mpdm_set_i(b, v, n + 1); mpdm_unref(v); mpdm_unref(i); return r; }
void test_mpsl_file(void) { mpdm_t v; mpdm_t inc; mpsl_trap(NULL); inc = mpdm_ref(MPDM_A(0)); mpdm_push(inc, MPDM_S(L".")); printf("Compiling from file:\n"); v = do_test_mpsl_file("test.mpsl", inc); v = do_test_exec(v, NULL); mpdm_unref(inc); }
/** * mpdm_keys - Returns the keys of a hash. * @h: the hash * * Returns an array containing all the keys of the @h hash. * [Hashes] * [Arrays] */ mpdm_t mpdm_keys(const mpdm_t h) { int c; mpdm_t a, i; printf("Warning: deprecated function mpdm_keys()\n"); mpdm_ref(h); /* create an array with the same number of elements */ a = MPDM_A(0); c = 0; while (mpdm_iterator(h, &c, NULL, &i)) mpdm_push(a, i); mpdm_unref(h); return a; }
/** * mpsl_startup - Initializes MPSL. * * Initializes the Minimum Profit Scripting Language. Returns 0 if * everything went OK. */ int mpsl_startup(void) { mpdm_t r; mpdm_t m; /* startup MPDM */ mpdm_startup(); r = mpdm_root(); /* creates INC, unless already defined */ if (mpdm_hget_s(r, L"INC") == NULL) mpdm_hset_s(r, L"INC", MPDM_A(0)); /* the TRUE value */ mpdm_hset_s(r, L"TRUE", MPDM_I(1)); /* standard file descriptors */ mpdm_hset_s(r, L"STDIN", MPDM_F(stdin)); mpdm_hset_s(r, L"STDOUT", MPDM_F(stdout)); mpdm_hset_s(r, L"STDERR", MPDM_F(stderr)); /* home and application directories */ mpdm_hset_s(r, L"HOMEDIR", mpdm_home_dir()); mpdm_hset_s(r, L"APPDIR", mpdm_app_dir()); /* fill now the MPSL hash */ m = MPDM_H(0); mpdm_hset_s(r, L"MPSL", m); /* store things there */ mpdm_hset_s(m, L"VERSION", MPDM_MBS(VERSION)); mpdm_hset_s(m, L"OPCODE", mpsl_build_opcodes()); mpdm_hset_s(m, L"LC", MPDM_H(0)); mpdm_hset_s(m, L"CORE", mpsl_build_funcs()); mpdm_dump_1 = mpsl_dump_1; return 0; }
O_TYPE O_range(O_ARGS) /* build list from range of two numeric values */ { double v1 = RM1; double v2 = RM2; mpdm_t r = RF(MPDM_A(0)); if (v1 < v2) while (v1 <= v2) { mpdm_push(r, MPDM_R(v1)); v1 += 1.0; } else while (v1 >= v2) { mpdm_push(r, MPDM_R(v1)); v1 -= 1.0; } UFND(r); return r; }
static void set_local_symbols(mpdm_t s, mpdm_t v, mpdm_t l) /* sets (or creates) a list of local symbols with a list of values */ { if (l != NULL) { mpdm_t h; mpdm_ref(s); mpdm_ref(v); mpdm_ref(l); /* gets the top local variable frame */ h = mpdm_aget(l, -1); if (MPDM_IS_ARRAY(s) || MPDM_IS_ARRAY(v)) { int n; mpdm_t a; for (n = 0; n < mpdm_size(s); n++) mpdm_hset(h, mpdm_aget(s, n), mpdm_aget(v, n)); if (n < mpdm_size(v)) { /* store the rest of arguments into _ */ a = mpdm_hset_s(h, L"_", MPDM_A(0)); for (; n < mpdm_size(v); n++) mpdm_push(a, mpdm_aget(v, n)); } } else mpdm_hset(h, s, v); mpdm_unref(l); mpdm_unref(v); mpdm_unref(s); } }
O_TYPE O_subframe(O_ARGS) /* runs an instruction inside a subroutine frame */ { /* like a block frame, but with its own symbol table */ return O_blkframe(c, a, MPDM_A(0), f); }
void test_mpsl2(void) { mpdm_t v; mpdm_t w; /* execution tests */ v = do_test_mpsl("666;"); mpdm_dump(v); v = do_test_exec(v, NULL); do_test("literal number", mpdm_ival(v) == 666); v = do_test_mpsl("\"goodbye\";"); v = do_test_exec(v, NULL); do_test("literal string", mpdm_cmp(v, MPDM_S(L"goodbye")) == 0); v = do_test_mpsl("1 + 3 + 5;"); v = do_test_exec(v, NULL); do_test("mpsl calculator 1", mpdm_rval(v) == 9.0); v = do_test_mpsl("1 + ((3 - 5) * 8);"); v = do_test_exec(v, NULL); do_test("mpsl calculator 2", mpdm_rval(v) == -15.0); /* next value cannot be tested as an exact equality, as rounding errors will manifest */ v = do_test_mpsl("1.5 + ((3.1 - 5.8) * 8.0);"); v = do_test_exec(v, NULL); do_test("mpsl calculator 3", mpdm_rval(v) < -20.0 && mpdm_rval(v) > -21.0); v = do_test_mpsl("2 + 3 * 4;"); v = do_test_exec(v, NULL); do_test("mpsl calculator 4", mpdm_rval(v) == 14.0); v = do_test_mpsl("2 * 3 + 4;"); v = do_test_exec(v, NULL); do_test("mpsl calculator 5", mpdm_rval(v) == 10.0); v = do_test_exec(do_test_mpsl("2 + 3 * 4;"), NULL); mpdm_ref(v); w = do_test_exec(do_test_mpsl("2 + (3 * 4);"), NULL); do_test("mpsl calculator 6 (operator precedence)", mpdm_rval(v) == mpdm_rval(w)); mpdm_unref(v); v = do_test_exec(do_test_mpsl("2 + 3 * 4;"), NULL); mpdm_ref(v); w = do_test_exec(do_test_mpsl("(2 + 3) * 4;"), NULL); do_test("mpsl calculator 7 (operator precedence)", mpdm_rval(v) != mpdm_rval(w)); mpdm_unref(v); v = do_test_mpsl("/* array */ [\"this\", \"one\", \"is\", 666, \"cool\"];"); v = do_test_exec(v, NULL); mpdm_dump(v); do_test("mpsl array", mpdm_ival(mpdm_get_i(v, 3)) == 666); v = do_test_mpsl ("/* hash */ { \"enero\" => \"january\", \"febrero\" => \"february\" };"); v = do_test_exec(v, NULL); mpdm_dump(v); do_test("mpsl hash", mpdm_cmp(mpdm_get(v, MPDM_S(L"febrero")), MPDM_S(L"february")) == 0); v = do_test_mpsl("! 1;"); v = do_test_exec(v, NULL); do_test("boolean not 1", !mpdm_is_true(v)); v = do_test_mpsl("! 0;"); v = do_test_exec(v, NULL); do_test("boolean not 2", v != NULL); v = do_test_mpsl("1 && 3;"); v = do_test_exec(v, NULL); do_test("boolean and 1", mpdm_ival(v) == 3); v = do_test_mpsl("1 && 0;"); v = do_test_exec(v, NULL); do_test("boolean and 2", !mpdm_is_true(v)); v = do_test_mpsl("0 && 1;"); v = do_test_exec(v, NULL); do_test("boolean and 3", !mpdm_is_true(v)); v = do_test_mpsl("1 || 3;"); v = do_test_exec(v, NULL); do_test("boolean or 1", mpdm_ival(v) == 1); v = do_test_mpsl("2 || 0;"); v = do_test_exec(v, NULL); do_test("boolean or 2", mpdm_ival(v) == 2); v = do_test_mpsl("0 || 3;"); v = do_test_exec(v, NULL); do_test("boolean or 3", mpdm_ival(v) == 3); v = do_test_mpsl("6 == 6;"); v = do_test_exec(v, NULL); do_test("numeric == 1", v != NULL); v = do_test_mpsl("8.0 == 8.0;"); v = do_test_exec(v, NULL); do_test("numeric == 2", v != NULL); v = do_test_mpsl("6 == 8;"); v = do_test_exec(v, NULL); do_test("numeric == 3", !mpdm_is_true(v)); v = do_test_mpsl("6 != 6;"); v = do_test_exec(v, NULL); do_test("numeric != 1", !mpdm_is_true(v)); v = do_test_mpsl("8.0 != 8.0;"); v = do_test_exec(v, NULL); do_test("numeric != 2", !mpdm_is_true(v)); v = do_test_mpsl("6 != 8;"); v = do_test_exec(v, NULL); do_test("numeric != 3", v != NULL); v = do_test_mpsl("6 < 6;"); v = do_test_exec(v, NULL); do_test("numeric < 1", !mpdm_is_true(v)); v = do_test_mpsl("8 < 6;"); v = do_test_exec(v, NULL); do_test("numeric < 2", !mpdm_is_true(v)); v = do_test_mpsl("5 < 6;"); v = do_test_exec(v, NULL); do_test("numeric < 3", v != NULL); v = do_test_mpsl("6 > 6;"); v = do_test_exec(v, NULL); do_test("numeric > 1", !mpdm_is_true(v)); v = do_test_mpsl("8 > 6;"); v = do_test_exec(v, NULL); do_test("numeric > 2", v != NULL); v = do_test_mpsl("5 > 6;"); v = do_test_exec(v, NULL); do_test("numeric > 3", !mpdm_is_true(v)); v = do_test_mpsl("6 <= 6;"); v = do_test_exec(v, NULL); do_test("numeric <= 1", v != NULL); v = do_test_mpsl("8 <= 6;"); v = do_test_exec(v, NULL); do_test("numeric <= 2", !mpdm_is_true(v)); v = do_test_mpsl("5 <= 6;"); v = do_test_exec(v, NULL); do_test("numeric <= 3", v != NULL); v = do_test_mpsl("6 >= 6;"); v = do_test_exec(v, NULL); do_test("numeric >= 1", v != NULL); v = do_test_mpsl("8 >= 6;"); v = do_test_exec(v, NULL); do_test("numeric >= 2", v != NULL); v = do_test_mpsl("5 >= 6;"); v = do_test_exec(v, NULL); do_test("numeric >= 3", !mpdm_is_true(v)); v = do_test_mpsl("11 % 6;"); v = do_test_exec(v, NULL); do_test("modulo", mpdm_ival(v) == 5); v = do_test_mpsl("variable=16384;"); mpdm_dump(v); v = do_test_exec(v, NULL); do_test("assign 1", mpdm_ival(v) == 16384); v = do_test_mpsl("array=[10, 20, 30, 40];"); v = do_test_exec(v, NULL); do_test("assign 2", mpdm_ival(mpdm_get_i(v, 2)) == 30); v = do_test_mpsl("a=1; b=2; c=3;"); mpdm_dump(v); v = do_test_exec(v, NULL); v = do_test_mpsl("CACHE={}; CACHE.regex=[]; CACHE.regex[0]=12345;"); v = do_test_exec(v, NULL); v = do_test_mpsl("variable;"); v = do_test_exec(v, NULL); do_test("symval 1", mpdm_ival(v) == 16384); v = do_test_mpsl("variable2=1 + ((3 - 5) * 8); variable2;"); mpdm_dump(v); v = do_test_exec(v, NULL); do_test("symval 2", mpdm_rval(v) == -15); v = do_test_mpsl("variable3=variable2 * 2;"); v = do_test_exec(v, NULL); do_test("symval 3", mpdm_ival(v) == -30); v = do_test_mpsl("sub mysum(a, b) { a + b; }"); mpdm_dump(v); v = do_test_exec(v, NULL); do_test("sub 1", v != NULL); v = do_test_mpsl("sub pi() { 3.1416; }"); mpdm_dump(v); v = do_test_exec(v, NULL); do_test("sub 2", v != NULL); v = do_test_mpsl("var10=pi();"); v = do_test_exec(v, NULL); do_test("exec 1", mpdm_rval(v) == 3.1416); v = do_test_mpsl("var11=pi() * 10000; var11;"); v = do_test_exec(v, NULL); do_test("exec 2", mpdm_rval(v) == 31416); v = do_test_mpsl("mysum(100, 20);"); v = do_test_exec(v, NULL); do_test("exec 3", mpdm_rval(v) == 120.0); v = do_test_mpsl("a = NULL;"); v = do_test_exec(v, NULL); do_test("NULL 1", v == NULL); v = do_test_mpsl("a == NULL;"); v = do_test_exec(v, NULL); do_test("NULL 2", mpdm_ival(v) == 1); v = do_test_mpsl("local a, b; a = 1; b = 2;"); v = do_test_exec(v, NULL); v = do_test_mpsl("a == NULL;"); v = do_test_exec(v, NULL); do_test("local 1", mpdm_ival(v) == 1); v = do_test_mpsl("66 * -1;"); v = do_test_exec(v, NULL); do_test("uminus", mpdm_ival(v) == -66); v = do_test_mpsl("\"test\" eq \"test\";"); v = do_test_exec(v, NULL); do_test("streq 1", mpdm_is_true(v)); v = do_test_mpsl("\"test\" eq \"prueba\";"); v = do_test_exec(v, NULL); do_test("streq 1", !mpdm_is_true(v)); v = do_test_mpsl("a = 6; ++ a;"); v = do_test_exec(v, NULL); do_test("pinc", mpdm_ival(v) == 7); v = do_test_mpsl("a++;"); v = do_test_exec(v, NULL); do_test("sinc", mpdm_ival(v) == 7); v = do_test_mpsl("a += 10;"); v = do_test_exec(v, NULL); do_test("iadd", mpdm_ival(v) == 18); v = do_test_mpsl("local a, b, c; a=1; b=2; c=3; if(a == b) c=1000; c;"); v = do_test_exec(v, NULL); do_test("if 1", mpdm_ival(v) == 3); v = do_test_mpsl("local a, b, c; a=1; b=2; c=3; if(a <= b) c=1000; c;"); v = do_test_exec(v, NULL); do_test("if 2", mpdm_ival(v) == 1000); v = do_test_mpsl("local a, b, c; a=1; b=2; if(a == b) c=1000; else c=2000; c;"); v = do_test_exec(v, NULL); do_test("ifelse", mpdm_ival(v) == 2000); v = do_test_mpsl("local a; a = 0; while(a < 100) { a++; } a;"); v = do_test_exec(v, NULL); do_test("ifelse", mpdm_ival(v) == 100); v = do_test_mpsl("a=mysum(100, 50); a;"); v = do_test_exec(v, NULL); do_test("mysum 1", mpdm_ival(v) == 150); v = do_test_mpsl("a=mysum(2000, 500); a;"); v = do_test_exec(v, NULL); do_test("mysum 2", mpdm_ival(v) == 2500); w = mpdm_ref(MPDM_A(2)); mpdm_set_i(w, MPDM_I(100), 0); mpdm_set_i(w, MPDM_I(50), 1); /* asks for the value of the mysum symbol (the code) */ v = do_test_mpsl("mysum;"); /* executes, so mysum() itself is being returned */ v = do_test_exec(v, NULL); mpdm_dump(v); do_test("mysum 3", mpdm_ival(do_test_exec(v, w)) == 150); mpdm_set_i(w, MPDM_I(75), 1); do_test("mysum 4", mpdm_ival(do_test_exec(v, w)) == 175); /* compiles (and executes) the definition of gcd() */ v = do_test_mpsl ("/* greatest common divisor (Euclid's algorithm) */ sub gcd(m, n) { while (m > 0) { if(n > m) { local t = m; m = n; n = t; } m -= n; } n; }"); do_test_exec(v, NULL); /* gets a pointer to gcd() */ v = do_test_exec(do_test_mpsl("gcd;"), NULL); mpdm_dump(v); /* executes gcd(100, 50); */ mpdm_set_i(w, MPDM_I(50), 1); do_test("gcd() 1", mpdm_ival(do_test_exec(v, w)) == 50); /* executes gcd(100, 75); */ mpdm_set_i(w, MPDM_I(75), 1); do_test("gcd() 2", mpdm_ival(do_test_exec(v, w)) == 25); mpdm_unref(w); /* string concatenation */ w = mpdm_ref(MPDM_S(L"big lebowski")); v = do_test_mpsl("\"big\" ~ \" lebowski\";"); do_test("~ (strcat 1)", mpdm_cmp(do_test_exec(v, NULL), w) == 0); v = do_test_mpsl("\"big\" ~ \" \" ~ \"lebowski\";"); do_test("~ (strcat 2)", mpdm_cmp(do_test_exec(v, NULL), w) == 0); mpdm_unref(w); }
static mpdm_t kde4_drv_form(mpdm_t a, mpdm_t ctxt) { int n; mpdm_t widget_list; QWidget *qlist[100]; mpdm_t r; KDialog *dialog = new KDialog(window); dialog->setModal(true); dialog->setButtons(KDialog::Ok | KDialog::Cancel); widget_list = mpdm_aget(a, 0); KVBox *vb = new KVBox(dialog); dialog->setMainWidget(vb); for (n = 0; n < mpdm_size(widget_list); n++) { mpdm_t w = mpdm_aget(widget_list, n); wchar_t *type; mpdm_t t; KHBox *hb = new KHBox(vb); type = mpdm_string(mpdm_hget_s(w, L"type")); if ((t = mpdm_hget_s(w, L"label")) != NULL) { QLabel *ql = new QLabel(hb); ql->setText(str_to_qstring(mpdm_gettext(t))); } t = mpdm_hget_s(w, L"value"); if (wcscmp(type, L"text") == 0) { mpdm_t h; QComboBox *ql = new QComboBox(hb); ql->setEditable(true); ql->setMinimumContentsLength(30); ql->setMaxVisibleItems(8); if (t != NULL) ql->setEditText(str_to_qstring(t)); qlist[n] = ql; if ((h = mpdm_hget_s(w, L"history")) != NULL) { int i; /* has history; fill it */ h = mp_get_history(h); for (i = mpdm_size(h) - 1; i >= 0; i--) ql->addItem(str_to_qstring(mpdm_aget(h, i))); } } else if (wcscmp(type, L"password") == 0) { QLineEdit *ql = new QLineEdit(hb); ql->setEchoMode(QLineEdit::Password); qlist[n] = ql; } else if (wcscmp(type, L"checkbox") == 0) { QCheckBox *qc = new QCheckBox(hb); if (mpdm_ival(t)) qc->setCheckState(Qt::Checked); qlist[n] = qc; } else if (wcscmp(type, L"list") == 0) { int i; QListWidget *ql = new QListWidget(hb); ql->setMinimumWidth(480); /* use a monospaced font */ ql->setFont(QFont(QString("Mono"))); mpdm_t l = mpdm_hget_s(w, L"list"); for (i = 0; i < mpdm_size(l); i++) ql->addItem(str_to_qstring(mpdm_aget(l, i))); ql->setCurrentRow(mpdm_ival(t)); qlist[n] = ql; } if (n == 0) qlist[n]->setFocus(Qt::OtherFocusReason); } n = dialog->exec(); if (!n) return NULL; r = MPDM_A(mpdm_size(widget_list)); /* fill the return values */ for (n = 0; n < mpdm_size(widget_list); n++) { mpdm_t w = mpdm_aget(widget_list, n); mpdm_t v = NULL; wchar_t *type; type = mpdm_string(mpdm_hget_s(w, L"type")); if (wcscmp(type, L"text") == 0) { mpdm_t h; QComboBox *ql = (QComboBox *) qlist[n]; v = qstring_to_str(ql->currentText()); /* if it has history, add to it */ if ((h = mpdm_hget_s(w, L"history")) != NULL && v != NULL && mpdm_cmp_s(v, L"") != 0) { h = mp_get_history(h); if (mpdm_cmp(v, mpdm_aget(h, -1)) != 0) mpdm_push(h, v); } } else if (wcscmp(type, L"password") == 0) { QLineEdit *ql = (QLineEdit *) qlist[n]; v = qstring_to_str(ql->text()); } else if (wcscmp(type, L"checkbox") == 0) { QCheckBox *qb = (QCheckBox *) qlist[n]; v = MPDM_I(qb->checkState() == Qt::Checked); } else if (wcscmp(type, L"list") == 0) { QListWidget *ql = (QListWidget *) qlist[n]; v = MPDM_I(ql->currentRow()); } mpdm_aset(r, v, n); } return r; }