1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ 5 * Copyright (c) 2009-2016, The OpenClonk Team and contributors 6 * 7 * Distributed under the terms of the ISC license; see accompanying file 8 * "COPYING" for details. 9 * 10 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 11 * See accompanying file "TRADEMARK" for details. 12 * 13 * To redistribute this file separately, substitute the full license texts 14 * for the above references. 15 */ 16 17 #ifndef INC_C4AulParse 18 #define INC_C4AulParse 19 20 #include "script/C4Aul.h" 21 #include "script/C4AulAST.h" 22 #include "script/C4AulCompiler.h" 23 #include "script/C4AulScriptFunc.h" 24 25 #include <stack> 26 27 enum C4AulBCCType : int; 28 enum C4AulTokenType : int; 29 30 struct C4ScriptOpDef 31 { 32 unsigned short Priority; 33 const char* Identifier; 34 C4AulBCCType Code; 35 bool Postfix; 36 bool Changer; // changes first operand to result, rewrite to "a = a (op) b" 37 bool NoSecondStatement; // no second statement expected (++/-- postfix) 38 C4V_Type RetType; // type returned. ignored by C4V 39 C4V_Type Type1; 40 C4V_Type Type2; 41 }; 42 43 extern const C4ScriptOpDef C4ScriptOpMap[]; 44 45 class C4AulParse 46 { 47 public: 48 C4AulParse(class C4ScriptHost *host); 49 C4AulParse(C4AulScriptFunc * Fn, C4AulScriptContext* context, C4AulScriptEngine *Engine); 50 ~C4AulParse(); 51 std::unique_ptr<::aul::ast::FunctionDecl> Parse_DirectExec(const char *code, bool whole_function); 52 std::unique_ptr<::aul::ast::Script> Parse_Script(C4ScriptHost *); 53 54 private: 55 C4AulScriptFunc *Fn; C4ScriptHost * Host; C4ScriptHost * pOrgScript; 56 C4AulScriptEngine *Engine; 57 const char *SPos; // current position in the script 58 const char *TokenSPos; // start of the current token in the script 59 char Idtf[C4AUL_MAX_Identifier]; // current identifier 60 C4AulTokenType TokenType; // current token type 61 int32_t cInt; // current int constant 62 C4String * cStr; // current string constant 63 C4AulScriptContext* ContextToExecIn; 64 void Parse_Function(bool parse_for_direct_exec); 65 void Parse_WarningPragma(); 66 67 protected: 68 // All of the Parse_* functions need to be protected (not private!) so 69 // we can make them public in a derived class for unit testing purposes 70 std::unique_ptr<::aul::ast::FunctionDecl> Parse_ToplevelFunctionDecl(); 71 std::unique_ptr<::aul::ast::Stmt> Parse_Statement(); 72 std::unique_ptr<::aul::ast::Block> Parse_Block(); 73 std::unique_ptr<::aul::ast::ArrayLit> Parse_Array(); 74 std::unique_ptr<::aul::ast::ProplistLit> Parse_PropList(); 75 std::unique_ptr<::aul::ast::DoLoop> Parse_DoWhile(); 76 std::unique_ptr<::aul::ast::WhileLoop> Parse_While(); 77 std::unique_ptr<::aul::ast::If> Parse_If(); 78 std::unique_ptr<::aul::ast::ForLoop> Parse_For(); 79 std::unique_ptr<::aul::ast::RangeLoop> Parse_ForEach(); 80 std::unique_ptr<::aul::ast::Expr> Parse_Expression(int iParentPrio = -1); 81 std::unique_ptr<::aul::ast::VarDecl> Parse_Var(); 82 void Shift(); 83 84 private: 85 void Parse_Function(::aul::ast::Function *func); 86 void Parse_CallParams(::aul::ast::CallExpr *call); 87 88 bool AdvanceSpaces(); // skip whitespaces; return whether script ended 89 int GetOperator(const char* pScript); 90 void ClearToken(); // clear any data held with the current token 91 C4AulTokenType GetNextToken(); // get next token of SPos 92 93 void Match(C4AulTokenType TokenType, const char * Expected = nullptr); 94 void Check(C4AulTokenType TokenType, const char * Expected = nullptr); 95 NORETURN void UnexpectedToken(const char * Expected); 96 97 void Warn(C4AulWarningId warning, ...); 98 bool IsWarningEnabled(const char *pos, C4AulWarningId warning) const; 99 void Error(const char *pMsg, ...) GNUC_FORMAT_ATTRIBUTE_O; 100 void AppendPosition(StdStrBuf & Buf); 101 102 friend class C4AulParseError; 103 std::stack<const char *> parse_pos_stack; 104 void PushParsePos(); 105 void PopParsePos(); 106 void DiscardParsePos(); 107 }; 108 109 #endif 110