Basic list support

This commit is contained in:
2025-10-29 17:59:26 +00:00
parent 7e071a1b01
commit 26c1b7dd0f
5 changed files with 152 additions and 80 deletions

View File

@@ -15,7 +15,7 @@
class Lexer {
private:
std::vector<char> delimiters = {
'(', ')', '{', '}', '.', '\n', ' '
'(', ')', '{', '}', '[', ']', '.', '\n', ' ', ','
};
std::string file;
size_t incrementor = -1;

View File

@@ -13,6 +13,9 @@ ASTValue::ASTValue(std::string in) : type(ValueType::String), value(in) {}
ASTValue::ASTValue(bool in) : type(ValueType::Bool), value(in) {}
ASTValue::ASTValue(long long in) : type(ValueType::Int), value(in) {}
ASTValue::ASTValue(double in) : type(ValueType::Float), value(in) {}
ASTValue::ASTValue(ASTList in) : type(ValueType::List), value(std::move(in)) {}
ASTList::ASTList(std::vector<ASTNode> in) : elements(std::move(in)) {}
ValueType ASTValue::getValueType(std::string in) {
if (in.size() < 1) {
@@ -55,7 +58,7 @@ ASTFunctionCall::ASTFunctionCall(std::string func, std::vector<ASTNode> args) :
ASTIdentifier::ASTIdentifier(std::string in) : name(std::move(in)) {}
std::optional<std::string> ASTValue::getString() {
std::optional<std::string> ASTValue::getString() const {
if (type == ValueType::String && std::holds_alternative<std::string>(value)) {
return std::get<std::string>(value);
} else {
@@ -63,7 +66,7 @@ std::optional<std::string> ASTValue::getString() {
}
}
std::optional<int> ASTValue::getInt() {
std::optional<int> ASTValue::getInt() const {
if (type == ValueType::Int && std::holds_alternative<long long>(value)) {
return std::get<long long>(value);
} else {
@@ -71,7 +74,7 @@ std::optional<int> ASTValue::getInt() {
}
}
std::optional<double> ASTValue::getFloat() {
std::optional<double> ASTValue::getFloat() const {
if (type == ValueType::Float && std::holds_alternative<double>(value)) {
return std::get<double>(value);
} else {
@@ -79,7 +82,7 @@ std::optional<double> ASTValue::getFloat() {
}
}
std::optional<bool> ASTValue::getBool() {
std::optional<bool> ASTValue::getBool() const {
if (type == ValueType::Bool && std::holds_alternative<bool>(value)) {
return std::get<bool>(value);
} else {
@@ -87,6 +90,18 @@ std::optional<bool> ASTValue::getBool() {
}
}
std::optional<ASTList> ASTValue::getList() const {
if (type == ValueType::List && std::holds_alternative<ASTList>(value)) {
return std::get<ASTList>(value);
} else {
return {};
}
}
std::vector<ASTNode> ASTList::getElements() const {
return elements;
}
std::optional<std::string> ASTCodeBlock::consume() {
if (iterator < content.size()) {
return content[iterator++]; // Post-increment: returns current, then increments
@@ -132,6 +147,12 @@ TokenType ASTCodeBlock::getTokenType() {
if (token == ")") {
return TokenType::CloseParen;
}
if (token == "[") {
return TokenType::ListStart;
}
if (token == "]") {
return TokenType::ListEnd;
}
if (token == "\n") {
return TokenType::NewLine;
}
@@ -288,6 +309,40 @@ void ASTCodeBlock::parseBlock() {
nodes.emplace_back(std::make_shared<ASTCodeBlock>(body));
break;
}
case TokenType::ListStart: {
std::vector<std::string> body;
int depth = 1;
while (depth > 0) {
std::optional<std::string> token = consume();
if (token.has_value()) {
if (token.value() == "[") {
depth++;
} else if (token.value() == "]") {
depth--;
if (depth == 0) {
break;
}
}
body.push_back(token.value());
} else {
std::cout << "Reached end of file while parsing list" << std::endl;
exit(1);
}
}
ASTCodeBlock list_elements_block(body);
std::vector<ASTNode> final_nodes;
for (const auto& node : list_elements_block.nodes) {
if (std::holds_alternative<std::shared_ptr<ASTIdentifier>>(node)) {
auto ident = std::get<std::shared_ptr<ASTIdentifier>>(node);
if (ident->name == ",") {
continue;
}
}
final_nodes.push_back(node);
}
nodes.emplace_back(std::make_shared<ASTValue>(ASTList(final_nodes)));
break;
}
default:
break;
}
@@ -297,7 +352,7 @@ void ASTCodeBlock::parseBlock() {
}
}
ASTCodeBlock::ASTCodeBlock() {}
ASTCodeBlock::ASTCodeBlock() = default;
ASTCodeBlock::ASTCodeBlock(std::vector<std::string> in) : content(std::move(in)) {
parseBlock();

View File

@@ -13,14 +13,24 @@ class ASTCodeBlock;
class ASTIdentifier;
typedef std::variant<std::shared_ptr<ASTValue>, std::shared_ptr<ASTFunction>, std::shared_ptr<ASTFunctionCall>, std::shared_ptr<ASTCodeBlock>, std::shared_ptr<ASTIdentifier>> ASTNode;
typedef std::variant<long long, double, std::string, bool> RealValue;
class ASTList {
private:
std::vector<ASTNode> elements;
public:
explicit ASTList(std::vector<ASTNode> in);
std::vector<ASTNode> getElements() const;
};
typedef std::variant<long long, double, std::string, bool, ASTList> RealValue;
enum class ValueType {
Int, Float, String, Bool, None
Int, Float, String, Bool, List, None
};
enum class TokenType {
Identifier, Value, Function, FunctionCallStart, OpenParen, CloseParen, CodeBlockStart, CodeBlockEnd, NewLine, None
Identifier, Value, Function, FunctionCallStart, OpenParen, CloseParen, CodeBlockStart, CodeBlockEnd, NewLine, ListStart, ListEnd, None
};
/**
@@ -37,14 +47,16 @@ private:
public:
ValueType type;
ValueType getValueType(std::string in);
std::optional<std::string> getString();
std::optional<int> getInt();
std::optional<double> getFloat();
std::optional<bool> getBool();
std::optional<std::string> getString() const;
std::optional<int> getInt() const;
std::optional<double> getFloat() const;
std::optional<bool> getBool() const;
std::optional<ASTList> getList() const;
explicit ASTValue(std::string in);
explicit ASTValue(long long in);
explicit ASTValue(double in);
explicit ASTValue(bool in);
explicit ASTValue(ASTList in);
ASTValue();
};
@@ -95,4 +107,4 @@ class ASTIdentifier {
explicit ASTIdentifier(std::string in);
};
ASTNode parser(std::vector<std::string> in);
ASTNode parser(std::vector<std::string> in);

View File

@@ -17,6 +17,71 @@ std::map<std::string, Object> Executor::getVariables() {
std::map<std::string, Object> globalVariables;
void Executor::printValue(const ASTValue& arg) {
if (arg.type == ValueType::String) {
std::optional<std::string> argString = arg.getString();
if (argString.has_value()) {
std::cout << argString.value();
} else {
std::cout << "Type mismatch - expecting string but got something else";
}
} else if (arg.type == ValueType::Int) {
std::optional<int> argInt = arg.getInt();
if (argInt.has_value()) {
std::cout << argInt.value();
} else {
std::cout << "Type mismatch - expecting int but got something else";
}
} else if (arg.type == ValueType::Float) {
std::optional<double> argFloat = arg.getFloat();
if (argFloat.has_value()) {
std::cout << argFloat.value();
} else {
std::cout << "Type mismatch - expecting float but got something else";
}
} else if (arg.type == ValueType::Bool) {
std::optional<bool> argBool = arg.getBool();
if (argBool.has_value()) {
std::cout << (argBool.value() ? "true" : "false");
} else {
std::cout << "Type mismatch - expecting bool but got something else";
}
} else if (arg.type == ValueType::List) {
std::optional<ASTList> list = arg.getList();
if (list.has_value()) {
std::cout << "[";
auto elements = list.value().getElements();
for (size_t i = 0; i < elements.size(); ++i) {
auto& node = elements[i];
if (std::holds_alternative<std::shared_ptr<ASTValue>>(node)) {
printValue(*std::get<std::shared_ptr<ASTValue>>(node));
} else if (std::holds_alternative<std::shared_ptr<ASTIdentifier>>(node)) {
auto name = std::get<std::shared_ptr<ASTIdentifier>>(node)->name;
if (variables.count(name)) {
Object obj = variables[name];
if (!obj.isCustomObject && std::holds_alternative<ASTValue>(obj.value)) {
printValue(std::get<ASTValue>(obj.value));
} else {
std::cout << "<function>";
}
} else {
std::cout << "<undefined variable: " << name << ">";
}
} else {
std::cout << "<unprintable>";
}
if (i < elements.size() - 1) {
std::cout << ", ";
}
}
std::cout << "]";
}
} else {
std::cout << "Type mismatch - expecting string, int, float, bool or list but got something else";
}
}
std::optional<ASTNode> Executor::consume() {
if (iterator < code.nodes.size()) {
return code.nodes[iterator++];
@@ -184,40 +249,9 @@ Executor::Executor(ASTCodeBlock in, bool isInitCall, std::map<std::string, Objec
ASTValue arg;
if (object.isCustomObject == false && std::holds_alternative<ASTValue>(object.value)) {
arg = std::get<ASTValue>(object.value);
printValue(arg);
} else {
std::cout << "Type mismatch - expecting string, int, float, or bool but got something else" << std::endl;
exit(1);
}
if (arg.type == ValueType::String) {
std::optional<std::string> argString = arg.getString();
if (argString.has_value()) {
std::cout << argString.value();
} else {
std::cout << "Type mismatch - expecting string but got something else" << std::endl;
}
} else if (arg.type == ValueType::Int) {
std::optional<int> argInt = arg.getInt();
if (argInt.has_value()) {
std::cout << argInt.value();
} else {
std::cout << "Type mismatch - expecting int but got something else" << std::endl;
}
} else if (arg.type == ValueType::Float) {
std::optional<double> argFloat = arg.getFloat();
if (argFloat.has_value()) {
std::cout << argFloat.value();
} else {
std::cout << "Type mismatch - expecting float but got something else" << std::endl;
}
} else if (arg.type == ValueType::Bool) {
std::optional<bool> argBool = arg.getBool();
if (argBool.has_value()) {
std::cout << argBool.value();
} else {
std::cout << "Type mismatch - expecting bool but got something else" << std::endl;
}
} else {
std::cout << "Type mismatch - expecting string, int, float, or bool but got something else" << std::endl;
std::cout << "Type mismatch - expecting printable value but got something else";
}
}
} else if (fnName == "println") {
@@ -225,40 +259,10 @@ Executor::Executor(ASTCodeBlock in, bool isInitCall, std::map<std::string, Objec
ASTValue arg;
if (object.isCustomObject == false && std::holds_alternative<ASTValue>(object.value)) {
arg = std::get<ASTValue>(object.value);
printValue(arg);
std::cout << std::endl;
} else {
std::cout << "Type mismatch - expecting string, int, float, or bool but got something else" << std::endl;
exit(1);
}
if (arg.type == ValueType::String) {
std::optional<std::string> argString = arg.getString();
if (argString.has_value()) {
std::cout << argString.value() << std::endl;
} else {
std::cout << "Type mismatch - expecting string but got something else" << std::endl;
}
} else if (arg.type == ValueType::Int) {
std::optional<int> argInt = arg.getInt();
if (argInt.has_value()) {
std::cout << argInt.value() << std::endl;
} else {
std::cout << "Type mismatch - expecting int but got something else" << std::endl;
}
} else if (arg.type == ValueType::Float) {
std::optional<double> argFloat = arg.getFloat();
if (argFloat.has_value()) {
std::cout << argFloat.value() << std::endl;
} else {
std::cout << "Type mismatch - expecting float but got something else" << std::endl;
}
} else if (arg.type == ValueType::Bool) {
std::optional<bool> argBool = arg.getBool();
if (argBool.has_value()) {
std::cout << (argBool.value() ? "true" : "false") << std::endl;
} else {
std::cout << "Type mismatch - expecting bool but got something else" << std::endl;
}
} else {
std::cout << "Type mismatch - expecting string, int, float, or bool but got something else" << std::endl;
std::cout << "Type mismatch - expecting printable value but got something else" << std::endl;
}
}
} else if (fnName == "if") {

View File

@@ -35,6 +35,7 @@ class Executor {
size_t iterator = 0;
std::optional<ASTNode> consume();
std::optional<ASTNode> peek(int ahead = 1);
void printValue(const ASTValue& arg);
public:
explicit Executor(ASTCodeBlock in, bool isInitCall = false, std::map<std::string, Object> scopeVals = {}, std::vector<Object> args = {});
std::map<std::string, Object> getVariables();