/** * forspll - LLVM-based Forsp compiler * Copyright (C) 2024 Clyne Sullivan * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ #include "parser.hpp" #include #include std::string name; static bool isname(char ch) { return !isspace(ch) && ch != ')'; } static std::string_view extractName(std::string_view sv) { name.clear(); while (!sv.empty()) { const auto ch = sv.front(); if (isname(ch)) { name += ch; sv.remove_prefix(1); } else { break; } } return sv; } std::pair nextToken(std::string_view sv) { if (sv.empty()) return {sv, Token::none}; while (std::isspace(sv.front())) sv.remove_prefix(1); if (sv.empty()) return {sv, Token::none}; const auto ch = sv.front(); if (ch == ';') { return {{}, Token::none}; } else if (ch == '(') { return {sv.substr(1), Token::ThunkOpen}; } else if (ch == ')') { return {sv.substr(1), Token::ThunkClose}; } else if (ch == '\'') { return {extractName(sv.substr(1)), Token::Quote}; } else if (ch == '$') { return {extractName(sv.substr(1)), Token::PopVar}; } else if (ch == '^') { return {extractName(sv.substr(1)), Token::PushVar}; } else if (isdigit(ch) || (ch == '-' && sv.size() > 1 && isdigit(sv[1]))) { return {extractName(sv), Token::Number}; } else if (isname(ch)) { return {extractName(sv), Token::Var}; } return {sv, Token::none}; } void printToken(Token tok) { switch (tok) { case Token::ThunkOpen: std::cout << "ThunkOpen "; break; case Token::ThunkClose: std::cout << "ThunkClose "; break; case Token::Quote: std::cout << "Quote "; break; case Token::PopVar: std::cout << "PopVar "; break; case Token::PushVar: std::cout << "PushVar "; break; case Token::Var: std::cout << "Var "; break; case Token::Number: std::cout << "Number "; break; case Token::none: //std::cout << "none "; break; } }