User input via cin

This commit is contained in:
Maxwell 2025-04-29 12:11:15 +10:00
parent 9ec709d4f2
commit 3eadd01cfa
8 changed files with 101 additions and 20 deletions

0
e
View File

BIN
mx

Binary file not shown.

4
names.mx Normal file
View File

@ -0,0 +1,4 @@
println "Hello there!";
print "What is your name? ";
let str yourName input;
println "Hello, " + yourName + "!";

View File

@ -29,11 +29,13 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
if (nextToken->keyword == keywords::SEMICOLON || nextToken->keyword == keywords::OBRAC || nextToken->keyword == keywords::CBRAC) {
consume(); // consume the semicolon
break;
} else if (nextToken->keyword == keywords::COMMENT) {
break;
}
consume(); // consume the peeked token
currentInstruction.push_back(nextToken.value());
}
// Apply variables to tokens
// Apply variables to tokens, as well as allow users to input strings
// We start at 1 so we can reassign variables in the execution of code
for (int i = 1; i < currentInstruction.size(); i++) {
if (currentInstruction[i].type == valtype::STR) {
@ -48,6 +50,15 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
newToken.value = varIt->second;
currentInstruction[i] = newToken;
}
} else if (currentInstruction[i].keyword == keywords::INPUT) {
Token newToken;
string buffer;
getline(cin, buffer);
newToken.value.value = buffer;
newToken.keyword = keywords::VALUE;
newToken.type = valtype::STR;
newToken.value.type = valtype::STR;
currentInstruction[i] = newToken;
}
}
// Do math
@ -148,6 +159,42 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
get<bool>(currentInstruction[i + 1].value.value));
}
currentInstruction[i - 1] = newToken;
currentInstruction.erase(currentInstruction.begin() + i);
currentInstruction.erase(currentInstruction.begin() + i);
i -= 1;
}
if (currentInstruction[i].keyword == keywords::INEQUAL) {
Token newToken;
newToken.keyword = keywords::VALUE;
newToken.type = valtype::BOOL;
newToken.value.type = valtype::BOOL;
if (currentInstruction.size() < i + 1) syntaxError.mathTooFewArgs();
if (currentInstruction[i - 1].type != currentInstruction[i + 1].type) syntaxError.mathTypeMismatch();
log.debug("Comparing values of type: " + to_string(static_cast<int>(currentInstruction[i - 1].type)));
// Make sure both operands are values
if (currentInstruction[i - 1].keyword != keywords::VALUE ||
currentInstruction[i + 1].keyword != keywords::VALUE) {
syntaxError.generalError("Can only compare values of");
return;
}
// Ensure value types are set correctly
if (currentInstruction[i - 1].value.type == valtype::INT) {
newToken.value.value = (get<int>(currentInstruction[i - 1].value.value) !=
get<int>(currentInstruction[i + 1].value.value));
} else if (currentInstruction[i - 1].value.type == valtype::DEC) {
newToken.value.value = (get<double>(currentInstruction[i - 1].value.value) !=
get<double>(currentInstruction[i + 1].value.value));
} else if (currentInstruction[i - 1].value.type == valtype::STR) {
newToken.value.value = (get<string>(currentInstruction[i - 1].value.value) !=
get<string>(currentInstruction[i + 1].value.value));
} else if (currentInstruction[i - 1].value.type == valtype::BOOL) {
newToken.value.value = (get<bool>(currentInstruction[i - 1].value.value) !=
get<bool>(currentInstruction[i + 1].value.value));
}
currentInstruction[i - 1] = newToken;
currentInstruction.erase(currentInstruction.begin() + i);
currentInstruction.erase(currentInstruction.begin() + i);
@ -170,7 +217,7 @@ void Interpreter::executeCode(vector<Token> tokens) {
skipScope --;
return;
}
if (tokens[i].keyword == keywords::PRINT) {
if (tokens[i].keyword == keywords::PRINTLN) {
i++;
if (tokens.size() <= i) break;
Token nextToken = tokens[i];
@ -189,6 +236,32 @@ void Interpreter::executeCode(vector<Token> tokens) {
case valtype::BOOL:
cout << (get<bool>(nextToken.value.value) ? "true" : "false") << endl;
break;
default:
vector<string> validTypes = {"int", "dec", "str", "bool"};
syntaxError.fnTypeMismatch("println", validTypes, nextToken.type);
}
} else {
syntaxError.fnNotSufficientArgs("println", 1, 1, 0);
}
} else if (tokens[i].keyword == keywords::PRINT) {
i++;
if (tokens.size() <= i) break;
Token nextToken = tokens[i];
// Handle different value types
if (nextToken.keyword == keywords::VALUE) {
switch (nextToken.type) {
case valtype::INT:
cout << get<int>(nextToken.value.value);
break;
case valtype::DEC:
cout << get<double>(nextToken.value.value);
break;
case valtype::STR:
cout << get<string>(nextToken.value.value);
break;
case valtype::BOOL:
cout << (get<bool>(nextToken.value.value) ? "true" : "false");
break;
default:
vector<string> validTypes = {"int", "dec", "str", "bool"};
syntaxError.fnTypeMismatch("print", validTypes, nextToken.type);

View File

@ -101,6 +101,8 @@ void Parser::processLines() {
else if (ct == "fun") token.keyword = keywords::FUN;
else if (ct == "let") token.keyword = keywords::LET;
else if (ct == "print") token.keyword = keywords::PRINT;
else if (ct == "println") token.keyword = keywords::PRINTLN;
else if (ct == "input") token.keyword = keywords::INPUT;
else if (ct == "return") token.keyword = keywords::RETURN;
else if (ct == "exit") token.keyword = keywords::EXIT;
else if (ct == "int") token.keyword = keywords::INT;
@ -125,6 +127,10 @@ void Parser::processLines() {
else if (ct == "*=") token.keyword = keywords::MULTIPLYTO;
else if (ct == "/=") token.keyword = keywords::DIVIDEFROM;
else if (ct == "==") token.keyword = keywords::EQUAL;
else if (ct == "!=") token.keyword = keywords::INEQUAL;
else if (ct == "<") token.keyword = keywords::LESS;
else if (ct == ">") token.keyword = keywords::GREATER;
else if (ct == "//") token.keyword = keywords::COMMENT;
else {
token.keyword = keywords::VALUE;
// Convert the value based on its type

View File

@ -20,8 +20,9 @@ enum class keywords {
ADD, SUBTRACT, MULTIPLY, DIVIDE,
EQUAL, INEQUAL, LESS, GREATER, EQLESS, EQGREATER,
INCREMENT, DECREMENT,
PRINT, LET, INPUT, EXIT,
VALUE, SEMICOLON, VARIABLE
PRINT, PRINTLN, LET, INPUT, EXIT,
VALUE, SEMICOLON, VARIABLE,
COMMENT
};
struct Value {

View File

@ -2,4 +2,4 @@
bob
./mx --debug test.mx
./mx test.mx

27
test.mx
View File

@ -1,15 +1,12 @@
print "dingusify";
let str bingus "heheheha its bingusing time";
print bingus;
print 1 + 1;
let int myInt 3;
print myInt;
myInt = 5;
print myInt;
let str myString "dingus";
print myString;
myString = "dongus";
print myString;
print 5 == 5;
print 843 == 122;
print "dingus" == "dongus";
let str thing2 "dingus";
let str thing2 "dingus";
if thing1 == thing2 {
println "thing 1 and thing 2 are the same";
}
print "this is printing something without a new line";
println " this is coming from a seperate print statement lols";
print "Say some wise words... ";
println "Ah, '" + input + "', some very wise words indeed!";