src/parser.cc

changeset 82
841562f5a32f
parent 77
ad17801b1a36
child 85
264a61e9eba0
--- a/src/parser.cc	Sat Jan 18 02:11:45 2014 +0200
+++ b/src/parser.cc	Sun Jan 19 20:16:00 2014 +0200
@@ -185,6 +185,14 @@
 				parse_const();
 				break;
 
+			case tk_eventdef:
+				parse_eventdef();
+				break;
+
+			case tk_funcdef:
+				parse_funcdef();
+				break;
+
 			default:
 			{
 				// Check for labels
@@ -882,6 +890,110 @@
 	m_lx->must_get_next (tk_colon);
 }
 
+// =============================================================================
+//
+void botscript_parser::parse_eventdef()
+{
+	event_info* e = new event_info;
+
+	m_lx->must_get_next (tk_number);
+	e->number = token_string().to_long();
+	m_lx->must_get_next (tk_colon);
+	m_lx->must_get_next (tk_symbol);
+	e->name = m_lx->get_token()->text;
+	m_lx->must_get_next (tk_paren_start);
+	m_lx->must_get_next (tk_paren_end);
+	m_lx->must_get_next (tk_semicolon);
+	add_event (e);
+}
+
+// =============================================================================
+//
+void botscript_parser::parse_funcdef()
+{
+	command_info* comm = new command_info;
+
+	// Number
+	m_lx->must_get_next (tk_number);
+	comm->number = m_lx->get_token()->text.to_long();
+
+	m_lx->must_get_next (tk_colon);
+
+	// Name
+	m_lx->must_get_next (tk_symbol);
+	comm->name = m_lx->get_token()->text;
+
+	if (IsKeyword (comm->name))
+		error ("function name `%1` conflicts with keyword", comm->name);
+
+	m_lx->must_get_next (tk_colon);
+
+	// Return value
+	m_lx->must_get_any_of ({tk_int, tk_void, tk_bool, tk_str});
+	comm->returnvalue = GetTypeByName (m_lx->get_token()->text); // TODO
+	assert (comm->returnvalue != -1);
+
+	m_lx->must_get_next (tk_colon);
+
+	// Num args
+	m_lx->must_get_next (tk_number);
+	comm->numargs = m_lx->get_token()->text.to_long();
+
+	m_lx->must_get_next (tk_colon);
+
+	// Max args
+	m_lx->must_get_next (tk_number);
+	comm->maxargs = m_lx->get_token()->text.to_long();
+
+	// Argument types
+	int curarg = 0;
+
+	while (curarg < comm->maxargs)
+	{
+		command_argument arg;
+		m_lx->must_get_next (tk_colon);
+		m_lx->must_get_any_of ({tk_int, tk_bool, tk_str});
+		type_e type = GetTypeByName (m_lx->get_token()->text);
+		assert (type != -1 && type != TYPE_VOID);
+		arg.type = type;
+
+		m_lx->must_get_next (tk_paren_start);
+		m_lx->must_get_next (tk_symbol);
+		arg.name = m_lx->get_token()->text;
+
+		// If this is an optional parameter, we need the default value.
+		if (curarg >= comm->numargs)
+		{
+			m_lx->must_get_next (tk_assign);
+
+			switch (type)
+			{
+				case TYPE_INT:
+				case TYPE_BOOL:
+					m_lx->must_get_next (tk_number);
+					break;
+
+				case TYPE_STRING:
+					m_lx->must_get_next (tk_string);
+					break;
+
+				case TYPE_UNKNOWN:
+				case TYPE_VOID:
+					break;
+			}
+
+			arg.defvalue = m_lx->get_token()->text.to_long();
+		}
+
+		m_lx->must_get_next (tk_paren_end);
+		comm->args << arg;
+		curarg++;
+	}
+
+	m_lx->must_get_next (tk_semicolon);
+	add_command_definition (comm);
+}
+
 // ============================================================================
 // Parses a command call
 data_buffer* botscript_parser::ParseCommand (command_info* comm)

mercurial