From d2300fb11e0a976f3f86a3ca9d51db77893316d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20=C5=A0torc?= <storcond@fit.cvut.cz>
Date: Fri, 31 Mar 2023 16:05:22 +0200
Subject: [PATCH] cli: Add support for double in syntax.

Also create own syntax rule for each data type (String, Integer, Double).
This makes parsing simplier as we do not have to check if the node with one
type is present and the ANTLR runtime will do it for use.
---
 alib2cli/src/grammar/AltCliParser.g4          | 10 ++++++----
 alib2cli/src/grammar/Autocomplete.cpp         |  1 +
 alib2cli/src/parser/AltVisitor.Expression.cpp | 16 ++++++++++------
 alib2cli/src/parser/AltVisitor.Statement.cpp  | 16 ++++++++++------
 alib2cli/src/parser/AltVisitor.cpp            |  5 +++++
 alib2cli/src/parser/AltVisitor.h              | 14 ++++++++++++--
 6 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/alib2cli/src/grammar/AltCliParser.g4 b/alib2cli/src/grammar/AltCliParser.g4
index ffd8d26fa..915f1dbfa 100644
--- a/alib2cli/src/grammar/AltCliParser.g4
+++ b/alib2cli/src/grammar/AltCliParser.g4
@@ -42,8 +42,9 @@ out_redirect
 common
 	:	variable # VariableStatement
 	|	LESS_SIGN in_redirect # InRedirectStatement
-	|	string # ImmediateStatement
-	|	INTEGER # ImmediateStatement
+	|	string # StringImmediateStatement
+	|	INTEGER # IntegerImmediateStatement
+	|   DOUBLE # DoubleImmediateStatement
 	|	binding # ValueStatement
 	|	LEFT_BRACE ( param ) * RIGHT_BRACE # ContainerStatement
 	;
@@ -192,8 +193,9 @@ atom
 	|	algorithm bracketed_expression_list # FunctionCallExpression
 	|	variable # VariableExpression
 	|	LEFT_PAREN expression RIGHT_PAREN # AtomExpression
-	|	string # ImmediateExpression
-	|	INTEGER # ImmediateExpression
+	|	string # StringImmediateExpression
+	|	INTEGER # IntegerImmediateExpression
+	|	DOUBLE # DoubleImmediateExpression
 	;
 
 bracketed_expression_list
diff --git a/alib2cli/src/grammar/Autocomplete.cpp b/alib2cli/src/grammar/Autocomplete.cpp
index 6b0f97a3b..55655ca74 100644
--- a/alib2cli/src/grammar/Autocomplete.cpp
+++ b/alib2cli/src/grammar/Autocomplete.cpp
@@ -58,6 +58,7 @@ std::vector<cli::Autocomplete::Suggestion> cli::Autocomplete::getSuggestions(con
         AltCliLexer::NEWLINE,
         AltCliLexer::STRING,
         AltCliLexer::INTEGER,
+        AltCliLexer::DOUBLE,
         AltCliLexer::IDENTIFIER,
         AltCliLexer::EOF};
 
diff --git a/alib2cli/src/parser/AltVisitor.Expression.cpp b/alib2cli/src/parser/AltVisitor.Expression.cpp
index d9c630c2c..e2423f634 100644
--- a/alib2cli/src/parser/AltVisitor.Expression.cpp
+++ b/alib2cli/src/parser/AltVisitor.Expression.cpp
@@ -112,14 +112,18 @@ std::any AltVisitor::visitVariableExpression(AltCliParser::VariableExpressionCon
     return retPtr<Expression, VariableExpression>(std::move(name));
 }
 
-std::any AltVisitor::visitImmediateExpression(AltCliParser::ImmediateExpressionContext* ctx)
+std::any AltVisitor::visitStringImmediateExpression(AltCliParser::StringImmediateExpressionContext* ctx)
 {
-    if (ctx->string() != nullptr)
-        return retPtr<Expression, ImmediateExpression<std::string>>(cast<std::string>(visit(ctx->string())));
+    return retPtr<Expression, ImmediateExpression<std::string>>(cast<std::string>(visit(ctx->string())));
+}
 
-    if (ctx->INTEGER() != nullptr)
-        return retPtr<Expression, ImmediateExpression<int>>(visitInt(ctx->INTEGER()));
+std::any AltVisitor::visitIntegerImmediateExpression(AltCliParser::IntegerImmediateExpressionContext* ctx)
+{
+    return retPtr<Expression, ImmediateExpression<int>>(visitInt(ctx->INTEGER()));
+}
 
-    invalidParse("Invalid Immediate Expression");
+std::any AltVisitor::visitDoubleImmediateExpression(AltCliParser::DoubleImmediateExpressionContext* ctx)
+{
+    return retPtr<Expression, ImmediateExpression<double>>(visitDouble(ctx->DOUBLE()));
 }
 }
diff --git a/alib2cli/src/parser/AltVisitor.Statement.cpp b/alib2cli/src/parser/AltVisitor.Statement.cpp
index fc6b4b073..d6c3469f9 100644
--- a/alib2cli/src/parser/AltVisitor.Statement.cpp
+++ b/alib2cli/src/parser/AltVisitor.Statement.cpp
@@ -82,15 +82,19 @@ std::any AltVisitor::visitCommonStatement(AltCliParser::CommonStatementContext*
     return AltCliParserBaseVisitor::visitCommonStatement(ctx);
 }
 
-std::any AltVisitor::visitImmediateStatement(AltCliParser::ImmediateStatementContext* ctx)
+std::any AltVisitor::visitStringImmediateStatement(AltCliParser::StringImmediateStatementContext* ctx)
 {
-    if (ctx->string() != nullptr)
-        return retPtr<Statement, ImmediateStatement<std::string>>(cast<std::string>(visit(ctx->string())));
+    return retPtr<Statement, ImmediateStatement<std::string>>(cast<std::string>(visit(ctx->string())));
+}
 
-    if (ctx->INTEGER() != nullptr)
-        return retPtr<Statement, ImmediateStatement<int>>(visitInt(ctx->INTEGER()));
+std::any AltVisitor::visitIntegerImmediateStatement(AltCliParser::IntegerImmediateStatementContext* ctx)
+{
+    return retPtr<Statement, ImmediateStatement<int>>(visitInt(ctx->INTEGER()));
+}
 
-    invalidParse("Invalid ImmediateStatement");
+std::any AltVisitor::visitDoubleImmediateStatement(AltCliParser::DoubleImmediateStatementContext* ctx)
+{
+    return retPtr<Statement, ImmediateStatement<double>>(visitDouble(ctx->DOUBLE()));
 }
 
 std::any AltVisitor::visitImmediateParam(AltCliParser::ImmediateParamContext* ctx)
diff --git a/alib2cli/src/parser/AltVisitor.cpp b/alib2cli/src/parser/AltVisitor.cpp
index 06c3cc96f..14ef3adc4 100644
--- a/alib2cli/src/parser/AltVisitor.cpp
+++ b/alib2cli/src/parser/AltVisitor.cpp
@@ -47,6 +47,11 @@ int AltVisitor::visitInt(antlr4::tree::TerminalNode* node)
     return std::stoi(node->getText());
 }
 
+double AltVisitor::visitDouble(antlr4::tree::TerminalNode* node)
+{
+    return std::stod(node->getText());
+}
+
 std::any AltVisitor::visitString(AltCliParser::StringContext* ctx)
 {
     std::string text = ctx->getText();
diff --git a/alib2cli/src/parser/AltVisitor.h b/alib2cli/src/parser/AltVisitor.h
index 56abbf2e7..3f6a4746c 100644
--- a/alib2cli/src/parser/AltVisitor.h
+++ b/alib2cli/src/parser/AltVisitor.h
@@ -39,7 +39,11 @@ struct AltVisitor : public AltCliParserBaseVisitor {
 
     std::any visitExpressionOrBatch(AltCliParser::ExpressionOrBatchContext* ctx) override;
 
-    std::any visitImmediateStatement(AltCliParser::ImmediateStatementContext* ctx) override;
+    std::any visitStringImmediateStatement(AltCliParser::StringImmediateStatementContext* ctx) override;
+
+    std::any visitIntegerImmediateStatement(AltCliParser::IntegerImmediateStatementContext* ctx) override;
+
+    std::any visitDoubleImmediateStatement(AltCliParser::DoubleImmediateStatementContext* ctx) override;
 
     std::any visitCommonStatement(AltCliParser::CommonStatementContext* ctx) override;
 
@@ -81,7 +85,11 @@ struct AltVisitor : public AltCliParserBaseVisitor {
 
     std::any visitWhileCommand(AltCliParser::WhileCommandContext* ctx) override;
 
-    std::any visitImmediateExpression(AltCliParser::ImmediateExpressionContext* ctx) override;
+    std::any visitStringImmediateExpression(AltCliParser::StringImmediateExpressionContext* ctx) override;
+
+    std::any visitIntegerImmediateExpression(AltCliParser::IntegerImmediateExpressionContext* ctx) override;
+
+    std::any visitDoubleImmediateExpression(AltCliParser::DoubleImmediateExpressionContext* ctx) override;
 
     std::any visitPostfixExpression(AltCliParser::PostfixExpressionContext* ctx) override;
 
@@ -217,6 +225,8 @@ private:
 
     static int visitInt(antlr4::tree::TerminalNode* node);
 
+    static double visitDouble(antlr4::tree::TerminalNode* node);
+
     static std::string getRawText(antlr4::ParserRuleContext* ctx);
 
     template <typename T>
-- 
GitLab