diff --git a/src/Lib/Script/Ast/IrExpression.cc b/src/Lib/Script/Ast/IrExpression.cc index 9cc1c7a58da4078d1c2086c7b741d181c7a13210..b3086532464ab9585f535c62e164405bfa9fc9f2 100644 --- a/src/Lib/Script/Ast/IrExpression.cc +++ b/src/Lib/Script/Ast/IrExpression.cc @@ -18,14 +18,15 @@ IrExpression::IrExpression(IrElement *p, Type type) noexcept { } - void IrExpression::setInnerType(IrType *type) - { - if (selfInnerType != nullptr) { - throw std::logic_error("IrExpression: try to set the inner type multiple times"); - } - selfInnerType = type; - selfInnerType->setParent(this); +void +IrExpression::setInnerType(IrType *type) +{ + if (selfInnerType != nullptr) { + throw std::logic_error("IrExpression: try to set the inner type multiple times"); } + selfInnerType = type; + selfInnerType->setParent(this); +} std::string IrExpression::toString() const noexcept @@ -48,10 +49,12 @@ IrExpression::parse(std::vector<Token> *tokens) #include "Parser/IrExpression.hh" } -void IrExpression::assertType(Type t) const +void +IrExpression::assertType(Type t) const { if (type() != t) { - throw std::runtime_error("Expected type " + std::to_string(static_cast<int>(t)) + " but was type " + std::to_string(static_cast<int>(type()))); + throw std::runtime_error("Expected type " + std::to_string(static_cast<int>(t)) + + " but was type " + std::to_string(static_cast<int>(type()))); } } @@ -105,7 +108,8 @@ IrEConstExpr::IrEConstExpr(const Token &singleElement) } else if (singleElement.isSimple(TOKEN_TRUE)) { setInnerType(IrElement::create<IrTPrimitive>(this, IrType::PrimitiveType::Bool)); } else { - throw std::logic_error("IrEConstExpr unexpected simple token: " + singleElement.toString() + ", expected `true` or `false`"); + throw std::logic_error("IrEConstExpr unexpected simple token: " + + singleElement.toString() + ", expected `true` or `false`"); } return; } @@ -117,36 +121,42 @@ IrEConstExpr::IrEConstExpr(const Token &singleElement) } } -IrTPrimitive *IrEConstExpr::innerType() const noexcept +IrTPrimitive * +IrEConstExpr::innerType() const noexcept { - return dynamic_cast<IrTPrimitive*>(IrExpression::innerType()); + return dynamic_cast<IrTPrimitive *>(IrExpression::innerType()); } -bool IrEConstExpr::getInnerBoolean() const +bool +IrEConstExpr::getInnerBoolean() const { innerType()->assertInnerType(IrType::PrimitiveType::Bool); return inner.boolean; } -int IrEConstExpr::getInnerInteger() const +int +IrEConstExpr::getInnerInteger() const { innerType()->assertInnerType(IrType::PrimitiveType::Int); return inner.integer; } -float IrEConstExpr::getInnerFloating() const +float +IrEConstExpr::getInnerFloating() const { innerType()->assertInnerType(IrType::PrimitiveType::Float); return inner.floating; } -StrV IrEConstExpr::getInnerStringLit() const +StrV +IrEConstExpr::getInnerStringLit() const { innerType()->assertInnerType(IrType::PrimitiveType::String); return inner.string; } -StrV IrEConstExpr::getInnerColorLit() const +StrV +IrEConstExpr::getInnerColorLit() const { innerType()->assertInnerType(IrType::PrimitiveType::Color); return inner.string; @@ -156,11 +166,12 @@ std::string IrEConstExpr::toString() const noexcept { switch (innerType()->innerType()) { - case IrType::PrimitiveType::Color: return inner.string.toStdString(); - case IrType::PrimitiveType::String: return inner.string.toStdString(); - case IrType::PrimitiveType::Int: return std::to_string(inner.integer); - case IrType::PrimitiveType::Float: return std::to_string(inner.floating); - case IrType::PrimitiveType::Bool: return inner.boolean ? std::string("true") : std::string("false"); + case IrType::PrimitiveType::Color: return inner.string.toStdString(); + case IrType::PrimitiveType::String: return inner.string.toStdString(); + case IrType::PrimitiveType::Int: return std::to_string(inner.integer); + case IrType::PrimitiveType::Float: return std::to_string(inner.floating); + case IrType::PrimitiveType::Bool: + return inner.boolean ? std::string("true") : std::string("false"); } } } @@ -177,12 +188,14 @@ IrECall::toString() const noexcept return "IrECall"; } -const IrFunction *IrECall::call() const noexcept +const IrFunction * +IrECall::call() const noexcept { return callPtr; } -const std::vector<IrExpression *>& IrECall::args() const noexcept +const std::vector<IrExpression *> & +IrECall::args() const noexcept { return inArgs; } diff --git a/src/Lib/Script/Ast/IrExpression.hh b/src/Lib/Script/Ast/IrExpression.hh index b0777d284dd64ebaeb6db6b65f65119d5a082071..5df659d59769865bbeb1b9bbb9c0d2e41d0d11da 100644 --- a/src/Lib/Script/Ast/IrExpression.hh +++ b/src/Lib/Script/Ast/IrExpression.hh @@ -65,7 +65,7 @@ public: std::string toString() const noexcept override; const IrFunction *call() const noexcept; - const std::vector<IrExpression *>& args() const noexcept; + const std::vector<IrExpression *> &args() const noexcept; }; class IrECompOp : public IrExpression { @@ -79,7 +79,7 @@ private: IrExpression *left; IrExpression *right; - IrECompOp(OpType, IrExpression*&&left, IrExpression*&&right) noexcept; + IrECompOp(OpType, IrExpression *&&left, IrExpression *&&right) noexcept; public: std::string toString() const noexcept override; @@ -98,7 +98,7 @@ private: IrExpression *left; IrExpression *right; - IrEArithmeticOp(OpType, IrExpression*&&left, IrExpression*&&right) noexcept; + IrEArithmeticOp(OpType, IrExpression *&&left, IrExpression *&&right) noexcept; public: std::string toString() const noexcept override; @@ -117,7 +117,7 @@ private: IrExpression *left; IrExpression *right; - IrELogicOp(OpType, IrExpression*&&left, IrExpression*&&right) noexcept; + IrELogicOp(OpType, IrExpression *&&left, IrExpression *&&right) noexcept; public: std::string toString() const noexcept override; @@ -132,11 +132,10 @@ class IrEVariableRef : public IrExpression { IrEVariableRef(IrVariable *) noexcept; - IrEVariableRef(IrVariable *, std::vector<IrExpression*>&&); + IrEVariableRef(IrVariable *, std::vector<IrExpression *> &&); - template<typename... Args> - IrEVariableRef(IrVariable *var, Args&&...indicies) - : IrEVariableRef(var, std::vector<IrExpression*>{indicies...}) + template <typename... Args> IrEVariableRef(IrVariable *var, Args &&...indicies) + : IrEVariableRef(var, std::vector<IrExpression *>{ indicies... }) { } diff --git a/src/Lib/Script/Ast/IrType.cc b/src/Lib/Script/Ast/IrType.cc index 972e4a8b5f06d8efcb178621c4bc9745b5eef2e6..7d3d3f16ba3c3ad312fd87399a0f6f35e479eecb 100644 --- a/src/Lib/Script/Ast/IrType.cc +++ b/src/Lib/Script/Ast/IrType.cc @@ -1,7 +1,7 @@ #include "IrType.hh" #include "IrElement.hh" #include "IrVariable.hh" -#include "Lib/Script/FrontEnd/Lexer.cc" +#include "Lib/Script/FrontEnd/Lexer.hh" namespace Vivy::Script { @@ -9,11 +9,9 @@ void IrType::assertType(Type t) const { if (type() != t) { - throw std::runtime_error( - "Type differs from asked type, this is " + - std::to_string(static_cast<int>(type())) + - " and asked " + std::to_string(static_cast<int>(t)) - ); + throw std::runtime_error("Type differs from asked type, this is " + + std::to_string(static_cast<int>(type())) + " and asked " + + std::to_string(static_cast<int>(t))); } } @@ -26,34 +24,31 @@ IrType::~IrType() noexcept {} namespace Vivy::Script { -IrTAss::IrTAss(const Token &name) -{ - setSelfInnerTypeFromToken(name); -} +IrTAss::IrTAss(const Token &name) { setSelfInnerTypeFromToken(name); } IrTAss::IrTAss(const AssType type, unsigned int size) noexcept - : selfInnerType(type) + : selfType(type) , selfArraySize(size) { } IrTAss::IrTAss(const AssType type) noexcept - : AssType(type, 1) + : IrTAss(type, 1) { } void IrTAss::setSelfInnerTypeFromToken(const Token &name) - { +{ name.assertType(Token::Type::SIMPLE); if (name.isSimple(TOKEN_LINE)) { - selfInnerType = IrType::AssType::Line; + selfType = IrType::AssType::Line; } else if (name.isSimple(TOKEN_SYLLABE)) { - selfInnerType = IrType::AssType::Syllabe; + selfType = IrType::AssType::Syllabe; } else { throw std::logic_error("IrTPrimitive unexpected token " + name.toString()); } - } +} IrType::Type IrTAss::type() const noexcept @@ -71,11 +66,9 @@ unsigned int IrTAss::innerTypeCount() const noexcept { /* 0 is same as 1, it's not an array! */ - const unsigned int ret = std::reduce( - std::execution::seq, - std::begin(arraySizes), std::end(arraySizes), 1, - [](unsigned int a, unsigned int b) noexcept -> unsigned int { return a * b; } - ); + const unsigned int ret = + std::reduce(std::begin(arraySizes), std::end(arraySizes), 1u, + [](unsigned int a, unsigned int b) noexcept -> unsigned int { return a * b; }); return ret <= 1 ? 1 : ret; } @@ -85,25 +78,30 @@ IrTAss::toString() const noexcept return "IrTAss"; } -bool IrTAss::isArray() const +bool +IrTAss::isArray() const { return selfArraySize >= 2; } -unsigned int IrTAss::getArrayDimensions() const +unsigned int +IrTAss::getArrayDimensions() const { - isArray() ? selfArraySize : 0; + return isArray() ? selfArraySize : 0; } -unsigned int IrTAss::getArrayDimensionAt(unsigned int level) const +unsigned int +IrTAss::getArrayDimensionAt(unsigned int level) const { return level >= selfArraySize ? 0 : arraySizes.at(level); } -void IrTAss::assertInnerType(AssType type) const +void +IrTAss::assertInnerType(AssType t) const { if (innerType() != t) { - throw std::runtime_error("Expected inner type " + std::to_string(static_cast<int>(t)) + " but was type " + std::to_string(static_cast<int>(innerType()))); + throw std::runtime_error("Expected inner type " + std::to_string(static_cast<int>(t)) + + " but was type " + std::to_string(static_cast<int>(innerType()))); } } } @@ -157,13 +155,13 @@ IrTPrimitive::IrTPrimitive(const PrimitiveType type) noexcept void IrTPrimitive::setSelfInnerTypeFromToken(const Token &name) - { - name.assertType(Token::Type::SIMPLE); +{ + name.assertType(Token::Type::SIMPLE); if (name.isSimple(TOKEN_BOOL)) { selfInnerType = IrType::PrimitiveType::Bool; } else if (name.isSimple(TOKEN_INT)) { selfInnerType = IrType::PrimitiveType::Int; - } else if (name.isSimple(TOKEN_FLOAT)) { + } else if (name.isSimple(TOKEN_REAL)) { selfInnerType = IrType::PrimitiveType::Float; } else if (name.isSimple(TOKEN_STRING)) { selfInnerType = IrType::PrimitiveType::String; @@ -172,18 +170,16 @@ IrTPrimitive::setSelfInnerTypeFromToken(const Token &name) } else { throw std::logic_error("IrTPrimitive unexpected token " + name.toString()); } - } - -IrTPrimitive::IrTPrimitive(const Token &name) -{ - setSelfInnerTypeFromToken(name); } +IrTPrimitive::IrTPrimitive(const Token &name) { setSelfInnerTypeFromToken(name); } + void IrTPrimitive::assertInnerType(PrimitiveType t) const { if (innerType() != t) { - throw std::runtime_error("Expected inner type " + std::to_string(static_cast<int>(t)) + " but was type " + std::to_string(static_cast<int>(innerType()))); + throw std::runtime_error("Expected inner type " + std::to_string(static_cast<int>(t)) + + " but was type " + std::to_string(static_cast<int>(innerType()))); } } @@ -199,30 +195,31 @@ IrTPrimitive::innerType() const noexcept return selfInnerType; } -bool IrTPrimitive::isArray() const +bool +IrTPrimitive::isArray() const { return selfArraySize >= 2; } -unsigned int IrTPrimitive::getArrayDimensions() const +unsigned int +IrTPrimitive::getArrayDimensions() const { - isArray() ? selfArraySize : 0; + return isArray() ? selfArraySize : 0; } -unsigned int IrTPrimitive::getArrayDimensionAt(unsigned int level) const +unsigned int +IrTPrimitive::getArrayDimensionAt(unsigned int level) const { return level >= selfArraySize ? 0 : arraySizes.at(level); } unsigned int -IrTAss::innerTypeCount() const noexcept +IrTPrimitive::innerTypeCount() const noexcept { /* 0 is same as 1, it's not an array! */ - const unsigned int ret = std::reduce( - std::execution::seq, - std::begin(arraySizes), std::end(arraySizes), 1, - [](unsigned int a, unsigned int b) noexcept -> unsigned int { return a * b; } - ); + const unsigned int ret = + std::reduce(std::begin(arraySizes), std::end(arraySizes), 1u, + [](unsigned int a, unsigned int b) noexcept -> unsigned int { return a * b; }); return ret <= 1 ? 1 : ret; } @@ -241,7 +238,7 @@ IrTPrimitive::toString() const noexcept void IrTPrimitive::parse(std::vector<Token> *tokens) { - selfArraySize.clear(); + arraySizes.clear(); if (tokens->size() == 0) { throw std::runtime_error("Expected at least one token to parse an IrTPrimitive"); } else if (tokens->size() == 1) { @@ -252,25 +249,35 @@ IrTPrimitive::parse(std::vector<Token> *tokens) std::vector<Token> sizeTokens = tokenListPopToNextSimpleToken(tokens, TOKEN_BRACKET_RIGHT); if (tokens->size()) { - throw std::runtime_error(getInnerTokenOpt(tokenListPeek(tokens)).location().toString() ": Remaining tokens for the array dimensions of the type, this is invalid. To declare an array, use `TYPE_NAME[dim1, dim2, ...]`"); - } else if (sizeTokens->size() <= 2) { - throw std::runtime_error(getInnerTokenOpt(tokenListPeek(sizeTokens)).location().toString() ": Invalid array dimensions for the type. To declare an array, use `TYPE_NAME[dim1, dim2, ...]`"); + throw std::runtime_error( + getInnerTokenOpt(tokenListPeek(tokens)).location().toString() + + ": Remaining tokens for the array dimensions of the type, this is invalid. " + "To declare an array, use `TYPE_NAME[dim1, dim2, ...]`"); + } else if (sizeTokens.size() <= 2) { + throw std::runtime_error( + getInnerTokenOpt(tokenListPeek(&sizeTokens)).location().toString() + + ": Invalid array dimensions for the type. " + "To declare an array, use `TYPE_NAME[dim1, dim2, ...]`"); } bool parsedBracketOnce = false; - Token sizeToken = getInnerTokenOpt(tokenListPop(sizeTokens)); + Token sizeToken = getInnerTokenOpt(tokenListPop(&sizeTokens)); do { if (sizeToken.isSimple(TOKEN_BRACKET_LEFT)) { if (parsedBracketOnce) { - throw std::runtime_error("Unexepcted token " + sizeToken.toString() + ", the [ must begein the size specifications, line `INT[1, 2, 3]`"); + throw std::runtime_error( + "Unexepcted token " + sizeToken.toString() + + ", the [ must begein the size specifications, line `INT[1, 2, 3]`"); } parsedBracketOnce = true; - sizeToken = getInnerTokenOpt(tokenListPop(sizeTokens)); + sizeToken = getInnerTokenOpt(tokenListPop(&sizeTokens)); } else if (sizeToken.isSimple(TOKEN_COMMA)) { if (!parsedBracketOnce) { - throw std::runtime_error("Unexepcted token " + sizeToken.toString() + ", the [ must begein the size specifications, line `INT[1, 2, 3]`"); + throw std::runtime_error( + "Unexepcted token " + sizeToken.toString() + + ", the [ must begein the size specifications, line `INT[1, 2, 3]`"); } - sizeToken = getInnerTokenOpt(tokenListPop(sizeTokens)); + sizeToken = getInnerTokenOpt(tokenListPop(&sizeTokens)); } else if (sizeToken.isSimple(TOKEN_BRACKET_RIGHT)) { break; } else { @@ -278,7 +285,12 @@ IrTPrimitive::parse(std::vector<Token> *tokens) } sizeToken.assertType(Token::Type::INTEGER); - arraySizes.push_back(sizeToken.asInteger()); + int size = sizeToken.asInteger(); + if (size <= 0) { + throw std::runtime_error(sizeToken.location().toString() + + "Unexepcted négative or null size in array dimensions"); + } + arraySizes.push_back(static_cast<unsigned int>(size)); /* The [ and , are ignored, they delimit each dimensions */ } while (sizeToken.valueType() == Token::Type::INTEGER); diff --git a/src/Lib/Script/Ast/IrType.hh b/src/Lib/Script/Ast/IrType.hh index 7b09d2b741a73383215e30d18671c859ed3a0c4e..78aa50cd8b4e8fd803e05d11d7ad32353923004e 100644 --- a/src/Lib/Script/Ast/IrType.hh +++ b/src/Lib/Script/Ast/IrType.hh @@ -23,7 +23,7 @@ class IrTAss final : public IrType { VIVY_IR_ELEMENT(IrTAss) AssType selfType; - unsigned int selfArraySize = 1; + unsigned int selfArraySize = 1; std::vector<unsigned int> arraySizes = { 1 }; IrTAss(const Token &); @@ -64,7 +64,7 @@ class IrTPrimitive final : public IrType { VIVY_IR_ELEMENT(IrTPrimitive) PrimitiveType selfInnerType; - unsigned int selfArraySize = 1; + unsigned int selfArraySize = 1; std::vector<unsigned int> arraySizes = { 1 }; IrTPrimitive(const Token &); diff --git a/src/Lib/Script/FrontEnd/Tokens.hh b/src/Lib/Script/FrontEnd/Tokens.hh index c06428f0dd7917956609b407130064f0d11dc417..6868074d04dca2531d5d75df42d40a6373250652 100644 --- a/src/Lib/Script/FrontEnd/Tokens.hh +++ b/src/Lib/Script/FrontEnd/Tokens.hh @@ -42,6 +42,8 @@ namespace Vivy::Script #define TOKEN_COLOR STRV_STATIC("COLOR") #define TOKEN_VOID STRV_STATIC("VOID") #define TOKEN_STRING STRV_STATIC("STR") +#define TOKEN_LINE STRV_STATIC("LINE") +#define TOKEN_SYLLABE STRV_STATIC("SYLLABE") #define TOKEN_IN STRV_STATIC("in") #define TOKEN_FOR STRV_STATIC("for") #define TOKEN_AS STRV_STATIC("as") @@ -59,11 +61,16 @@ namespace Vivy::Script #define TOKEN_FUNCTION STRV_STATIC("function") #define TOKEN_JOB STRV_STATIC("job") -#define TOKEN_LIST_BASE_TYPE \ - { \ +#define TOKEN_LIST_BASE_TYPE \ + { \ TOKEN_BOOL, TOKEN_REAL, TOKEN_INT, TOKEN_COLOR, TOKEN_VOID, TOKEN_STRING \ } +#define TOKEN_LIST_ASS_TYPE \ + { \ + TOKEN_LINE, TOKEN_SYLLABE, \ + } + #define TOKEN_RULE_INT "(+|-)?[0-9]+" #define TOKEN_RULE_ID "[a-zA-Z\u0391-\u03C9\u220F_\u221A_][a-zA-Z\u0391-\u03C9_0-9\\-\\+]*" #define TOKEN_RULE_REAL TOKEN_RULE_INT ".(" TOKEN_RULE_INT "((e|E)(+|-)" TOKEN_RULE_INT ")?)?" @@ -103,6 +110,8 @@ namespace Vivy::Script TOKEN_BRACKET_RIGHT, TOKEN_CURLY_BRACKET_LEFT, TOKEN_CURLY_BRACKET_RIGHT, + TOKEN_LINE, + TOKEN_SYLLABE, TOKEN_SEMICOL, TOKEN_COL, TOKEN_PIPE,