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.
93 lines
2.0 KiB
C++
93 lines
2.0 KiB
C++
4 months ago
|
#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;
|
||
|
}
|
||
|
}
|
||
|
|