void boolexpr(void) { negexpr(); while(tokeq("&") || tokeq("|") || tokeq("~")) { char x = token[0]; scan(); negexpr(); if(x == '&') { g_pop_ax(); g_pop_dx(); g_and_ax_dx(); g_push_dx(); } if(x == '|') { g_pop_ax(); g_pop_dx(); g_or_ax_dx(); g_push_dx(); } if(x == '~') { g_pop_ax(); g_pop_dx(); g_xor_ax_dx(); g_push_dx(); } } }
void negexpr(void) { if(tokeq("!")) { scan(); compexpr(0); g_pop_ax(); g_or_ax_ax(); g_jz(+3); g_xor_ax_ax(); g_dec_ax(); g_label(); g_inc_ax(); g_push_ax(); } else if(tokeq("?")) { scan(); compexpr(0); g_pop_ax(); g_xor_bx_bx(); g_or_ax_ax(); g_jz(+1); g_inc_bx(); g_label(); g_push_bx(); } else { compexpr(0); } }
int test_array_nomem(void) { int i; int r; jsmn_parser p; jsmntok_t toksmall[10], toklarge[10]; const char *js; js = " [ 1, true, [123, \"hello\"]]"; for (i = 0; i < 6; i++) { jsmn_init(&p); memset(toksmall, 0, sizeof(toksmall)); memset(toklarge, 0, sizeof(toklarge)); r = jsmn_parse(&p, js, strlen(js), toksmall, i); check(r == JSMN_ERROR_NOMEM); memcpy(toklarge, toksmall, sizeof(toksmall)); r = jsmn_parse(&p, js, strlen(js), toklarge, 10); check(r >= 0); check(tokeq(js, toklarge, 4, JSMN_ARRAY, -1, -1, 3, JSMN_PRIMITIVE, "1", JSMN_PRIMITIVE, "true", JSMN_ARRAY, -1, -1, 2, JSMN_PRIMITIVE, "123", JSMN_STRING, "hello", 0)); } return 0; }
int test_partial_array(void) { #ifdef JSMN_STRICT int r; int i; jsmn_parser p; jsmntok_t tok[10]; const char *js = "[ 1, true, [123, \"hello\"]]"; jsmn_init(&p); for (i = 1; i <= strlen(js); i++) { r = jsmn_parse(&p, js, i, tok, sizeof(tok)/sizeof(tok[0])); if (i == strlen(js)) { check(r == 6); check(tokeq(js, tok, 6, JSMN_ARRAY, -1, -1, 3, JSMN_PRIMITIVE, "1", JSMN_PRIMITIVE, "true", JSMN_ARRAY, -1, -1, 2, JSMN_PRIMITIVE, "123", JSMN_STRING, "hello", 0)); } else { check(r == JSMN_ERROR_PART); } } #endif return 0; }
void term(void) { int fixed = 0; factor(); while(tokeq("*") || tokeq("/")) { char x = token[0]; scan(); if (tokeq(".")) { fixed = 1; scan(); } factor(); if(x == '*') { g_pop_ax(); g_pop_dx(); g_imul_dx(); if (fixed) { g_mov_al_ah(); g_mov_ah_dl(); } g_push_ax(); } if(x == '/') { g_pop_ax(); g_pop_cx(); g_xor_dx_dx(); if (fixed) { g_mov_dl_ah(); g_mov_ah_al(); g_xor_al_al(); } g_idiv_cx(); g_push_ax(); } } }
void addexpr(void) { term(); while(tokeq("+") || tokeq("-")) { char x = token[0]; scan(); term(); if(x == '+') { g_pop_ax(); g_pop_dx(); g_add_ax_dx(); g_push_ax(); } if(x == '-') { g_pop_dx(); g_pop_ax(); g_sub_ax_dx(); g_push_ax(); } } }
void factor(void) { primitive(); while(tokeq(">>") || tokeq("<<")) { char x = token[0]; scan(); primitive(); if (x == '>') { g_pop_cx(); g_pop_ax(); g_shr_ax_cl(); g_push_ax(); } if (x == '<') { g_pop_cx(); g_pop_ax(); g_shr_ax_cl(); g_push_ax(); } } }
int test_input_length(void) { const char *js; int r; jsmn_parser p; jsmntok_t tokens[10]; js = "{\"a\": 0}garbage"; jsmn_init(&p); r = jsmn_parse(&p, js, 8, tokens, 10); check(r == 3); check(tokeq(js, tokens, 3, JSMN_OBJECT, -1, -1, 1, JSMN_STRING, "a", 1, JSMN_PRIMITIVE, 0)); return 0; }
int test_unquoted_keys(void) { #ifndef JSMN_STRICT int r; jsmn_parser p; jsmntok_t tok[10]; const char *js; jsmn_init(&p); js = "key1: \"value\"\nkey2 : 123"; r = jsmn_parse(&p, js, strlen(js), tok, 10); check(r >= 0); check(tokeq(js, tok, 4, JSMN_PRIMITIVE, "key1", JSMN_STRING, "value", 0, JSMN_PRIMITIVE, "key2", JSMN_PRIMITIVE, "123")); #endif return 0; }
int test_partial_string(void) { int i; int r; jsmn_parser p; jsmntok_t tok[5]; const char *js = "{\"x\": \"va\\\\ue\", \"y\": \"value y\"}"; jsmn_init(&p); for (i = 1; i <= strlen(js); i++) { r = jsmn_parse(&p, js, i, tok, sizeof(tok)/sizeof(tok[0])); if (i == strlen(js)) { check(r == 5); check(tokeq(js, tok, 5, JSMN_OBJECT, -1, -1, 2, JSMN_STRING, "x", 1, JSMN_STRING, "va\\\\ue", 0, JSMN_STRING, "y", 1, JSMN_STRING, "value y", 0)); } else { check(r == JSMN_ERROR_PART); } } return 0; }
void dereference(void) /* assume address has already been pushed */ { while(tokeq(".") || tokeq("[") || tokeq("^")) { if(tokeq(".")) { scan(); g_pop_bx(); g_add_bx(member()); g_push_bx(); } else if(tokeq("[")) { scan(); addexpr(); if(tokeq("]")) { scan(); g_pop_ax(); g_pop_bx(); g_add_bx_ax(); g_push_bx(); } else { error("Missing ]"); } } else if(tokeq("^")) { scan(); g_pop_bx(); g_mov_ax_BX(); g_push_ax(); } } }
void fullmoonfever(void) { int ok = 1; while(ok) { if(tokeq("ILLGOL") || tokeq("Illgola2") || tokeq("Illberon") || tokeq("Illgol##")) { scan(); block(); } else if(tokeq("GO")) { scan(); boolexpr(); boolexpr(); g_pop_ax(); g_pop_dx(); g_mov_dh_al(); g_mov_ah(2); g_xor_bx_bx(); g_int(0x10); } else if(tokeq("PRINT")) { scan(); boolexpr(); g_mov_ah(0x0e); g_pop_si(); g_label(); g_mov_al_SI(); g_or_al_al(); g_jz(12); g_mov_bx_I(caddr(pencolor)); g_xor_bh_bh(); g_int(16); g_inc_si(); g_jmp(-18); g_label(); } else if(tokeq("CENTRE")) { int l = 0; scan(); l = (80-(strlen(token)-1)) >> 1; boolexpr(); boolexpr(); g_pop_ax(); g_mov_dx(l); g_mov_dh_al(); g_mov_ah(2); g_xor_bx_bx(); g_int(0x10); g_mov_ah(0x0e); g_pop_si(); g_label(); g_mov_al_SI(); g_or_al_al(); g_jz(12); g_mov_bx_I(caddr(pencolor)); g_xor_bh_bh(); g_int(16); g_inc_si(); g_jmp(-18); g_label(); } else if(tokeq("PAUSE"))
void compexpr(int findvar) { char x, y; if (findvar) { if(tokeq("*")) { scan(); shouldsym = name(1); } else { shouldsym = name(0); } g_pop_bx(); g_push_BX(); } else { addexpr(); } while(tokeq("=") || tokeq("<>") || tokeq(">") || tokeq(">=") || tokeq("<") || tokeq("<=")) { x = token[0]; y = token[1]; scan(); addexpr(); if(x == '=') { g_pop_ax(); g_pop_dx(); g_sub_ax_dx(); g_jz(+3); g_xor_ax_ax(); g_dec_ax(); g_label(); g_inc_ax(); g_push_ax(); } if(x == '<' && y == '>') { g_pop_ax(); g_pop_dx(); g_xor_cx_cx(); g_sub_ax_dx(); g_jz(+1); g_inc_cx(); g_label(); g_push_cx(); } if(x == '<' && y == 0) { g_pop_dx(); g_pop_ax(); g_xor_cx_cx(); g_cmp_ax_dx(); g_jge(+1); g_inc_cx(); g_label(); g_push_cx(); } if(x == '>' && y == 0) { g_pop_dx(); g_pop_ax(); g_xor_cx_cx(); g_cmp_ax_dx(); g_jle(+1); g_inc_cx(); g_label(); g_push_cx(); } if(x == '<' && y == '=') { g_pop_dx(); g_pop_ax(); g_xor_cx_cx(); g_cmp_ax_dx(); g_jg(+1); g_inc_cx(); g_label(); g_push_cx(); } if(x == '>' && y == '=') { g_pop_dx(); g_pop_ax(); g_xor_cx_cx(); g_cmp_ax_dx(); g_jl(+1); g_inc_cx(); g_label(); g_push_cx(); } } }
void primitive(void) { int ptr = 0; if(tokeq("call")) { byte * b = m; int l; int c; int v; int a = 0; int i; scan(); boolexpr(); if(tokeq("(")) { scan(); a++; boolexpr(); g_pop_ax(); g_pop_bx(); g_push_ax(); g_push_bx(); while (tokeq(",")) { scan(); a++; boolexpr(); g_pop_ax(); g_pop_bx(); g_push_ax(); g_push_bx(); } if(tokeq(")")) { scan(); } else { error("Missing )"); } } g_pop_bx(); g_push_bp(); g_mov_ax_sp(); g_add_ax(a << 1); g_mov_bp_ax(); g_call_bx(); g_pop_dx(); g_pop_bp(); for(i=0;i<a;i++) { g_pop_ax(); } g_push_dx(); return; } if(tokeq("poll")) { scan(); if(tokeq("tty")) { scan(); g_mov_ah(11); g_int(0x21); g_xor_ah_ah(); g_push_ax(); return; } error("You can only poll the tty"); return; } if(tokeq("Ypush")) { scan(); if(tokeq("(")) { scan(); boolexpr(); if(tokeq(")")) { g_xor_ax_ax(); g_push_ax(); scan(); return; } if(tokeq(",")) { scan(); boolexpr(); if(tokeq(")")) { scan(); return; } } } error("Usage is Ypush(boolexpr[,boolexpr]) in function"); return; } if(tokeq("Ypop")) { scan(); if(tokeq("(")) { scan(); if(tokeq(")")) { scan(); return; } } error("Usage would be Ypop() in function"); return; } if(tokeq("eof")) { scan(); g_mov_bx(caddr(eofflag)); g_push_BX(); g_xor_ax_ax(); g_mov_BX_ax(); return; } if(tokeq("gpos")) { scan(); if(tokeq("(")) { scan(); boolexpr(); if (tokeq(",")) { scan(); boolexpr(); g_xor_cx_cx(); g_pop_dx(); g_mov_ax(0x4201); g_pop_bx(); g_int(0x21); g_push_ax(); if (tokeq(")")) { scan(); return; } } } error("Malformed way to use 'gpos'"); } if(tokeq("sin")) { runtime_trig(); scan(); boolexpr(); g_pop_ax(); g_mov_bx(caddr(sin_routine)); g_call_bx(); g_push_cx(); return; } if(tokeq("cos")) { runtime_trig(); scan(); boolexpr(); g_pop_ax(); g_mov_bx(caddr(cos_routine)); g_call_bx(); g_push_cx(); return; } if(tokeq("abs")) { scan(); boolexpr(); g_pop_ax(); g_and_ax(0x7fff); g_push_ax(); return; } if(tokeq("asc")) { scan(); boolexpr(); g_pop_ax(); g_and_ax(0x007f); g_push_ax(); return; } if(tokeq("low")) { scan(); boolexpr(); g_pop_ax(); g_and_ax(0x00ff); g_push_ax(); return; } if(tokeq("med")) { scan(); boolexpr(); g_pop_ax(); g_mov_cl(4); g_shr_ax_cl(); g_and_ax(0x00ff); g_push_ax(); return; } if(tokeq("fix")) { scan(); boolexpr(); g_pop_ax(); g_mov_ah_al(); g_xor_al_al(); g_push_ax(); return; } if(tokeq("int") || tokeq("hig")) { scan(); boolexpr(); g_pop_ax(); g_mov_al_ah(); g_xor_ah_ah(); g_push_ax(); return; } if(tokeq("fre")) { scan(); boolexpr(); g_pop_ax(); g_mov_ax_I(caddr(d)-2); g_neg_ax(); g_push_ax(); return; } if(tokeq("rnd")) { symbol * q = NULL; scan(); if(tokeq("(")) { scan(); q = name(0); if(tokeq(")")) { scan(); } else error("Missing )"); } else { error("Need identifier in rnd()"); } g_pop_bx(); g_mov_ax_BX(); g_mov_dx(58653U); g_imul_dx(); g_mov_dx(13849U); g_add_ax_dx(); g_mov_BX_ax(); g_push_ax(); if (q != NULL && q->hook_addr != NULL) { g_mov_ax(caddr(q->hook_addr)); g_call_ax(); } return; } if(tokeq("stu")) { scan(); boolexpr(); g_pop_ax(); g_mov_bx(caddr(sbuffer + 14)); g_label(); g_xor_dx_dx(); g_mov_cx(10); g_idiv_cx(); g_add_dx('0'); g_mov_BX_dl(); g_dec_bx(); g_or_ax_ax(); g_jnz(-18); g_inc_bx(); g_push_bx(); return; } if(tokeq("str")) { scan(); boolexpr(); g_pop_ax(); g_push_ax(); g_cmp_ax(0); g_jg(+2); g_neg_ax(); g_label(); g_mov_bx(caddr(sbuffer + 14)); g_label(); g_xor_dx_dx(); g_mov_cx(10); g_idiv_cx(); g_add_dx('0'); g_mov_BX_dl(); g_dec_bx(); g_or_ax_ax(); g_jnz(-18); g_pop_ax(); g_cmp_ax(0); g_jge(+5); g_mov_al('-'); g_mov_BX_al(); g_dec_bx(); g_label(); g_inc_bx(); g_push_bx(); return; } if(tokeq("sif")) { scan(); boolexpr(); g_pop_ax(); g_push_ax(); g_xor_ah_ah(); g_mov_dx(39); g_imul_dx(); /* g_mov_al_ah(); g_mov_ah_dl(); */ g_mov_bx(caddr(sbuffer + 14)); g_mov_cx(10); g_label(); g_xor_dx_dx(); g_idiv_cx(); g_add_dx('0'); g_mov_BX_dl(); g_dec_bx(); g_cmp_bx(caddr(sbuffer + 10)); g_jnz(-17); g_mov_dx('.'); g_mov_BX_dl(); g_dec_bx(); g_pop_ax(); g_mov_al_ah(); g_xor_ah_ah(); g_label(); g_xor_dx_dx(); g_idiv_cx(); g_add_dx('0'); g_mov_BX_dl(); g_dec_bx(); g_or_ax_ax(); g_jnz(-15); g_inc_bx(); g_push_bx(); return; } if(tokeq("nameof")) { char * q; byte * b; scan(); if(tokeq("(")) { scan(); q = (token+1); b = stalloc(strlen(q)+1); name(0); if(tokeq(")")) { scan(); strcpy((char *)b, q); g_mov_ax(caddr(b)); g_push_ax(); } else error("Missing ("); } else error("Missing )"); return; } if(tokeq("^")) { scan(); ptr = 1; } if(tokeq("#")) { scan(); if (tokeq("(")) { scan(); boolexpr(); if (tokeq(")")) { scan(); g_pop_ax(); g_shl_ax_1(); g_neg_ax(); g_xchg_si_ax(); g_mov_ax_BP_SI(); g_push_ax(); return; } error("Missing )"); return; } g_mov_ax_BP(-2 * member()); g_push_ax(); return; } if(sym_exists(token)) { symbol * q = NULL; q = name(0); if (!ptr) { g_pop_bx(); g_push_BX(); if (tokeq("++")) { scan(); g_mov_ax_BX(); g_inc_ax(); g_mov_BX_ax(); if (q != NULL && q->hook_addr != NULL) { g_mov_ax(caddr(q->hook_addr)); g_call_ax(); } } if (tokeq("--")) { scan(); g_mov_ax_BX(); g_dec_ax(); g_mov_BX_ax(); if (q != NULL && q->hook_addr != NULL) { g_mov_ax(caddr(q->hook_addr)); g_call_ax(); } } } return; } if (ptr) { error("Identifier should follow ^"); } if(token[0] >= '0' && token[0] <= '9') { int v = atoi(token); g_mov_ax(v); g_push_ax(); scan(); if (tokeq(".")) { scan(); while(strlen(token) < 4) { strcat(token, "0"); } v = atoi(token) / 39; scan(); if (v > 255) v = 255; g_pop_ax(); g_mov_ah_al(); g_mov_al(v & 0xff); g_push_ax(); } return; } if(token[0] == '"') { char * q = (token+1); byte * b = stalloc(strlen(q)+1); strcpy((char *)b, q); g_mov_ax(caddr(b)); g_push_ax(); scan(); while(token[0] == '"') { char * q = (token+1); byte * b; stretract(); b = stalloc(strlen(q)+1); strcpy((char *)b, q); scan(); } return; } if(tokeq("{")) { byte * l; byte * q; int c=0; int v=0; int lc; scan(); l = m; g_label(); g_nop(); assignments(); if (tokeq("}")) { scan(); g_ret(); q = stalloc(m - l); memcpy(q, l, m - l); m = l; g_mov_ax(caddr(q)); g_push_ax(); return; } error("Missing }"); return; } if(tokeq("INLINE")) { byte * l; byte * q; int c=0; int v=0; int lc; scan(); if(tokeq("{")) scan(); l = m; g_label(); g_nop(); while(tokne("}")) { GEN(atoi(token)); scan(); } scan(); g_ret(); q = stalloc(m - l); memcpy(q, l, m - l); m = l; g_mov_ax(caddr(q)); g_push_ax(); return; } if(tokeq("(")) { scan(); boolexpr(); if (tokeq(")")) { scan(); return; } error("Missing )"); return; } if(tokeq("*")) { scan(); boolexpr(); g_mov_bx(260); g_mov_ax_BX(); g_pop_dx(); g_push_ax(); g_add_ax_dx(); g_mov_BX_ax(); return; } error("Unrecognized primitive"); }