# HG changeset patch # User William Astle # Date 1379810619 21600 # Node ID 41118fb0a8f250a70a754ecfc0e640ec48240947 # Parent 7957e90d0a35297dd1ac53546b37d7cbdb57d8b2 Add no-op parser and parse tree infrastructure diff -r 7957e90d0a35 -r 41118fb0a8f2 Makefile --- a/Makefile Sat Sep 21 13:53:18 2013 -0600 +++ b/Makefile Sat Sep 21 18:43:39 2013 -0600 @@ -108,7 +108,7 @@ lwcc_cpp_objs := $(lwcc_cpp_srcs:.c=.o) lwcc_cpp_deps := $(lwcc_cpp_srcs:.c=.d) -lwcc_cc_srcs := cc-main.c +lwcc_cc_srcs := cc-main.c tree.c parse.c lwcc_cc_srcs := $(addprefix lwcc/,$(lwcc_cc_srcs)) lwcc_cc_objs := $(lwcc_cc_srcs:.c=.o) lwcc_cc_deps := $(lwcc_cc_srcs:.c=.d) diff -r 7957e90d0a35 -r 41118fb0a8f2 lwcc/cc-main.c --- a/lwcc/cc-main.c Sat Sep 21 13:53:18 2013 -0600 +++ b/lwcc/cc-main.c Sat Sep 21 18:43:39 2013 -0600 @@ -30,9 +30,13 @@ #include #include "cpp.h" +#include "tree.h" -int process_file(const char *); +node_t *process_file(const char *); static void do_error(const char *f, ...); +extern node_t *parse_program(struct preproc_info *pp); + +node_t *program_tree = NULL; /* command line option handling */ #define PROGVER "lwcc-cc from " PACKAGE_STRING @@ -112,6 +116,7 @@ { program_name = argv[0]; int retval = 0; + node_t *n; input_files = lw_stringlist_create(); includedirs = lw_stringlist_create(); @@ -135,10 +140,16 @@ } } + program_tree = node_create(NODE_PROGRAM); + if (lw_stringlist_nstrings(input_files) == 0) { /* if no input files, work on stdin */ - retval = process_file("-"); + n = process_file("-"); + if (!n) + retval = 1; + else + node_addchild(program_tree, n); } else { @@ -146,47 +157,33 @@ lw_stringlist_reset(input_files); for (s = lw_stringlist_current(input_files); s; s = lw_stringlist_next(input_files)) { - retval = process_file(s); + n = process_file(s); + if (!n) + retval = 1; if (retval != 0) break; + node_addchild(program_tree, n); } } lw_stringlist_destroy(input_files); lw_stringlist_destroy(includedirs); lw_stringlist_destroy(sysincludedirs); lw_stringlist_destroy(macrolist); + + node_display(program_tree, stdout); + node_destroy(program_tree); exit(retval); } -static void print_line_marker(FILE *fp, int line, const char *fn, int flag) -{ - fprintf(fp, "\n# %d \"", line); - while (*fn) - { - if (*fn < 32 || *fn == 34 || *fn > 126) - { - fprintf(fp, "\\%03o", *fn); - } - else - { - fprintf(fp, "%c", *fn); - } - fn++; - } - fprintf(fp, "\" %d", flag); -} - -int process_file(const char *fn) +node_t *process_file(const char *fn) { struct preproc_info *pp; - struct token *tok = NULL; - int last_line = 0; - char *last_fn = NULL; char *tstr; - + node_t *n; + pp = preproc_init(fn); if (!pp) - return -1; + return NULL; /* set up the include paths */ lw_stringlist_reset(includedirs); @@ -208,43 +205,9 @@ preproc_add_macro(pp, tstr); } - print_line_marker(output_fp, 1, fn, 1); - last_fn = lw_strdup(fn); - for (;;) - { - tok = preproc_next(pp); - if (tok -> ttype == TOK_EOF) - break; - if (strcmp(tok -> fn, last_fn) != 0) - { - int lt = 1; - if (tok -> lineno != 1) - { - lt = 2; - } - lw_free(last_fn); - last_fn = lw_strdup(tok -> fn); - last_line = tok -> lineno; - print_line_marker(output_fp, last_line, last_fn, lt); - } - else - { - while (tok -> lineno > last_line) - { - fprintf(output_fp, "\n"); - last_line++; - } - } - token_print(tok, output_fp); - if (tok -> ttype == TOK_EOL) - last_line++; - token_free(tok); - } - token_free(tok); - lw_free(last_fn); -// symtab_dump(pp); + n = parse_program(pp); preproc_finish(pp); - return 0; + return n; } static void do_error(const char *f, ...) diff -r 7957e90d0a35 -r 41118fb0a8f2 lwcc/parse.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwcc/parse.c Sat Sep 21 18:43:39 2013 -0600 @@ -0,0 +1,28 @@ +/* +lwcc/parse.c + +Copyright © 2013 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include "cpp.h" +#include "tree.h" + +node_t *parse_program(struct preproc_info *pp) +{ + return node_create(NODE_NONE); +} diff -r 7957e90d0a35 -r 41118fb0a8f2 lwcc/tree.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwcc/tree.c Sat Sep 21 18:43:39 2013 -0600 @@ -0,0 +1,139 @@ +/* +lwcc/tree.c + +Copyright © 2013 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include +#include +#include + +#include "tree.h" + +static char *node_names[] = { + "NONE", + "PROGRAM", +}; + + + +node_t *node_create(int type, ...) +{ + node_t *r; + int nargs = 0; + va_list args; + + va_start(args, type); + r = lw_alloc(sizeof(node_t)); + memset(r, sizeof(node_t), 0); + r -> type = type; + + switch (type) + { + } + + while (nargs--) + { + node_addchild(r, va_arg(args, node_t *)); + } + va_end(args); + return r; +} + +void node_destroy(node_t *node) +{ + node_t *n; + + while (node -> children) + { + n = node -> children -> next_child; + node_destroy(node -> children); + node -> children = n; + } + lw_free(node -> strval); + lw_free(node); +} + +void node_addchild(node_t *node, node_t *nn) +{ + node_t *tmp; + + nn -> parent = node; + nn -> next_child = NULL; + if (node -> children) + { + for (tmp = node -> children; tmp -> next_child; tmp = tmp -> next_child) + /* do nothing */ ; + tmp -> next_child = nn; + } + else + { + node -> children = nn; + } +} + +void node_removechild(node_t *node, node_t *nn) +{ + node_t **pp; + node_t *np; + + if (!node) + node = nn -> parent; + + pp = &(node -> children); + for (np = node -> children; np; np = np -> next_child) + { + if (np -> next_child == nn) + break; + pp = &((*pp) -> next_child); + } + if (!np) + return; + + *pp = nn -> next_child; + nn -> parent = NULL; + nn -> next_child = NULL; +} + +void node_removechild_destroy(node_t *node, node_t *nn) +{ + node_removechild(node, nn); + node_destroy(nn); +} + +static void node_display_aux(node_t *node, FILE *f, int level) +{ + node_t *nn; + int i; + + for (i = 0; i < level * 4; i++) + fputc(' ', f); + fprintf(f, "(%s ", node_names[node -> type]); + fputc('\n', f); + for (nn = node -> children; nn; nn = nn -> next_child) + node_display_aux(nn, f, level + 1); + for (i = 0; i < level * 4; i++) + fputc(' ', f); + fputc(')', f); + fputc('\n', f); +} + +void node_display(node_t *node, FILE *f) +{ + node_display_aux(node, f, 0); +} diff -r 7957e90d0a35 -r 41118fb0a8f2 lwcc/tree.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwcc/tree.h Sat Sep 21 18:43:39 2013 -0600 @@ -0,0 +1,51 @@ +/* +lwcc/tree.h + +Copyright © 2013 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#ifndef tree_h_seen___ +#define tree_h_seen___ + +#include + +/* the various node types */ +#define NODE_NONE 0 // a node with no type +#define NODE_PROGRAM 1 // the whole program +#define NODE_NUMTYPES 2 // the number of node types + +typedef struct node_s node_t; + +struct node_s +{ + int type; // node type + char *strval; // any string value associated with the node + unsigned char ival[8]; // any 64 bit integer value associated with the node, signed or unsigned + node_t *children; // pointer to list of child nodes + node_t *next_child; // pointer to next child in the list + node_t *parent; // pointer to parent node +}; + +extern node_t *node_create(int, ...); +extern void node_destroy(node_t *); +extern void node_addchild(node_t *, node_t *); +extern void node_removechild(node_t *, node_t *); +extern void node_display(node_t *, FILE *); +extern void node_removechild_destroy(node_t *, node_t *); + +#endif // tree_h_seen___