From 89a4fc4335fe433af6758db84990a08ae5a8e3b2 Mon Sep 17 00:00:00 2001
From: Nora Abi Akar <nora.abiakar@gmail.com>
Date: Thu, 28 Nov 2019 13:17:25 +0100
Subject: [PATCH] Modcc: Add support for `COMMENT` and `ENDCOMMENT` (#906)

Also change the way we handle unitson/unitsoff.
UNITSON, UNITSOFF, COMMENT, ENDCOMMENT are now all handled in Lexer::parse

Fixes #14
Fixes #885
---
 modcc/lexer.cpp  | 23 ++++++++++++++++-------
 modcc/parser.cpp | 19 -------------------
 modcc/parser.hpp |  1 -
 3 files changed, 16 insertions(+), 27 deletions(-)

diff --git a/modcc/lexer.cpp b/modcc/lexer.cpp
index dc5851ec..086a5a80 100644
--- a/modcc/lexer.cpp
+++ b/modcc/lexer.cpp
@@ -20,7 +20,7 @@ inline bool is_alphanumeric(char c) {
     return (is_numeric(c) || is_alpha(c) );
 }
 inline bool is_whitespace(char c) {
-    return (c==' ' || c=='\t' || c=='\v' || c=='\f');
+    return (c==' ' || c=='\t' || c=='\v' || c=='\f' || c=='\n' || c=='\r');
 }
 inline bool is_eof(char c) {
     return (c==0);
@@ -97,14 +97,23 @@ Token Lexer::parse() {
             // identifier or keyword
             case 'a' ... 'z':
             case 'A' ... 'Z':
-            case '_':
+            case '_': {
                 // get std::string of the identifier
-                t.spelling = identifier();
-                t.type
-                    = status_==lexerStatus::error
-                    ? tok::reserved
-                    : get_identifier_type(t.spelling);
+                auto id = identifier();
+                if (id == "UNITSON" || id == "UNITSOFF") continue;
+                if (id == "COMMENT") {
+                    while (!is_eof(*current_)) {
+                        while (is_whitespace(*current_) || !is_alpha(*current_)) current_++;
+                        if (identifier() == "ENDCOMMENT") break;
+                    }
+                    continue;
+                }
+                t.spelling = id;
+                t.type = status_ == lexerStatus::error
+                          ? tok::reserved
+                          : get_identifier_type(t.spelling);
                 return t;
+            }
             case '(':
                 t.type = tok::lparen;
                 t.spelling += character();
diff --git a/modcc/parser.cpp b/modcc/parser.cpp
index 3cacb0f1..efeb1cac 100644
--- a/modcc/parser.cpp
+++ b/modcc/parser.cpp
@@ -35,15 +35,6 @@ bool Parser::expect(tok tok, std::string const& str) {
     return false;
 }
 
-void Parser::parse_unit() {
-    if(token_.type == tok::lparen) {
-        while (token_.type != tok::rparen) {
-            get_token();
-        }
-        get_token(); // consume ')'
-    }
-}
-
 void Parser::error(std::string msg) {
     std::string location_info = pprintf(
             "%:% ", module_ ? module_->source_name() : "", token_.location);
@@ -138,12 +129,6 @@ bool Parser::parse() {
                 module_->add_callable(std::move(f));
                 }
                 break;
-            case tok::unitson :
-                get_token();
-                break;
-            case tok::unitsoff :
-                get_token();
-                break;
             default :
                 error(pprintf("expected block type, found '%'", token_.spelling));
                 break;
@@ -835,8 +820,6 @@ expression_ptr Parser::parse_prototype(std::string name=std::string()) {
 
         get_token(); // consume the identifier
 
-        parse_unit(); // consume the unit if provided
-
         // look for a comma
         if(!(token_.type == tok::comma || token_.type==tok::rparen)) {
             error(  "expected a comma or closing parenthesis, found '"
@@ -967,8 +950,6 @@ symbol_ptr Parser::parse_function() {
     auto p = parse_prototype();
     if(p==nullptr) return nullptr;
 
-    parse_unit();
-
     // check for opening left brace {
     if(!expect(tok::lbrace)) return nullptr;
 
diff --git a/modcc/parser.hpp b/modcc/parser.hpp
index 09130e9a..49512f7e 100644
--- a/modcc/parser.hpp
+++ b/modcc/parser.hpp
@@ -81,7 +81,6 @@ private:
     Parser();
     Parser(Parser const &);
 
-    void parse_unit();
     bool expect(tok, const char *str="");
     bool expect(tok, std::string const& str);
 };
-- 
GitLab