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) { if (nextToken->keyword == keywords::SEMICOLON || nextToken->keyword == keywords::OBRAC || nextToken->keyword == keywords::CBRAC) {
consume(); // consume the semicolon consume(); // consume the semicolon
break; break;
} else if (nextToken->keyword == keywords::COMMENT) {
break;
} }
consume(); // consume the peeked token consume(); // consume the peeked token
currentInstruction.push_back(nextToken.value()); 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 // We start at 1 so we can reassign variables in the execution of code
for (int i = 1; i < currentInstruction.size(); i++) { for (int i = 1; i < currentInstruction.size(); i++) {
if (currentInstruction[i].type == valtype::STR) { if (currentInstruction[i].type == valtype::STR) {
@ -48,6 +50,15 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
newToken.value = varIt->second; newToken.value = varIt->second;
currentInstruction[i] = newToken; 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 // Do math
@ -148,6 +159,42 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
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);
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[i - 1] = newToken;
currentInstruction.erase(currentInstruction.begin() + i); currentInstruction.erase(currentInstruction.begin() + i);
currentInstruction.erase(currentInstruction.begin() + i); currentInstruction.erase(currentInstruction.begin() + i);
@ -170,7 +217,7 @@ void Interpreter::executeCode(vector<Token> tokens) {
skipScope --; skipScope --;
return; return;
} }
if (tokens[i].keyword == keywords::PRINT) { if (tokens[i].keyword == keywords::PRINTLN) {
i++; i++;
if (tokens.size() <= i) break; if (tokens.size() <= i) break;
Token nextToken = tokens[i]; Token nextToken = tokens[i];
@ -189,6 +236,32 @@ void Interpreter::executeCode(vector<Token> tokens) {
case valtype::BOOL: case valtype::BOOL:
cout << (get<bool>(nextToken.value.value) ? "true" : "false") << endl; cout << (get<bool>(nextToken.value.value) ? "true" : "false") << endl;
break; 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: default:
vector<string> validTypes = {"int", "dec", "str", "bool"}; vector<string> validTypes = {"int", "dec", "str", "bool"};
syntaxError.fnTypeMismatch("print", validTypes, nextToken.type); 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 == "fun") token.keyword = keywords::FUN;
else if (ct == "let") token.keyword = keywords::LET; else if (ct == "let") token.keyword = keywords::LET;
else if (ct == "print") token.keyword = keywords::PRINT; 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 == "return") token.keyword = keywords::RETURN;
else if (ct == "exit") token.keyword = keywords::EXIT; else if (ct == "exit") token.keyword = keywords::EXIT;
else if (ct == "int") token.keyword = keywords::INT; 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::MULTIPLYTO;
else if (ct == "/=") token.keyword = keywords::DIVIDEFROM; else if (ct == "/=") token.keyword = keywords::DIVIDEFROM;
else if (ct == "==") token.keyword = keywords::EQUAL; 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 { else {
token.keyword = keywords::VALUE; token.keyword = keywords::VALUE;
// Convert the value based on its type // Convert the value based on its type

View File

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

View File

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

27
test.mx
View File

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