You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
2.8 KiB
C++

/**
* forspll - LLVM-based Forsp compiler
* Copyright (C) 2024 Clyne Sullivan <clyne@bitgloo.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "parser.hpp"
#include <cctype>
#include <iostream>
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<std::string_view, Token> 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;
}
}