src/parser.h

changeset 86
43fe4be38a58
parent 85
264a61e9eba0
--- a/src/parser.h	Sun Jan 19 20:39:30 2014 +0200
+++ b/src/parser.h	Sun Jan 26 23:18:48 2014 +0200
@@ -32,18 +32,26 @@
 #include <stdio.h>
 #include "main.h"
 #include "commands.h"
-#include "object_writer.h"
 #include "lexer_scanner.h"
 #include "tokens.h"
 
-#define MAX_FILESTACK 8
 #define MAX_SCOPE 32
 #define MAX_CASE 64
+#define MAX_MARKS 512 // TODO: get rid of this
 
+class data_buffer;
 class lexer;
 class script_variable;
 
+struct undefined_label
+{
+	string		name;
+	byte_mark*	target;
+};
+
+// ============================================================================
 // Operators
+//
 enum operator_e
 {
 	OPER_ADD,
@@ -76,6 +84,8 @@
 	OPER_STRLEN,
 };
 
+// ============================================================================
+//
 struct operator_info
 {
 	operator_e		opercode;
@@ -83,7 +93,9 @@
 	e_token			token;
 };
 
+// ============================================================================
 // Mark types
+//
 enum marktype_e
 {
 	e_label_mark,
@@ -91,7 +103,9 @@
 	e_internal_mark, // internal structures
 };
 
-// Block types
+// ============================================================================
+// Scope types
+//
 enum scopetype_e
 {
 	e_unknown_scope,
@@ -104,32 +118,34 @@
 };
 
 // ============================================================================
-// Meta-data about blocks
+// Meta-data about scopes
+//
 struct ScopeInfo
 {
-	int mark1;
-	int mark2;
-	scopetype_e type;
-	data_buffer* buffer1;
+	byte_mark*		mark1;
+	byte_mark*		mark2;
+	scopetype_e		type;
+	data_buffer*	buffer1;
 
 	// switch-related stuff
 	// Which case are we at?
-	short casecursor;
+	int				casecursor;
 
 	// Marks to case-blocks
-	int casemarks[MAX_CASE];
+	byte_mark*		casemarks[MAX_CASE];
 
 	// Numbers of the case labels
-	int casenumbers[MAX_CASE];
+	int				casenumbers[MAX_CASE];
 
 	// actual case blocks
-	data_buffer* casebuffers[MAX_CASE];
+	data_buffer*	casebuffers[MAX_CASE];
 
 	// What is the current buffer of the block?
-	data_buffer* recordbuffer;
+	data_buffer*	recordbuffer;
 };
 
 // ============================================================================
+//
 struct constant_info
 {
 	string name;
@@ -138,71 +154,105 @@
 };
 
 // ============================================================================
-// The script reader reads the script, parses it and tells the object writer
-// the bytecode it needs to write to file.
+//
 class botscript_parser
 {
 	public:
 		// ====================================================================
-		// TODO: make private
-		FILE* fp[MAX_FILESTACK];
-		string filepath[MAX_FILESTACK];
-		int fc;
-
-		int pos[MAX_FILESTACK];
-		int curline[MAX_FILESTACK];
-		int curchar[MAX_FILESTACK];
-		ScopeInfo scopestack[MAX_SCOPE];
-		long savedpos[MAX_FILESTACK]; // filepointer cursor position
-		int commentmode;
-		long prevpos;
-		string prevtoken;
-
-		// ====================================================================
 		// METHODS
 		botscript_parser();
 		~botscript_parser();
-		void parse_botscript (string file_name, object_writer* w);
-		data_buffer* ParseCommand (command_info* comm);
-		data_buffer* parse_expression (type_e reqtype);
-		data_buffer* parse_assignment (script_variable* var);
-		int parse_operator (bool peek = false);
-		data_buffer* parse_expr_value (type_e reqtype);
-		string parse_float ();
-		void push_scope ();
-		data_buffer* parse_statement ();
-		void add_switch_case (data_buffer* b);
-		void check_toplevel();
-		void check_not_toplevel();
-		bool token_is (e_token a);
-		string token_string();
-		string describe_position() const;
+		void			parse_botscript (string file_name);
+		data_buffer*	parse_command (command_info* comm);
+		data_buffer*	parse_expression (type_e reqtype);
+		data_buffer*	parse_assignment (script_variable* var);
+		int				parse_operator (bool peek = false);
+		data_buffer*	parse_expr_value (type_e reqtype);
+		string			parse_float();
+		void			push_scope();
+		data_buffer*	parse_statement();
+		void			add_switch_case (data_buffer* b);
+		void			check_toplevel();
+		void			check_not_toplevel();
+		bool			token_is (e_token a);
+		string			token_string();
+		string			describe_position() const;
+		void			write_to_file (string outfile);
+
+		inline int get_num_events() const
+		{
+			return m_num_events;
+		}
+
+		inline int get_num_states() const
+		{
+			return m_num_states;
+		}
 
 	private:
-		lexer*			m_lx;
-		object_writer*	m_writer;
+		// The lexer we're using.
+		lexer*					m_lx;
+
+		// The main buffer - the contents of this is what we
+		// write to file after parsing is complete
+		data_buffer*			m_main_buffer;
+
+		// onenter buffer - the contents of the onenter{} block
+		// is buffered here and is merged further at the end of state
+		data_buffer*			m_on_enter_buffer;
+
+		// Mainloop buffer - the contents of the mainloop{} block
+		// is buffered here and is merged further at the end of state
+		data_buffer*			m_main_loop_buffer;
+
+		// Switch buffer - switch case data is recorded to this
+		// buffer initially, instead of into main buffer.
+		data_buffer*			m_switch_buffer;
+
+		int						m_num_states;
+		int						m_num_events;
+		parsermode_e			m_current_mode;
+		string					m_current_state;
+		bool					m_state_spawn_defined;
+		bool					m_got_main_loop;
+		int						m_scope_cursor;
+		data_buffer*			m_if_expression;
+		bool					m_can_else;
+		list<undefined_label>	m_undefined_labels;
+		list<constant_info>		m_constants;
 
-		void parse_state_block();
-		void parse_event_block();
-		void parse_mainloop();
-		void parse_on_enter_exit();
-		void parse_variable_declaration();
-		void parse_goto();
-		void parse_if();
-		void parse_else();
-		void parse_while_block();
-		void parse_for_block();
-		void parse_do_block();
-		void parse_switch_block();
-		void parse_switch_case();
-		void parse_switch_default();
-		void parse_break();
-		void parse_continue();
-		void parse_block_end();
-		void parse_const();
-		void parse_label();
-		void parse_eventdef();
-		void parse_funcdef();
+		// How many bytes have we written to file?
+		int				m_num_written_bytes;
+
+		// Scope data
+		// TODO: make a list
+		ScopeInfo		m_scope_stack[MAX_SCOPE];
+
+		data_buffer*	buffer();
+		constant_info*	find_constant (const string& tok);
+		void			parse_state_block();
+		void			parse_event_block();
+		void			parse_mainloop();
+		void			parse_on_enter_exit();
+		void			parse_variable_declaration();
+		void			parse_goto();
+		void			parse_if();
+		void			parse_else();
+		void			parse_while_block();
+		void			parse_for_block();
+		void			parse_do_block();
+		void			parse_switch_block();
+		void			parse_switch_case();
+		void			parse_switch_default();
+		void			parse_break();
+		void			parse_continue();
+		void			parse_block_end();
+		void			parse_const();
+		void			parse_label();
+		void			parse_eventdef();
+		void			parse_funcdef();
+		void			write_member_buffers();
+		void			write_string_table();
 };
 
 constant_info* find_constant (const string& tok);

mercurial