User input via cin
This commit is contained in:
parent
9ec709d4f2
commit
3eadd01cfa
4
names.mx
Normal file
4
names.mx
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
println "Hello there!";
|
||||||
|
print "What is your name? ";
|
||||||
|
let str yourName input;
|
||||||
|
println "Hello, " + yourName + "!";
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
27
test.mx
27
test.mx
|
@ -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";
|
|
Loading…
Reference in New Issue
Block a user