int syms_is_global(const char * n) { struct sym *s; if (!n || is_number(n) || is_local_label_ref(n) || isregister(n)) return 0; /* if not found, it must be extern -> global */ if (!(s = sym_exists(n))) return 1; return s->gl; }
int member(void) { if (token[0] >= '0' && token[0] <= '9') { int v = atoi(token); scan(); return v; } if (sym_exists(token)) { int c = 0; int v = 0; sym_addr(token, &c, &v, &whatever); scan(); if (c) return v; } error("Unrecognized member"); return 0; }
symbol * name(int dcl) { symbol * q = NULL; if(sym_exists(token) || dcl) { int c = 0; int v = 0; int l = 0; l = caddr(sym_addr(token, &c, &v, &q)); scan(); g_mov_bx(l); g_push_bx(); dereference(); } else { error("Expected identifier"); } return q; }
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"); }