1 /* 2 * OpenBOR - http://www.LavaLit.com 3 * ----------------------------------------------------------------------- 4 * All rights reserved, see LICENSE in OpenBOR root for details. 5 * 6 * Copyright (c) 2004 - 2013 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 { 33 cs_none = 0, 34 cs_true = 1, 35 cs_false = 2, 36 cs_done = 3 37 }; 38 39 /** 40 * Stack of conditional directives. The preprocessor can handle up to 16 nested 41 * conditionals. The stack is implemented as a 32-bit integer. 42 */ 43 typedef union 44 { 45 u64 all; 46 struct 47 { 48 u64 top: 2; 49 u64 others: 62; 50 }; 51 } conditional_stack; 52 53 typedef struct pp_context 54 { 55 List macros; // list of currently defined non-function macros 56 List func_macros; // list of currently defined function-style macros 57 List imports; // list of files for the interpreter to "import" 58 conditional_stack conditionals; // the conditional stack 59 int num_conditionals; // current size of the conditional stack 60 } pp_context; 61 62 typedef enum 63 { 64 PP_ROOT, 65 PP_INCLUDE, 66 PP_NORMAL_MACRO, 67 PP_FUNCTION_MACRO, 68 PP_CONCATENATE, 69 PP_CONDITIONAL 70 } pp_parser_type; 71 72 typedef struct pp_parser 73 { 74 pp_parser_type type; 75 pp_context *ctx; 76 pp_lexer lexer; 77 const char *filename; 78 char *sourceCode; 79 int numParams; // parameter macros defined for a function macro parser 80 char *macroName; 81 bool freeFilename; 82 bool freeSourceCode; 83 pp_token token; 84 pp_token last_token; 85 struct pp_parser *parent; 86 struct pp_parser *child; 87 bool newline; 88 bool overread; 89 } pp_parser; 90 91 void pp_context_init(pp_context *self); 92 void pp_context_destroy(pp_context *self); 93 94 void pp_parser_init(pp_parser *self, pp_context *ctx, const char *filename, char *sourceCode, TEXTPOS initialPosition); 95 pp_parser *pp_parser_alloc(pp_parser *parent, const char *filename, char *sourceCode, pp_parser_type type); 96 pp_parser *pp_parser_alloc_macro(pp_parser *parent, char *macroContents, int numParams, pp_parser_type type); 97 98 pp_token *pp_parser_emit_token(pp_parser *self); 99 HRESULT pp_parser_lex_token(pp_parser *self, bool skip_whitespace); 100 HRESULT pp_parser_readline(pp_parser *self, char *buf, int bufsize); 101 HRESULT pp_parser_stringify(pp_parser *self); 102 void pp_parser_concatenate(pp_parser *self, const char *token1, const char *token2); 103 HRESULT pp_parser_parse_directive(pp_parser *self); 104 HRESULT pp_parser_include(pp_parser *self, char *filename); 105 HRESULT pp_parser_define(pp_parser *self, char *name); 106 HRESULT pp_parser_conditional(pp_parser *self, PP_TOKEN_TYPE directive); 107 HRESULT pp_parser_eval_conditional(pp_parser *self, PP_TOKEN_TYPE directive, int *result); 108 void pp_parser_insert_macro(pp_parser *self, char *name); 109 HRESULT pp_parser_insert_function_macro(pp_parser *self, char *name); 110 bool pp_is_builtin_macro(const char *name); 111 void pp_parser_insert_builtin_macro(pp_parser *self, const char *name); 112 bool pp_parser_is_defined(pp_parser *self, const char *name); 113 114 HRESULT pp_error(pp_parser *self, char *format, ...); 115 void pp_warning(pp_parser *self, char *format, ...); 116 117 #endif 118 119