Mercurial > hg-old > index.cgi
diff lwasm/pseudo.c @ 356:7166254491ed
Finished pseudo ops
author | lost@starbug |
---|---|
date | Wed, 31 Mar 2010 18:46:32 -0600 |
parents | 60568b123281 |
children | d96c30e60ddf |
line wrap: on
line diff
--- a/lwasm/pseudo.c Tue Mar 30 23:12:41 2010 -0600 +++ b/lwasm/pseudo.c Wed Mar 31 18:46:32 2010 -0600 @@ -21,8 +21,11 @@ #include <config.h> +#include <stdio.h> + #include "lwasm.h" #include "instab.h" +#include "input.h" #include "lw_string.h" @@ -912,3 +915,188 @@ lwasm_register_error(as, l, "User error: %s", *p); skip_operand(p); } + +PARSEFUNC(pseudo_parse_includebin) +{ + char *fn, *p2; + int delim = 0; + FILE *fp; + long flen; + + if (!**p) + { + lwasm_register_error(as, l, "Missing filename"); + return; + } + + if (**p == '"' || **p == '\'') + { + delim = **p; + (*p)++; + + for (p2 = *p; *p2 && *p2 != delim; p2++) + /* do nothing */ ; + } + else + { + for (p2 = *p; *p2 && !isspace(*p2); p2++) + /* do nothing */ ; + } + fn = lw_strndup(*p, p2 - *p); + + if (delim && **p) + (*p)++; + + fp = input_open_standalone(as, fn); + if (!fp) + { + lwasm_register_error(as, l, "Cannot open file"); + lw_free(fn); + return; + } + + l -> lstr = fn; + + fseek(fp, 0, SEEK_END); + flen = ftell(fp); + fclose(fp); + + l -> len = flen; +} + +EMITFUNC(pseudo_emit_includebin) +{ + FILE *fp; + int c; + + fp = input_open_standalone(as, l -> lstr); + if (!fp) + { + lwasm_register_error(as, l, "Cannot open file (emit)!"); + return; + } + + for (;;) + { + c = fgetc(fp); + if (c == EOF) + { + fclose(fp); + return; + } + lwasm_emit(l, c); + } +} + +PARSEFUNC(pseudo_parse_include) +{ + char *fn, *p2; + int delim = 0; + + if (!**p) + { + lwasm_register_error(as, l, "Missing filename"); + return; + } + + if (**p == '"' || **p == '\'') + { + delim = **p; + (*p)++; + + for (p2 = *p; *p2 && *p2 != delim; p2++) + /* do nothing */ ; + } + else + { + for (p2 = *p; *p2 && !isspace(*p2); p2++) + /* do nothing */ ; + } + fn = lw_strndup(*p, p2 - *p); + + if (delim && **p) + (*p)++; + + input_open(as, fn); + + l -> len = 0; +} + +PARSEFUNC(pseudo_parse_align) +{ + lw_expr_t e; + + if (!**p) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + lwasm_save_expr(l, 0, e); + + if (**p == ',') + { + e = lwasm_parse_expr(as, p); + } + else + { + e = lw_expr_build(lw_expr_type_int, 0); + } + if (!e) + { + lwasm_register_error(as, l, "Bad padding"); + return; + } + + lwasm_save_expr(l, 1, e); +} + +RESOLVEFUNC(pseudo_resolve_align) +{ + lw_expr_t e; + int align; + + e = lwasm_fetch_expr(l, 0); + + if (lw_expr_istype(e, lw_expr_type_int)) + { + align = lw_expr_intval(e); + if (align < 1) + { + lwasm_register_error(as, l, "Invalid alignment"); + return; + } + } + + if (lw_expr_istype(l -> addr, lw_expr_type_int)) + { + int a; + a = lw_expr_intval(l -> addr); + if (a % align == 0) + { + l -> len = 0; + return; + } + l -> len = align - (a % align); + return; + } +} + +EMITFUNC(pseudo_emit_align) +{ + lw_expr_t e; + int i; + + e = lwasm_fetch_expr(l, 1); + for (i = 0; i < l -> len; i++) + { + lwasm_emitexpr(l, e, 1); + } +}