preliminary segregated console subsystem

This commit is contained in:
Dale Weiler 2012-11-14 19:17:43 +00:00
parent e7d558dbd8
commit f0750209b7
6 changed files with 391 additions and 80 deletions

View file

@ -24,7 +24,8 @@ OBJ = \
code.o \
ast.o \
ir.o \
error.o
error.o \
con.o
OBJ_A = test/ast-test.o
OBJ_I = test/ir-test.o
OBJ_C = main.o lexer.o parser.o

309
con.c Normal file
View file

@ -0,0 +1,309 @@
/*
* Copyright (C) 2012
* Dale Weiler
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "gmqcc.h"
/*
* isatty/STDERR_FILENO/STDOUT_FILNO
* + some other things likewise.
*/
#ifndef _WIN32
#include <unistd.h>
#endif
#define GMQCC_IS_STDOUT(X) ((X) == stdout)
#define GMQCC_IS_STDERR(X) ((X) == stderr)
#define GMQCC_IS_DEFINE(X) (GMQCC_IS_STDERR(X) || GMQCC_IS_STDOUT(X))
typedef struct {
FILE *handle_err;
FILE *handle_out;
int color_err;
int color_out;
} con_t;
/*
* Doing colored output on windows is fucking stupid. The linux way is
* the real way. So we emulate it on windows :)
*/
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/*
* Windows doesn't have constants for FILENO, sadly but the docs tell
* use the constant values.
*/
#undef STDERR_FILENO
#undef STDOUT_FILENO
#define STDERR_FILENO 2
#define STDOUT_FILENO 1
/*
* Windows and it's posix underscore bullshit. We simply fix this
* with yay, another macro :P
*/
#define isatty _isatty
enum {
RESET = 0,
BOLD = 1,
BLACK = 30,
RED,
GREEN,
YELLOW,
BLUE,
MAGENTA,
CYAN,
GRAY,
WHITE
};
enum {
WBLACK,
WBLUE,
WGREEN = 2,
WRED = 4,
WINTENSE = 8,
WCYAN = WBLUE | WGREEN,
WMAGENTA = WBLUE | WRED,
WYELLOW = WGREEN | WRED,
WWHITE = WBLUE | WGREEN | WRED
}
static const ansi2win[] = {
WBLACK,
WRED,
WGREEN,
WYELLOW,
WBLUE,
WMAGENTA,
WCYAN,
WWHITE
};
static void win_fputs(char *str, FILE *f) {
/* state for translate */
int acolor;
int wcolor;
int icolor;
int state;
int place;
/* attributes */
int intense = -1;
int colors[] = {-1, -1 };
int colorpos = 1;
CONSOLE_SCREEN_BUFFER_INFO cinfo;
GetConsoleScreenBufferInfo(
(h == stdout) ?
GetStdHandle(STD_OUTPUT_HANDLE) :
GetStdHandle(STD_ERROR_HANDLE), &cinfo
);
icolor = cinfo.wAttributes;
while (*str) {
if (*str == '\e')
state = '\e';
else if (state == '\e' && *str == '[')
state = '[';
else if (state == '[') {
if (*str != 'm') {
colors[colorpos] = *str;
colorpos--;
} else {
int find;
int mult;
for (find = colorpos + 1, acolor = 0, mult = 1; find < 2; find++) {
acolor += (colors[find] - 48) * mult;
mult *= 10;
}
/* convert to windows color */
if (acolor == BOLD)
intense = WINTENSE;
else if (acolor == RESET) {
intense = WBLACK;
wcolor = icolor;
}
else if (BLACK < acolor && acolor <= WHITE)
wcolor = ansi2win[acolor - 30];
else if (acolor == 90) {
/* special gray really white man */
wcolor = WWHITE;
intense = WBLACK;
}
SetConsoleTextattribute(
(h == stdout) ?
GetStdHandle(STD_OUTPUT_HANDLE) :
GetStdHandle(STD_ERROR_HANDLE),
wcolor | intense | (icolor & 0xF0)
);
colorpos = 1;
state = -1;
}
} else {
fputc(*str, h);
}
}
/* restore */
SetConsoleTextAttribute(
(h == stdout) ?
GetStdHandle(STD_OUTPUT_HANDLE) :
GetStdHandle(STD_ERROR_HANDLE),
icolor
);
}
#endif
/*
* We use standard files as default. These can be changed at any time
* with con_change(F, F)
*/
static con_t console;
/*
* Enables color on output if supported.
* NOTE: The support for checking colors is NULL. On windows this will
* always work, on *nix it depends if the term has colors.
*
* NOTE: This prevents colored output to piped stdout/err via isatty
* checks.
*/
static void con_enablecolor() {
if (console.handle_err == stderr || console.handle_err == stdout)
console.color_err = !!(isatty(STDERR_FILENO));
if (console.handle_out == stderr || console.handle_out == stdout)
console.color_out = !!(isatty(STDOUT_FILENO));
}
/*
* Does a write to the handle with the format string and list of
* arguments. This colorizes for windows as well via translate
* step.
*/
static int con_write(FILE *handle, const char *fmt, va_list va) {
int ln;
#ifndef _WIN32
ln = vfprintf(handle, fmt, va);
#else
{
char *data = NULL;
ln = _vscprintf(fmt, va);
data = malloc(ln + 1);
data[ln] = 0;
vsprintf(data, fmt, va);
if (GMQCC_IS_DEFINE(handle))
ln = win_fputs(data, handle);
else
ln = fputs(data, handle);
free(data);
}
#endif
return ln;
}
/**********************************************************************
* EXPOSED INTERFACE BEGINS
*********************************************************************/
void con_close() {
if (!GMQCC_IS_DEFINE(console.handle_err))
fclose(console.handle_err);
if (!GMQCC_IS_DEFINE(console.handle_out))
fclose(console.handle_out);
}
void con_color(int state) {
if (state)
con_enablecolor();
else {
console.color_err = 0;
console.color_out = 0;
}
}
void con_init() {
console.handle_err = stderr;
console.handle_out = stdout;
con_enablecolor();
}
void con_reset() {
con_close();
con_init ();
}
/*
* This is clever, say you want to change the console to use two
* files for out/err. You pass in two strings, it will properly
* close the existing handles (if they're not std* handles) and
* open them. Now say you want TO use stdout and stderr, this
* allows you to do that so long as you cast them to (char*).
* Say you need stdout for out, but want a file for error, you can
* do this too, just cast the stdout for (char*) and stick to a
* string for the error file.
*/
int con_change(const char *out, const char *err) {
con_close();
if (GMQCC_IS_DEFINE((FILE*)out)) {
console.handle_out = (((FILE*)err) == stdout) ? stdout : stderr;
con_enablecolor();
} else if (!(console.handle_out = fopen(out, "w"))) return 0;
if (GMQCC_IS_DEFINE((FILE*)err)) {
console.handle_err = (((FILE*)err) == stdout) ? stdout : stderr;
con_enablecolor();
} else if (!(console.handle_err = fopen(err, "w"))) return 0;
return 1;
}
int con_verr(const char *fmt, va_list va) {
return con_write(console.handle_err, fmt, va);
}
int con_vout(const char *fmt, va_list va) {
return con_write(console.handle_out, fmt, va);
}
int con_err(const char *fmt, ...) {
va_list va;
int ln = 0;
va_start(va, fmt);
con_verr(fmt, va);
va_end (va);
return ln;
}
int con_out(const char *fmt, ...) {
va_list va;
int ln = 0;
va_start(va, fmt);
con_vout(fmt, va);
va_end (va);
return ln;
}

17
gmqcc.h
View file

@ -528,6 +528,19 @@ uint32_t code_genstring (const char *string);
uint32_t code_cachedstring(const char *string);
qcint code_alloc_field (size_t qcsize);
/*===================================================================*/
/*============================ con.c ================================*/
/*===================================================================*/
void con_close();
void con_color(int state);
void con_init ();
void con_reset();
int con_change(const char *out, const char *err);
int con_verr (const char *fmt, va_list va);
int con_vout (const char *fmt, va_list va);
int con_err (const char *fmt, ...);
int con_out (const char *fmt, ...);
/*===================================================================*/
/*========================= assembler.c =============================*/
/*===================================================================*/
@ -605,10 +618,6 @@ static const struct {
{ "END" , 0, 3 } /* virtual assembler instruction */
};
void asm_init (const char *, FILE **);
void asm_close(FILE *);
void asm_parse(FILE *);
/*===================================================================*/
/*============================= ast.c ===============================*/
/*===================================================================*/

81
main.c
View file

@ -54,28 +54,28 @@ VECTOR_MAKE(argitem, items);
static const char *app_name;
static int usage() {
printf("usage: %s [options] [files...]", app_name);
printf("options:\n"
con_out("usage: %s [options] [files...]", app_name);
con_out("options:\n"
" -h, --help show this help message\n"
" -debug turns on compiler debug messages\n"
" -memchk turns on compiler memory leak check\n");
printf(" -o, --output=file output file, defaults to progs.dat\n"
con_out(" -o, --output=file output file, defaults to progs.dat\n"
" -a filename add an asm file to be assembled\n"
" -s filename add a progs.src file to be used\n");
printf(" -E stop after preprocessing\n");
printf(" -f<flag> enable a flag\n"
con_out(" -E stop after preprocessing\n");
con_out(" -f<flag> enable a flag\n"
" -fno-<flag> disable a flag\n"
" -std standard select one of the following standards\n"
" -std=qcc original QuakeC\n"
" -std=fteqcc fteqcc QuakeC\n"
" -std=gmqcc this compiler (default)\n");
printf(" -W<warning> enable a warning\n"
con_out(" -W<warning> enable a warning\n"
" -Wno-<warning> disable a warning\n"
" -Wall enable all warnings\n"
" -Werror treat warnings as errors\n");
printf(" -force-crc=num force a specific checksum into the header\n");
printf("\n");
printf("flags:\n"
con_out(" -force-crc=num force a specific checksum into the header\n");
con_out("\n");
con_out("flags:\n"
" -fadjust-vector-fields\n"
" when assigning a vector field, its _y and _z fields also get assigned\n"
);
@ -184,7 +184,7 @@ static bool options_parse(int argc, char **argv) {
else if (!strcmp(argarg, "qccx"))
opts_standard = COMPILER_QCCX;
else {
printf("Unknown standard: %s\n", argarg);
con_out("Unknown standard: %s\n", argarg);
return false;
}
continue;
@ -222,31 +222,31 @@ static bool options_parse(int argc, char **argv) {
case 'f':
util_strtocmd(argv[0]+2, argv[0]+2, strlen(argv[0]+2)+1);
if (!strcmp(argv[0]+2, "HELP")) {
printf("Possible flags:\n");
con_out("Possible flags:\n");
for (itr = 0; itr < COUNT_FLAGS; ++itr) {
util_strtononcmd(opts_flag_list[itr].name, buffer, sizeof(buffer));
printf(" -f%s\n", buffer);
con_out(" -f%s\n", buffer);
}
exit(0);
}
else if (!strncmp(argv[0]+2, "NO_", 3)) {
if (!options_setflag(argv[0]+5, false)) {
printf("unknown flag: %s\n", argv[0]+2);
con_out("unknown flag: %s\n", argv[0]+2);
return false;
}
}
else if (!options_setflag(argv[0]+2, true)) {
printf("unknown flag: %s\n", argv[0]+2);
con_out("unknown flag: %s\n", argv[0]+2);
return false;
}
break;
case 'W':
util_strtocmd(argv[0]+2, argv[0]+2, strlen(argv[0]+2)+1);
if (!strcmp(argv[0]+2, "HELP")) {
printf("Possible warnings:\n");
con_out("Possible warnings:\n");
for (itr = 0; itr < COUNT_WARNINGS; ++itr) {
util_strtononcmd(opts_warn_list[itr].name, buffer, sizeof(buffer));
printf(" -W%s\n", buffer);
con_out(" -W%s\n", buffer);
}
exit(0);
}
@ -270,19 +270,19 @@ static bool options_parse(int argc, char **argv) {
}
if (!strncmp(argv[0]+2, "NO_", 3)) {
if (!options_setwarn(argv[0]+5, false)) {
printf("unknown warning: %s\n", argv[0]+2);
con_out("unknown warning: %s\n", argv[0]+2);
return false;
}
}
else if (!options_setwarn(argv[0]+2, true)) {
printf("unknown warning: %s\n", argv[0]+2);
con_out("unknown warning: %s\n", argv[0]+2);
return false;
}
break;
case 'O':
if (!options_witharg(&argc, &argv, &argarg)) {
printf("option -O requires a numerical argument\n");
con_out("option -O requires a numerical argument\n");
return false;
}
opts_O = atoi(argarg);
@ -290,7 +290,7 @@ static bool options_parse(int argc, char **argv) {
case 'o':
if (!options_witharg(&argc, &argv, &argarg)) {
printf("option -o requires an argument: the output file name\n");
con_out("option -o requires an argument: the output file name\n");
return false;
}
opts_output = argarg;
@ -301,7 +301,7 @@ static bool options_parse(int argc, char **argv) {
case 's':
item.type = argv[0][1] == 'a' ? TYPE_ASM : TYPE_SRC;
if (!options_witharg(&argc, &argv, &argarg)) {
printf("option -a requires a filename %s\n",
con_out("option -a requires a filename %s\n",
(argv[0][1] == 'a' ? "containing QC-asm" : "containing a progs.src formatted list"));
return false;
}
@ -326,14 +326,14 @@ static bool options_parse(int argc, char **argv) {
opts_output = argarg;
opts_output_wasset = true;
} else {
printf("Unknown parameter: %s\n", argv[0]);
con_out("Unknown parameter: %s\n", argv[0]);
return false;
}
}
break;
default:
printf("Unknown parameter: %s\n", argv[0]);
con_out("Unknown parameter: %s\n", argv[0]);
return false;
}
}
@ -398,6 +398,7 @@ int main(int argc, char **argv) {
bool opts_output_free = false;
app_name = argv[0];
con_init();
/* default options / warn flags */
options_set(opts_warn, WARN_UNKNOWN_CONTROL_SEQUENCE, true);
@ -431,18 +432,18 @@ int main(int argc, char **argv) {
if (opts_dump) {
for (itr = 0; itr < COUNT_FLAGS; ++itr) {
printf("Flag %s = %i\n", opts_flag_list[itr].name, OPTS_FLAG(itr));
con_out("Flag %s = %i\n", opts_flag_list[itr].name, OPTS_FLAG(itr));
}
for (itr = 0; itr < COUNT_WARNINGS; ++itr) {
printf("Warning %s = %i\n", opts_warn_list[itr].name, OPTS_WARN(itr));
con_out("Warning %s = %i\n", opts_warn_list[itr].name, OPTS_WARN(itr));
}
printf("output = %s\n", opts_output);
printf("optimization level = %i\n", (int)opts_O);
printf("standard = %i\n", opts_standard);
con_out("output = %s\n", opts_output);
con_out("optimization level = %i\n", (int)opts_O);
con_out("standard = %i\n", opts_standard);
}
if (!parser_init()) {
printf("failed to initialize parser\n");
con_out("failed to initialize parser\n");
retval = 1;
goto cleanup;
}
@ -450,23 +451,17 @@ int main(int argc, char **argv) {
util_debug("COM", "starting ...\n");
if (items_elements) {
printf("Mode: manual\n");
printf("There are %lu items to compile:\n", (unsigned long)items_elements);
con_out("Mode: manual\n");
con_out("There are %lu items to compile:\n", (unsigned long)items_elements);
for (itr = 0; itr < items_elements; ++itr) {
#ifndef JS
printf(" item: %s (%s)\n",
con_out(" item: %s (%s)\n",
items_data[itr].filename,
( (items_data[itr].type == TYPE_QC ? "qc" :
(items_data[itr].type == TYPE_ASM ? "asm" :
(items_data[itr].type == TYPE_SRC ? "progs.src" :
("unknown"))))));
#endif
#ifdef JS
if (!parser_compile_string("js.qc", items_data[itr].filename))
#else
if (!parser_compile_file(items_data[itr].filename))
#endif
if (!parser_compile_file(items_data[itr].filename))
{
retval = 1;
goto cleanup;
@ -483,17 +478,17 @@ int main(int argc, char **argv) {
char *line;
size_t linelen = 0;
printf("Mode: progs.src\n");
con_out("Mode: progs.src\n");
src = util_fopen("progs.src", "rb");
if (!src) {
printf("failed to open `progs.src` for reading\n");
con_out("failed to open `progs.src` for reading\n");
retval = 1;
goto cleanup;
}
line = NULL;
if (!progs_nextline(&line, &linelen, src) || !line[0]) {
printf("illformatted progs.src file: expected output filename in first line\n");
con_out("illformatted progs.src file: expected output filename in first line\n");
retval = 1;
goto srcdone;
}
@ -506,7 +501,7 @@ int main(int argc, char **argv) {
while (progs_nextline(&line, &linelen, src)) {
if (!line[0] || (line[0] == '/' && line[1] == '/'))
continue;
printf(" src: %s\n", line);
con_out(" src: %s\n", line);
if (!parser_compile_file(line)) {
retval = 1;
goto srcdone;

View file

@ -522,7 +522,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
op = &operators[sy->ops[sy->ops_count-1].etype - 1];
ctx = sy->ops[sy->ops_count-1].ctx;
DEBUGSHUNTDO(printf("apply %s\n", op->op));
DEBUGSHUNTDO(con_out("apply %s\n", op->op));
if (sy->out_count < op->operands) {
parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", sy->out_count,
@ -826,7 +826,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
return false;
}
if (opts_standard == COMPILER_GMQCC)
printf("TODO: early out logic\n");
con_out("TODO: early out logic\n");
if (CanConstFold(exprs[0], exprs[1]))
out = (ast_expression*)parser_const_float(parser,
(generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
@ -956,7 +956,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
return false;
}
DEBUGSHUNTDO(printf("applied %s\n", op->op));
DEBUGSHUNTDO(con_out("applied %s\n", op->op));
sy->out[sy->out_count++] = syexp(ctx, out);
return true;
}
@ -1183,7 +1183,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
parseerror(parser, "out of memory");
goto onerr;
}
DEBUGSHUNTDO(printf("push %s\n", parser_tokval(parser)));
DEBUGSHUNTDO(con_out("push %s\n", parser_tokval(parser)));
}
else if (parser->tok == TOKEN_FLOATCONST) {
ast_value *val;
@ -1199,7 +1199,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
parseerror(parser, "out of memory");
goto onerr;
}
DEBUGSHUNTDO(printf("push %g\n", parser_token(parser)->constval.f));
DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f));
}
else if (parser->tok == TOKEN_INTCONST) {
ast_value *val;
@ -1215,7 +1215,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
parseerror(parser, "out of memory");
goto onerr;
}
DEBUGSHUNTDO(printf("push %i\n", parser_token(parser)->constval.i));
DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i));
}
else if (parser->tok == TOKEN_STRINGCONST) {
ast_value *val;
@ -1231,7 +1231,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
parseerror(parser, "out of memory");
goto onerr;
}
DEBUGSHUNTDO(printf("push string\n"));
DEBUGSHUNTDO(con_out("push string\n"));
}
else if (parser->tok == TOKEN_VECTORCONST) {
ast_value *val;
@ -1247,7 +1247,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
parseerror(parser, "out of memory");
goto onerr;
}
DEBUGSHUNTDO(printf("push '%g %g %g'\n",
DEBUGSHUNTDO(con_out("push '%g %g %g'\n",
parser_token(parser)->constval.v.x,
parser_token(parser)->constval.v.y,
parser_token(parser)->constval.v.z));
@ -1258,7 +1258,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
}
else if (parser->tok == ')') {
if (wantop) {
DEBUGSHUNTDO(printf("do[op] )\n"));
DEBUGSHUNTDO(con_out("do[op] )\n"));
--parens;
if (parens < 0)
break;
@ -1267,7 +1267,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
if (!parser_close_paren(parser, &sy, false))
goto onerr;
} else {
DEBUGSHUNTDO(printf("do[nop] )\n"));
DEBUGSHUNTDO(con_out("do[nop] )\n"));
--parens;
if (parens < 0)
break;
@ -1348,7 +1348,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
if (op->id == opid1('(')) {
if (wantop) {
DEBUGSHUNTDO(printf("push [op] (\n"));
DEBUGSHUNTDO(con_out("push [op] (\n"));
++parens;
/* we expected an operator, this is the function-call operator */
if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) {
@ -1361,11 +1361,11 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
parseerror(parser, "out of memory");
goto onerr;
}
DEBUGSHUNTDO(printf("push [nop] (\n"));
DEBUGSHUNTDO(con_out("push [nop] (\n"));
}
wantop = false;
} else {
DEBUGSHUNTDO(printf("push operator %s\n", op->op));
DEBUGSHUNTDO(con_out("push operator %s\n", op->op));
if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
goto onerr;
wantop = false;
@ -1392,7 +1392,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
expr = sy.out[0].out;
MEM_VECTOR_CLEAR(&sy, out);
MEM_VECTOR_CLEAR(&sy, ops);
DEBUGSHUNTDO(printf("shunt done\n"));
DEBUGSHUNTDO(con_out("shunt done\n"));
return expr;
onerr:
@ -2891,7 +2891,7 @@ bool parser_compile_file(const char *filename)
{
parser->lex = lex_open(filename);
if (!parser->lex) {
printf("failed to open file \"%s\"\n", filename);
con_out("failed to open file \"%s\"\n", filename);
return false;
}
return parser_compile();
@ -2901,7 +2901,7 @@ bool parser_compile_string(const char *name, const char *str)
{
parser->lex = lex_open_string(str, strlen(str), name);
if (!parser->lex) {
printf("failed to create lexer for string \"%s\"\n", name);
con_out("failed to create lexer for string \"%s\"\n", name);
return false;
}
return parser_compile();
@ -3023,7 +3023,7 @@ bool parser_finish(const char *output)
{
ir = ir_builder_new("gmqcc_out");
if (!ir) {
printf("failed to allocate builder\n");
con_out("failed to allocate builder\n");
return false;
}
@ -3036,7 +3036,7 @@ bool parser_finish(const char *output)
isconst = field->isconst;
field->isconst = false;
if (!ast_global_codegen((ast_value*)field, ir)) {
printf("failed to generate field %s\n", field->name);
con_out("failed to generate field %s\n", field->name);
ir_builder_delete(ir);
return false;
}
@ -3067,40 +3067,40 @@ bool parser_finish(const char *output)
}
}
if (!ast_global_codegen(asvalue, ir)) {
printf("failed to generate global %s\n", parser->globals[i].name);
con_out("failed to generate global %s\n", parser->globals[i].name);
ir_builder_delete(ir);
return false;
}
}
for (i = 0; i < parser->imm_float_count; ++i) {
if (!ast_global_codegen(parser->imm_float[i], ir)) {
printf("failed to generate global %s\n", parser->imm_float[i]->name);
con_out("failed to generate global %s\n", parser->imm_float[i]->name);
ir_builder_delete(ir);
return false;
}
}
for (i = 0; i < parser->imm_string_count; ++i) {
if (!ast_global_codegen(parser->imm_string[i], ir)) {
printf("failed to generate global %s\n", parser->imm_string[i]->name);
con_out("failed to generate global %s\n", parser->imm_string[i]->name);
ir_builder_delete(ir);
return false;
}
}
for (i = 0; i < parser->imm_vector_count; ++i) {
if (!ast_global_codegen(parser->imm_vector[i], ir)) {
printf("failed to generate global %s\n", parser->imm_vector[i]->name);
con_out("failed to generate global %s\n", parser->imm_vector[i]->name);
ir_builder_delete(ir);
return false;
}
}
for (i = 0; i < parser->functions_count; ++i) {
if (!ast_function_codegen(parser->functions[i], ir)) {
printf("failed to generate function %s\n", parser->functions[i]->name);
con_out("failed to generate function %s\n", parser->functions[i]->name);
ir_builder_delete(ir);
return false;
}
if (!ir_function_finalize(parser->functions[i]->ir_func)) {
printf("failed to finalize function %s\n", parser->functions[i]->name);
con_out("failed to finalize function %s\n", parser->functions[i]->name);
ir_builder_delete(ir);
return false;
}
@ -3108,12 +3108,12 @@ bool parser_finish(const char *output)
if (retval) {
if (opts_dump)
ir_builder_dump(ir, printf);
ir_builder_dump(ir, con_out);
generate_checksum(parser);
if (!ir_builder_generate(ir, output)) {
printf("*** failed to generate output file\n");
con_out("*** failed to generate output file\n");
ir_builder_delete(ir);
return false;
}
@ -3123,6 +3123,6 @@ bool parser_finish(const char *output)
return retval;
}
printf("*** there were compile errors\n");
con_out("*** there were compile errors\n");
return false;
}

7
util.c
View file

@ -242,11 +242,8 @@ void util_debug(const char *area, const char *ms, ...) {
return;
va_start(va, ms);
fprintf (stdout, "DEBUG: ");
fputc ('[', stdout);
fprintf(stdout, "%s", area);
fputs ("] ", stdout);
vfprintf(stdout, ms, va);
con_out ("[%s] ", area);
con_vout(ms, va);
va_end (va);
}