Exemple #1
0
static void rcc_element(REgg *egg, char *str) {
	REggEmit *e = egg->remit;
	char *p = strrchr (str, ',');
	int num, num2;

	if (CTX) {
		nargs = 0;
		if (mode == GOTO)
			mode = NORMAL; // XXX
		while (p) {
			*p = '\0';
			p = (char *)skipspaces (p+1);
			rcc_pusharg (egg, p);
			p = strrchr (str, ',');
		}
		if (callname)
			rcc_pusharg (egg, str);
		else
		if (mode == NORMAL) {
			if (!atoi (str)) {
				if (dstvar == NULL) /* return string */
					dstvar = strdup (".fix0");
				rcc_pushstr (egg, str, 1);
			}
		}
	} else {
		switch (mode) {
		case ALIAS:
			e->equ (egg, dstvar, str);
			R_FREE (dstvar);
			mode = NORMAL;
			break;
		case SYSCALL:
			syscalls[nsyscalls].name = strdup (dstvar);
			syscalls[nsyscalls].arg = strdup (str);
			nsyscalls++;
			R_FREE (dstvar);
			break;
		case GOTO:
			elem[elem_n] = 0;
			e->jmp (egg, elem, 0);
			break;
		default:
			p = strchr (str, ',');
			if (p) {
				*p='\0';
				num2 = atoi (p+1);
			} else num2 = 0;
			num = atoi (str) + num2;
			stackframe = num;
			stackfixed = num2;
			if (mode != NAKED)
				e->frame (egg, stackframe+stackfixed);
		}
		elem[0] = 0;
		elem_n = 0;
	}
}
Exemple #2
0
/* TODO: split this function into several ones..quite long fun */
static void rcc_next(REgg *egg) {
	const char *ocn;
	REggEmit *e = egg->remit;
	char *str = NULL, *p, *ptr, buf[64];
	int i;

	if (setenviron) {
		elem[elem_n - 1] = 0;
		r_sys_setenv (setenviron, elem);
		R_FREE (setenviron);
		return;
	}
	if (includefile) {
		char *p, *q, *path;
		// TODO: add support for directories
		elem[elem_n-1] = 0;
		path = find_include (elem, includefile);
		if (!path) {
			eprintf ("Cannot find include file '%s'\n", elem);
			return;
		}
		free (includefile);
		includefile = NULL;
		rcc_reset_callname ();
		p = q = r_file_slurp (path, NULL);
		if (p) {
			int oline = ++line;
			elem[0] = 0; // TODO: this must be a separate function
			elem_n = 0;
			line = 0;
			for (; *p; p++)
				r_egg_lang_parsechar (egg, *p);
			free (q);
			line = oline;
		} else {
			eprintf ("Cannot find '%s'\n", path);
		}
		free (path);
		return;
	}
	docall = 1;
	if (callname) {
		if (!strcmp (callname, "goto")) {
			if (nargs != 1) {
				eprintf ("Invalid number of arguments for goto()\n");
				return;
			}
			e->jmp (egg, ctxpush[CTX], 0);
			rcc_reset_callname ();
			return;
		}
		if (!strcmp (callname, "break")) {
			e->trap (egg);
			rcc_reset_callname ();
			return;
		}
		ptr = strchr (callname, '=');
		if (ptr) {
			*ptr = '\0';
			//ocn = ptr+1; // what is the point of this?
		}
		ocn = skipspaces (callname);
		if (!ocn) return;
		str = r_egg_mkvar (egg, buf, ocn, 0);
		if (!str) {
			eprintf ("Cannot mkvar\n");
			return;
		}
		if (*ocn=='.')
			e->call (egg, str, 1);
		if (!strcmp (str, "while")) {
			char var[128];
			if (lastctxdelta >= 0)
				exit (eprintf ("ERROR: Unsupported while syntax\n"));
			sprintf (var, "__begin_%d_%d_%d\n", nfunctions, CTX, nestedi[CTX-1]);
			e->while_end (egg, var); //get_frame_label (1));
#if 0
			eprintf ("------------------------------------------ lastctx: %d\n", lastctxdelta);
			// TODO: the pushvar is required for the if(){}while(); constructions
			//char *pushvar = ctxpush[context+nbrackets-1];
			/* TODO: support to compare more than one expression (LOGICAL OR) */
			rcc_printf ("  pop %%eax\n");
			rcc_printf ("  cmp $0, %%eax\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
			/* TODO : Simplify!! */
			//if (pushvar)
			//	printf("  push %s /* wihle push */\n", pushvar);
			if (lastctxdelta<0)
				rcc_printf ("  jnz %s\n", get_frame_label (1));
			else rcc_printf ("  jnz %s\n", get_frame_label (0));
			//if (pushvar)
			//	printf("  pop %%"R_AX" /* while pop */\n");
#endif
			nargs = 0;
		} else {
			for (i = 0; i < nsyscalls; i++) {
				if (!strcmp (str, syscalls[i].name)) {
					p = syscallbody;
					e->comment (egg, "set syscall args");
					e->syscall_args (egg, nargs);
					docall = 0;
					e->comment (egg, "syscall");
					r_egg_lang_parsechar (egg, '\n'); /* FIX parsing issue */
					if (p) {
						for (; *p; p++)
							r_egg_lang_parsechar (egg, *p);
					} else {
						char *q, *s = e->syscall (egg, nargs);
						if (s) {
							for (q=s; *q; q++)
								r_egg_lang_parsechar (egg, *q);
							free (s);
						} else eprintf ("Cannot get @syscall payload\n");
					}
					docall = 0;
					break;
				}
			}
			if (docall)
			for (i = 0; i < ninlines; i++) {
				if (!strcmp (str, inlines[i].name)) {
					p = inlines[i].body;
					docall = 0;
					e->comment (egg, "inline");
					r_egg_lang_parsechar (egg, '\n'); /* FIX parsing issue */
					for (; *p; p++)
						r_egg_lang_parsechar (egg, *p);
					docall = 0;
					break;
				}
			}
			if (docall) {
				e->comment (egg, "call in mode %d", mode);
				e->call (egg, str, 0);
			}
		}
		if (nargs > 0)
			e->restore_stack (egg, nargs*e->size);
		if (ocn) { // Used to call .var0()
			/* XXX: Probably buggy and wrong */
			*buf = 0;
			free (str);
			str = r_egg_mkvar (egg, buf, ocn, 0);
			if (*buf)
				e->get_result (egg, buf);
			//else { eprintf("external symbol %s\n", ocn); }
		}
		/* store result of call */
		if (dstvar) {
			if (mode != NAKED) {
				*buf = 0;
				free (str);
				str = r_egg_mkvar (egg, buf, dstvar, 0);
				if (*buf == 0)
					eprintf ("Cannot resolve variable '%s'\n", dstvar);
				else e->get_result (egg, buf);
			}
			R_FREE (dstvar);
		}
		rcc_reset_callname ();
	} else {
		int vs = 'l';
		char type, *eq, *ptr = elem;
		elem[elem_n] = '\0';
		ptr = (char*)skipspaces (ptr);
		if (*ptr) {
			eq = strchr (ptr, '=');
			if (eq) {
				char str2[64], *p, ch = *(eq-1);
				*eq = '\0';
				eq = (char*) skipspaces (eq+1);
				p = r_egg_mkvar (egg, str2, ptr, 0);
				vs = varsize;
				if (is_var (eq)) {
					eq = r_egg_mkvar (egg, buf, eq, 0);
					if (varxs=='*')
						e->load (egg, eq, varsize);
					else
					/* XXX this is a hack .. must be integrated with pusharg */
					if (varxs=='&')
						e->load_ptr (egg, eq);
					if (eq) {
						free (eq);
						eq = NULL;
					}
					type = ' ';
				} else type = '$';
				vs = 'l'; // XXX: add support for != 'l' size
				e->mathop (egg, ch, vs, type, eq, p);
				free(p);
			} else {
				if (!strcmp (ptr, "break")) { // handle 'break;'
					e->trap (egg);
					rcc_reset_callname ();
				} else {
					e->mathop (egg, '=', vs, '$', ptr, NULL);
				}
			}
		}
	}
	free (str);
}