diff --git a/src/Lib/Script/Ast/IrType.cc b/src/Lib/Script/Ast/IrType.cc index 4860a1c52533a73843d6f40beb097fbde3d48281..e95b265ee47ac6b7c92fdcf7afc7a09ae09bc2f5 100644 --- a/src/Lib/Script/Ast/IrType.cc +++ b/src/Lib/Script/Ast/IrType.cc @@ -4,18 +4,6 @@ namespace Vivy::Script { -const ::Vivy::Script::IrVariable * -IrType::parent() const noexcept -{ - return dynamic_cast<const IrVariable *>(IrElement::parent()); -} - -::Vivy::Script::IrVariable * -IrType::parent() noexcept -{ - return dynamic_cast<IrVariable *>(IrElement::parent()); -} - void IrType::assertType(Type t) const { @@ -25,6 +13,10 @@ IrType::assertType(Type t) const } } +/* +** IrTAss +*/ + namespace Vivy::Script { IrType::Type @@ -58,6 +50,10 @@ IrTAss::parse(std::vector<Token> *) } } +/* +** IrTOption +*/ + namespace Vivy::Script { IrType::Type @@ -101,9 +97,28 @@ IrTPrimitive::IrTPrimitive(const PrimitiveType type) noexcept { } +void +IrTPrimitive::setSelfInnerTypeFromToken(const Token &name) + { + 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)) { + selfInnerType = IrType::PrimitiveType::Float; + } else if (name.isSimple(TOKEN_STRING)) { + selfInnerType = IrType::PrimitiveType::String; + } else if (name.isSimple(TOKEN_COLOR)) { + selfInnerType = IrType::PrimitiveType::Color; + } else { + throw std::logic_error("IrTPrimitive unexpected token " + name.toString()); + } + } + IrTPrimitive::IrTPrimitive(const Token &name) { - throw std::logic_error("IrTPrimitive " + name.toString()); + setSelfInnerTypeFromToken(name) } IrType::Type @@ -121,18 +136,70 @@ IrTPrimitive::innerType() const noexcept unsigned int IrTPrimitive::innerTypeCount() const noexcept { - return selfArraySize; + /* 0 is same as 1, it's not an array! */ + return selfArraySize <= 1 : 1 : selfArraySize; } std::string IrTPrimitive::toString() const noexcept { - return "IrTPrimitive"; + switch (selfInnerType) { + case IrType::PrimitiveType::Int: return std::string("INT"); + case IrType::PrimitiveType::Float: return std::string("FLOAT"); + case IrType::PrimitiveType::Bool: return std::string("BOOL"); + case IrType::PrimitiveType::Color: return std::string("COLOR"); + case IrType::PrimitiveType::String: return std::string("STRING"); + } } void -IrTPrimitive::parse(std::vector<Token> *) -{ - throw std::logic_error("Not implemented"); +IrTPrimitive::parse(std::vector<Token> *tokens) +{ + selfArraySize.clear(); + if (tokens->size() == 0) { + throw std::runtime_error("Expected at least one token to parse an IrTPrimitive"); + } else if (tokens->size() == 1) { + setSelfInnerTypeFromToken(getInnerTokenOpt(tokenListPop(tokens))) + } else { + const Token primToken = getInnerTokenOpt(tokenListPop(tokens)); + setSelfInnerTypeFromToken(primToken); + 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, ...]`"); + } + + bool parsedBracketOnce = false; + 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]`"); + } + parsedBracketOnce = true; + 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]`"); + } + sizeToken = getInnerTokenOpt(tokenListPop(sizeTokens)); + } else if (sizeToken.isSimple(TOKEN_BRACKET_RIGHT)) { + break; + } else { + throw std::runtime_error("Unexepcted token " + sizeToken.toString()); + } + + sizeToken.assertType(Token::Type::INTEGER); + arraySizes.push_back(sizeToken.asInteger()); + + /* The [ and , are ignored, they delimit each dimensions */ + } while (sizeToken.valueType() == Token::Type::INTEGER); + + /* Must end by a ] */ + sizeToken.assertTypeSimple(TOKEN_BRACKET_RIGHT); + selfArraySize = static_cast<unsigned int>(arraySizes.size()); + } } } diff --git a/src/Lib/Script/Ast/IrType.hh b/src/Lib/Script/Ast/IrType.hh index 71b2b5b36842e3c43dacd2d54780d70294880a5e..c2d537a0e051ae1f5cbabe1e22a96842832d9500 100644 --- a/src/Lib/Script/Ast/IrType.hh +++ b/src/Lib/Script/Ast/IrType.hh @@ -16,8 +16,6 @@ public: public: virtual Type type() const noexcept = 0; void assertType(Type) const; - const IrVariable *parent() const noexcept override; - IrVariable *parent() noexcept override; }; class IrTAss final : public IrType { @@ -53,11 +51,14 @@ class IrTPrimitive final : public IrType { PrimitiveType selfInnerType; unsigned int selfArraySize; + std::vector<unsigned int> arraySizes = { 1 }; IrTPrimitive(const Token &); IrTPrimitive(const PrimitiveType) noexcept; IrTPrimitive(const PrimitiveType, unsigned int) noexcept; + void IrTPrimitive::setSelfInnerTypeFromToken(const Token &name); + public: Type type() const noexcept override; PrimitiveType innerType() const noexcept; diff --git a/src/Lib/Script/FrontEnd/Tokens.hh b/src/Lib/Script/FrontEnd/Tokens.hh index bc1d6ebbd126c8e674bff06f152fef458198e849..c06428f0dd7917956609b407130064f0d11dc417 100644 --- a/src/Lib/Script/FrontEnd/Tokens.hh +++ b/src/Lib/Script/FrontEnd/Tokens.hh @@ -41,6 +41,7 @@ namespace Vivy::Script #define TOKEN_BOOL STRV_STATIC("BOOL") #define TOKEN_COLOR STRV_STATIC("COLOR") #define TOKEN_VOID STRV_STATIC("VOID") +#define TOKEN_STRING STRV_STATIC("STR") #define TOKEN_IN STRV_STATIC("in") #define TOKEN_FOR STRV_STATIC("for") #define TOKEN_AS STRV_STATIC("as") @@ -60,7 +61,7 @@ namespace Vivy::Script #define TOKEN_LIST_BASE_TYPE \ { \ - TOKEN_BOOL, TOKEN_REAL, TOKEN_INT, TOKEN_COLOR, TOKEN_VOID \ + TOKEN_BOOL, TOKEN_REAL, TOKEN_INT, TOKEN_COLOR, TOKEN_VOID, TOKEN_STRING \ } #define TOKEN_RULE_INT "(+|-)?[0-9]+" @@ -128,6 +129,7 @@ namespace Vivy::Script TOKEN_LE, TOKEN_GT, TOKEN_GE, + TOKEN_STRING, TOKEN_ASSIGN, TOKEN_FALSE, TOKEN_TRUE,