Exemplo n.º 1
0
static void rcc_pushstr(REgg *egg, char *str, int filter) {
        int dotrim = 1;
        int i, j, len;
	REggEmit *e = egg->remit;

        e->comment (egg, "encode %s string (%s) (%s)",
                filter? "filtered": "unfiltered", str, callname);

        if (filter)
        for (i=0; str[i]; i++) {
                if (str[i]=='\\') {
                        switch (str[i+1]) {
                        case 't': str[i]='\t'; break;
                        case 'n': str[i]='\n'; break;
                        case 'e': str[i]='\x1b'; break;
                        default: dotrim = 0; break;
                        }
                        if (dotrim)
                                memmove (str+i+1, str+i+2, strlen (str+i+2));
                }
        }

        len = strlen (str);
        j = (len-len%e->size)+e->size;
        e->set_string (egg, dstvar, str, j);
        free (dstvar);
	dstvar = NULL;
}
Exemplo n.º 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);
}
Exemplo n.º 3
0
static void rcc_context(REgg *egg, int delta) {
	REggEmit *emit = egg->remit;
	char str[64];


	if (CTX>31 || CTX <0)
		return;

	nestedi[CTX]++;
	if (callname && CTX>0) {// && delta>0) {
	//	set_nested (callname);
//eprintf (" - - - - - - -  set nested d=%d c=%d (%s)\n", delta, context-1, callname);
//shownested();
	}
	CTX += delta;
	lastctxdelta = delta;

	if (CTX == 0 && delta < 0) {
		if (mode != NAKED)
			emit->frame_end (egg, stackframe+stackfixed, nbrackets);
		if (mode == NORMAL) /* XXX : commenting this makes hello.r unhappy! TODO: find a cleaner alternative */
			stackframe = 0;
		mode = NORMAL;
	} else {
		/* conditional block */
//eprintf ("Callname is (%s)\n", callname);
		const char *elm = skipspaces (elem);
		const char *cn = callname;
//if (nested[context-1])
#if 0
if (delta<0 && context>0) {
eprintf ("close bracket foo!!!\n");
shownested ();
cn = strdup (nested[context-1]);
eprintf ("STATEMENT cn=(%s) idx=%d (%s)\n", cn, context-1, nested[context-1]);
eprintf ("CNTXXXPUSH (%s)\n", ctxpush[context-1]);
#if 0
if (!strcmp (cn, "while")) {
emit->while_end (egg, get_frame_label (context-1));
	//char *var = get_frame_label (0);
	//emit->jmp (egg, var, 0);
	return;
}
#endif
}
#endif
//eprintf ("ELEM (%s)\n", elm);
//eprintf ("END BLOCK %d, (%s)\n", context, nested[context-1]);
//eprintf ("CN = (%s) %d (%s) delta=%d\n", cn, context, nested[context-1], delta);
		if (cn) {
		//if (callname) { // handle 'foo() {'
			/* TODO: this must be an array */
			char *b, *g, *e, *n;
			emit->comment (egg, "cond frame %s (%s)", cn, elm);
			/* TODO: simplify with a single for */
			b = strchr (elem, '<'); /* below */
			g = strchr (elem, '>'); /* greater */
			e = strchr (elem, '='); /* equal */
			n = strchr (elem, '!'); /* negate */
			if (!strcmp (cn, "while")) {
				char lab[128];
				sprintf (lab, "__begin_%d_%d_%d", nfunctions,
					CTX-1, nestedi[CTX-1]);
				emit->get_while_end (egg, str, ctxpush[CTX-1], lab); //get_frame_label (2));
//get_frame_label (2));
//eprintf ("------ (%s)\n", ctxpush[context-1]);
			//	free (endframe);
// XXX: endframe is deprecated, must use set_nested only
				if (delta>0) {
					set_nested (egg, str);
				}
				rcc_set_callname ("if"); // append 'if' body
			}
			if (!strcmp (cn, "if")) {
				//emit->branch (egg, b, g, e, n, varsize, get_end_frame_label (egg));
				// HACK HACK :D
				sprintf (str, "__end_%d_%d_%d", nfunctions,
					CTX-1, nestedi[CTX-1]);
				nestede[CTX-1] = strdup (str);
				sprintf (str, "__end_%d_%d_%d", nfunctions,
					CTX, nestedi[CTX-1]);
				emit->branch (egg, b, g, e, n, varsize, str);
				if (CTX>0) {
					/* XXX .. */
				}
				rcc_reset_callname ();
			} //else eprintf ("Unknown statement (%s)(%s)\n", cn, elem);
		} // handle '{ ..'
	}
}