1 /*
2  * OpenBOR - http://www.LavaLit.com
3  * -----------------------------------------------------------------------
4  * All rights reserved, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2011 OpenBOR Team
7  */
8 
9 /**
10  * This is the parser for the script preprocessor.  Its purpose is to emit the
11  * preprocessed source code for use by scriptlib.  It is not derived from the
12  * parser in scriptlib because it does something entirely different.
13  *
14  * @author Plombo
15  * @date 15 October 2010
16  */
17 
18 #ifndef PP_PARSER_H
19 #define PP_PARSER_H
20 
21 #include "pp_lexer.h"
22 #include "List.h"
23 #include "types.h"
24 
25 #define MACRO_CONTENTS_SIZE		512
26 
27 /*
28  * The current "state" of a single conditional (#ifdef/#else/#endif) sequence:
29  * true, false, already completed (i.e. not eligible for #elif), or non-existent.
30  */
31 enum conditional_state {
32 	cs_none = 0,
33 	cs_true = 1,
34 	cs_false = 2,
35 	cs_done = 3
36 };
37 
38 /**
39  * Stack of conditional directives.  The preprocessor can handle up to 16 nested
40  * conditionals.  The stack is implemented as a 32-bit integer.
41  */
42 typedef union {
43 	int all;
44 	struct {
45 		unsigned top:2;
46 		unsigned others:30;
47 	};
48 } conditional_stack;
49 
50 typedef struct pp_context {
51 	List macros;                       // list of currently defined non-function macros
52 	List func_macros;                  // list of currently defined function-style macros
53 	List imports;                      // list of files for the interpreter to "import"
54 	conditional_stack conditionals;    // the conditional stack
55 	int num_conditionals;              // current size of the conditional stack
56 } pp_context;
57 
58 typedef enum {
59 	PP_ROOT,
60 	PP_INCLUDE,
61 	PP_NORMAL_MACRO,
62 	PP_FUNCTION_MACRO,
63 	PP_CONCATENATE
64 } pp_parser_type;
65 
66 typedef struct pp_parser {
67 	pp_parser_type type;
68 	pp_context* ctx;
69 	pp_lexer lexer;
70 	const char* filename;
71 	char* sourceCode;
72 	int numParams;                     // parameter macros defined for a function macro parser
73 	bool freeFilename;
74 	bool freeSourceCode;
75 	pp_token token;
76 	pp_token last_token;
77 	struct pp_parser* parent;
78 	struct pp_parser* child;
79 	bool newline;
80 	bool overread;
81 } pp_parser;
82 
83 void pp_context_init(pp_context* self);
84 void pp_context_destroy(pp_context* self);
85 
86 void pp_parser_init(pp_parser* self, pp_context* ctx, const char* filename, char* sourceCode, TEXTPOS initialPosition);
87 pp_parser* pp_parser_alloc(pp_parser* parent, const char* filename, char* sourceCode, pp_parser_type type);
88 pp_parser* pp_parser_alloc_macro(pp_parser* parent, char* macroContents, int numParams, pp_parser_type type);
89 
90 pp_token* pp_parser_emit_token(pp_parser* self);
91 HRESULT pp_parser_readline(pp_parser* self, char* buf, int bufsize);
92 HRESULT pp_parser_stringify(pp_parser* self);
93 void pp_parser_concatenate(pp_parser* self, const char* token1, const char* token2);
94 HRESULT pp_parser_parse_directive(pp_parser* self);
95 HRESULT pp_parser_include(pp_parser* self, char* filename);
96 HRESULT pp_parser_define(pp_parser* self, char* name);
97 HRESULT pp_parser_conditional(pp_parser* self, PP_TOKEN_TYPE directive);
98 bool pp_parser_eval_conditional(pp_parser* self, PP_TOKEN_TYPE directive);
99 void pp_parser_insert_macro(pp_parser* self, char* name);
100 HRESULT pp_parser_insert_function_macro(pp_parser* self, char* name);
101 
102 HRESULT pp_error(pp_parser* self, char* format, ...);
103 void pp_warning(pp_parser* self, char* format, ...);
104 
105 #endif
106 
107