Parse void function call.

This CL updates the WGSL parser to handle a void function call.

Fixes: tint:45
Change-Id: If5b2a4b9e62f0b10e0f2e2e10c0ca2586c5268e8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/25322
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 63e426b..c3e7318 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -1422,6 +1422,7 @@
 //   | if_stmt
 //   | switch_stmt
 //   | loop_stmt
+//   | func_call_stmt SEMICOLON
 //   | variable_stmt SEMICOLON
 //   | break_stmt SEMICOLON
 //   | continue_stmt SEMICOLON
@@ -1464,6 +1465,18 @@
   if (loop != nullptr)
     return loop;
 
+  auto func = func_call_stmt();
+  if (has_error())
+    return nullptr;
+  if (func != nullptr) {
+    t = next();
+    if (!t.IsSemicolon()) {
+      set_error(t, "missing ;");
+      return nullptr;
+    }
+    return func;
+  }
+
   auto var = variable_stmt();
   if (has_error())
     return nullptr;
@@ -1908,6 +1921,41 @@
                                               std::move(continuing));
 }
 
+// func_call_stmt
+//    : IDENT PAREN_LEFT argument_expression_list* PAREN_RIGHT
+std::unique_ptr<ast::CallStatement> ParserImpl::func_call_stmt() {
+  auto t = peek();
+  auto t2 = peek(1);
+  if (!t.IsIdentifier() || !t2.IsParenLeft())
+    return nullptr;
+
+  auto source = t.source();
+
+  next();  // Consume the peek
+  next();  // Consume the 2nd peek
+
+  auto name = t.to_str();
+
+  t = peek();
+  ast::ExpressionList params;
+  if (!t.IsParenRight() && !t.IsEof()) {
+    params = argument_expression_list();
+    if (has_error())
+      return nullptr;
+  }
+
+  t = next();
+  if (!t.IsParenRight()) {
+    set_error(t, "missing ) for call statement");
+    return nullptr;
+  }
+
+  return std::make_unique<ast::CallStatement>(
+      std::make_unique<ast::CallExpression>(
+          source, std::make_unique<ast::IdentifierExpression>(name),
+          std::move(params)));
+}
+
 // break_stmt
 //   : BREAK
 std::unique_ptr<ast::BreakStatement> ParserImpl::break_stmt() {