#include "hecl/hecl.hpp" #include "hecl/Frontend.hpp" /* Syntatical token parsing system */ namespace hecl { namespace Frontend { void Parser::skipWhitespace(std::string_view::const_iterator& it) { while (it != m_source.cend()) { while (it != m_source.cend() && isspace(*it)) ++it; /* Skip comment line */ if (it != m_source.cend() && *it == '#') { while (it != m_source.cend() && *it != '\n') ++it; if (it != m_source.cend() && *it == '\n') ++it; continue; } break; } } void Parser::reset(std::string_view source) { m_source = source; m_sourceIt = m_source.cbegin(); m_parenStack.clear(); m_reset = true; } Parser::Token Parser::consumeToken() { if (m_source.empty()) return Parser::Token(TokenType::None, SourceLocation()); /* If parser has just been reset, emit begin token */ if (m_reset) { m_reset = false; return Parser::Token(TokenType::SourceBegin, getLocation()); } /* Skip whitespace */ skipWhitespace(m_sourceIt); /* Check for source end */ if (m_sourceIt == m_source.cend()) return Parser::Token(TokenType::SourceEnd, getLocation()); /* Check for numeric literal */ { char* strEnd; float val = strtof(&*m_sourceIt, &strEnd); if (&*m_sourceIt != strEnd) { Parser::Token tok(TokenType::NumLiteral, getLocation()); tok.m_tokenFloat = val; m_sourceIt += (strEnd - &*m_sourceIt); return tok; } } /* Check for swizzle op */ if (*m_sourceIt == '.') { int count = 0; std::string_view::const_iterator tmp = m_sourceIt + 1; if (tmp != m_source.cend()) { for (int i=0 ; i<4 ; ++i) { std::string_view::const_iterator tmp2 = tmp + i; if (tmp2 == m_source.cend()) break; char ch = tolower(*tmp2); if (ch >= 'w' && ch <= 'z') ++count; else if (ch == 'r' || ch == 'g' || ch == 'b' || ch == 'a') ++count; else break; } } if (count) { Parser::Token tok(TokenType::VectorSwizzle, getLocation()); for (int i=0 ; i