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