floats
This commit is contained in:
parent
70cecced8d
commit
4ace3f049d
@ -28,40 +28,40 @@ Value Context::eval(peg::Ast& ast) {
|
|||||||
for (int i=0; i<ast.nodes.size(); i++) {
|
for (int i=0; i<ast.nodes.size(); i++) {
|
||||||
eval(*nodes[i]);
|
eval(*nodes[i]);
|
||||||
}
|
}
|
||||||
return Nil();
|
return Value(cxt, Nil());
|
||||||
} else if (ast.name == "VarDecl") {
|
} else if (ast.name == "VarDecl") {
|
||||||
std::string identifier = eval(*nodes[0]).getIdentifier(cxt).identifier;
|
std::string identifier = eval(*nodes[0]).getIdentifier(cxt).identifier;
|
||||||
Value value = eval(*nodes[1]);
|
Value value = eval(*nodes[1]);
|
||||||
currentScope->writeVar(cxt, identifier, value);
|
currentScope->writeVar(cxt, identifier, value);
|
||||||
return Nil();
|
return Value(cxt, Nil());
|
||||||
} else if (ast.name == "IDENTIFIER" || ast.name == "BUILTINIDENTIFIER") {
|
} else if (ast.name == "IDENTIFIER" || ast.name == "BUILTINIDENTIFIER") {
|
||||||
return Identifier(std::string(ast.token_to_string()));
|
return Value(cxt, Identifier(std::string(ast.token_to_string())));
|
||||||
} else if (ast.name == "INTEGER") {
|
} else if (ast.name == "INTEGER") {
|
||||||
// TODO parse hex, oct, and binary
|
return Value(cxt, ast.token_to_number<long>());
|
||||||
return ast.token_to_number<long>();
|
} else if (ast.name == "FLOAT") {
|
||||||
|
return Value(cxt, ast.token_to_number<double>());
|
||||||
} else if (ast.name == "BUILTINCALL" ) {
|
} else if (ast.name == "BUILTINCALL" ) {
|
||||||
std::string identifier = eval(*nodes[0]).getIdentifier(cxt).identifier;
|
std::string identifier = eval(*nodes[0]).getIdentifier(cxt).identifier;
|
||||||
Args args = eval(*nodes[1]).getArgs(cxt);
|
Args args = eval(*nodes[1]).getArgs(cxt);
|
||||||
return builtins.at(identifier).execute(cxt, args);
|
return builtins.at(identifier).execute(cxt, args);
|
||||||
} else if (ast.name == "STRINGLITERALSINGLE")
|
} else if (ast.name == "STRINGLITERALSINGLE")
|
||||||
{
|
{
|
||||||
return ast.token_to_string();
|
return Value(cxt, ast.token_to_string());
|
||||||
} else if (ast.name == "ExprList") {
|
} else if (ast.name == "ExprList") {
|
||||||
Args exprs;
|
Args exprs;
|
||||||
for (int i=0; i<ast.nodes.size(); i++) {
|
for (int i=0; i<ast.nodes.size(); i++) {
|
||||||
exprs.args.push_back(getValue(eval(*nodes[i])));
|
exprs.args.push_back(getValue(eval(*nodes[i])));
|
||||||
}
|
}
|
||||||
return exprs;
|
return Value(cxt, exprs);
|
||||||
} else if (ast.name == "AdditionExpr") {
|
} else if (ast.name == "AdditionExpr") {
|
||||||
Value value = getValue(eval(*nodes[0]));
|
Value value = getValue(eval(*nodes[0]));
|
||||||
for (int i=1; i<nodes.size(); i+=2) {
|
for (int i=1; i<nodes.size(); i+=2) {
|
||||||
int op = (*nodes[i]).choice;
|
int op = (*nodes[i]).choice;
|
||||||
Value v2 = getValue(eval(*nodes[i+1]));
|
Value v2 = getValue(eval(*nodes[i+1]));
|
||||||
// TODO: floats
|
|
||||||
if (op == 0) {
|
if (op == 0) {
|
||||||
value = value.getInt(cxt) + v2.getInt(cxt);
|
value = value + v2;
|
||||||
} else {
|
} else {
|
||||||
value = value.getInt(cxt) - v2.getInt(cxt);
|
value = value - v2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@ -70,11 +70,10 @@ Value Context::eval(peg::Ast& ast) {
|
|||||||
for (int i=1; i<nodes.size(); i+=2) {
|
for (int i=1; i<nodes.size(); i+=2) {
|
||||||
int op = (*nodes[i]).choice;
|
int op = (*nodes[i]).choice;
|
||||||
Value v2 = getValue(eval(*nodes[i+1]));
|
Value v2 = getValue(eval(*nodes[i+1]));
|
||||||
// TODO: floats
|
|
||||||
if (op == 0) {
|
if (op == 0) {
|
||||||
value = value.getInt(cxt) * v2.getInt(cxt);
|
value = value * v2;
|
||||||
} else {
|
} else {
|
||||||
value = value.getInt(cxt) / v2.getInt(cxt);
|
value = value / v2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@ -84,22 +83,21 @@ Value Context::eval(peg::Ast& ast) {
|
|||||||
auto v1 = currentScope->getVar(*this, name);
|
auto v1 = currentScope->getVar(*this, name);
|
||||||
int op = (*nodes[1]).choice;
|
int op = (*nodes[1]).choice;
|
||||||
auto v2 = getValue(eval(*nodes[2]));
|
auto v2 = getValue(eval(*nodes[2]));
|
||||||
Value result = Nil();
|
Value result = Value(cxt, Nil());
|
||||||
// TODO: floats
|
|
||||||
if (op == 0) {
|
if (op == 0) {
|
||||||
result = v1.getInt(cxt) * v2.getInt(cxt);
|
result = v1 * v2;
|
||||||
} else if (op == 1) {
|
} else if (op == 1) {
|
||||||
result = v1.getInt(cxt) % v2.getInt(cxt);
|
result = v1 % v2;
|
||||||
} else if (op == 2) {
|
} else if (op == 2) {
|
||||||
result = v1.getInt(cxt) + v2.getInt(cxt);
|
result = v1 + v2;
|
||||||
} else if (op == 3) {
|
} else if (op == 3) {
|
||||||
result = v1.getInt(cxt) - v2.getInt(cxt);
|
result = v1 - v2;
|
||||||
} else if (op == 4) {
|
} else if (op == 4) {
|
||||||
result = v1.getInt(cxt) & v2.getInt(cxt);
|
result = v1 & v2;
|
||||||
} else if (op == 5) {
|
} else if (op == 5) {
|
||||||
result = v1.getInt(cxt) ^ v2.getInt(cxt);
|
result = v1 ^ v2;
|
||||||
} else if (op == 6) {
|
} else if (op == 6) {
|
||||||
result = v1.getInt(cxt) | v2.getInt(cxt);
|
result = v1 | v2;
|
||||||
} else if (op == 7) {
|
} else if (op == 7) {
|
||||||
result = v2;
|
result = v2;
|
||||||
}
|
}
|
||||||
@ -107,12 +105,12 @@ Value Context::eval(peg::Ast& ast) {
|
|||||||
return result;
|
return result;
|
||||||
} else if (ast.name == "PrimaryTypeExpr") {
|
} else if (ast.name == "PrimaryTypeExpr") {
|
||||||
int op = ast.choice;
|
int op = ast.choice;
|
||||||
if (op == 8) {
|
if (op == 7) {
|
||||||
return false;
|
return Value(cxt, false);
|
||||||
|
} else if (op == 8) {
|
||||||
|
return Value(cxt, Nil());
|
||||||
} else if (op == 9) {
|
} else if (op == 9) {
|
||||||
return Nil();
|
return Value(cxt, true);
|
||||||
} else if (op == 10) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
} else if (ast.name == "CompareExpr") {
|
} else if (ast.name == "CompareExpr") {
|
||||||
Value v1 = getValue(eval(*nodes[0]));
|
Value v1 = getValue(eval(*nodes[0]));
|
||||||
@ -120,17 +118,17 @@ Value Context::eval(peg::Ast& ast) {
|
|||||||
Value v2 = getValue(eval(*nodes[2]));
|
Value v2 = getValue(eval(*nodes[2]));
|
||||||
// TODO: floats, bool, etc.
|
// TODO: floats, bool, etc.
|
||||||
if (op == 0) {
|
if (op == 0) {
|
||||||
return (bool)(v1.getInt(cxt) == v2.getInt(cxt));
|
return v1 == v2;
|
||||||
} else if (op == 1) {
|
} else if (op == 1) {
|
||||||
return (bool)(v1.getInt(cxt) != v2.getInt(cxt));
|
return v1 != v2;
|
||||||
} else if (op == 2) {
|
} else if (op == 2) {
|
||||||
return (bool)(v1.getInt(cxt) < v2.getInt(cxt));
|
return v1 < v2;
|
||||||
} else if (op == 3) {
|
} else if (op == 3) {
|
||||||
return (bool)(v1.getInt(cxt) > v2.getInt(cxt));
|
return v1 > v2;
|
||||||
} else if (op == 4) {
|
} else if (op == 4) {
|
||||||
return (bool)(v1.getInt(cxt) <= v2.getInt(cxt));
|
return v1 <= v2;
|
||||||
} else if (op == 5) {
|
} else if (op == 5) {
|
||||||
return (bool)(v1.getInt(cxt) >= v2.getInt(cxt));
|
return v1 >= v2;
|
||||||
}
|
}
|
||||||
} else if (ast.name == "IfStatement") {
|
} else if (ast.name == "IfStatement") {
|
||||||
Value val = getValue(eval(*nodes[0]));
|
Value val = getValue(eval(*nodes[0]));
|
||||||
@ -141,13 +139,13 @@ Value Context::eval(peg::Ast& ast) {
|
|||||||
}
|
}
|
||||||
} else if (ast.name == "Block") {
|
} else if (ast.name == "Block") {
|
||||||
// TODO create new scope
|
// TODO create new scope
|
||||||
Value result = Nil();
|
Value result = Value(cxt, Nil());
|
||||||
for (int i=0; i<ast.nodes.size(); i++) {
|
for (int i=0; i<ast.nodes.size(); i++) {
|
||||||
result = eval(*nodes[i]);
|
result = eval(*nodes[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else if (ast.name == "WhileStatement") {
|
} else if (ast.name == "WhileStatement") {
|
||||||
Value result = Nil();
|
Value result = Value(cxt, Nil());
|
||||||
while (getValue(eval(*nodes[0])).getBoolean(cxt)) {
|
while (getValue(eval(*nodes[0])).getBoolean(cxt)) {
|
||||||
result = eval(*nodes[1]);
|
result = eval(*nodes[1]);
|
||||||
}
|
}
|
||||||
@ -158,13 +156,13 @@ Value Context::eval(peg::Ast& ast) {
|
|||||||
for (int i=0; i<args.args.size(); i++) {
|
for (int i=0; i<args.args.size(); i++) {
|
||||||
identifiers.push_back(args.args[i].getIdentifier(cxt));
|
identifiers.push_back(args.args[i].getIdentifier(cxt));
|
||||||
}
|
}
|
||||||
return Func(nodes[1], identifiers);
|
return Value(cxt, Func(nodes[1], identifiers));
|
||||||
} else if (ast.name == "ParamDeclList") {
|
} else if (ast.name == "ParamDeclList") {
|
||||||
Args identifiers;
|
Args identifiers;
|
||||||
for (int i=0; i<nodes.size(); i++) {
|
for (int i=0; i<nodes.size(); i++) {
|
||||||
identifiers.args.push_back(Value(eval(*nodes[i]).getIdentifier(cxt)));
|
identifiers.args.push_back(Value(cxt, eval(*nodes[i]).getIdentifier(cxt)));
|
||||||
}
|
}
|
||||||
return identifiers;
|
return Value(cxt, identifiers);
|
||||||
} else if (ast.name == "SuffixExpr") {
|
} else if (ast.name == "SuffixExpr") {
|
||||||
// TODO handle other PrimaryTypeExpr types
|
// TODO handle other PrimaryTypeExpr types
|
||||||
Value val = getValue(eval(*nodes[0]));
|
Value val = getValue(eval(*nodes[0]));
|
||||||
@ -180,5 +178,5 @@ Value Context::eval(peg::Ast& ast) {
|
|||||||
std::cout << "AST child: " << ast.name << " : ";
|
std::cout << "AST child: " << ast.name << " : ";
|
||||||
eval(*nodes[i]);
|
eval(*nodes[i]);
|
||||||
}
|
}
|
||||||
return Nil();
|
return Value(cxt, Nil());
|
||||||
}
|
}
|
@ -67,7 +67,6 @@ SuffixExpr <- PrimaryTypeExpr (SuffixOp / FnCallArguments)*
|
|||||||
|
|
||||||
PrimaryTypeExpr
|
PrimaryTypeExpr
|
||||||
<- BUILTINCALL
|
<- BUILTINCALL
|
||||||
/ CHAR_LITERAL
|
|
||||||
/ DOT IDENTIFIER
|
/ DOT IDENTIFIER
|
||||||
/ FLOAT
|
/ FLOAT
|
||||||
/ Fn
|
/ Fn
|
||||||
@ -156,21 +155,14 @@ ExprList <- (Expr COMMA)* Expr? { no_ast_opt }
|
|||||||
ParamDeclList <- (IDENTIFIER COMMA)* IDENTIFIER? { no_ast_opt }
|
ParamDeclList <- (IDENTIFIER COMMA)* IDENTIFIER? { no_ast_opt }
|
||||||
|
|
||||||
# *** Tokens ***
|
# *** Tokens ***
|
||||||
INTEGER
|
INTEGER <- < dec_int > skip
|
||||||
<- "0b" < bin_int > skip
|
|
||||||
/ "0o" < oct_int > skip
|
|
||||||
/ "0x" < hex_int > skip
|
|
||||||
/ < dec_int > skip
|
|
||||||
|
|
||||||
IDENTIFIER <- !keyword < [A-Za-z_] [A-Za-z0-9_]* > skip
|
IDENTIFIER <- !keyword < [A-Za-z_] [A-Za-z0-9_]* > skip
|
||||||
BUILTINIDENTIFIER <- "@" < [A-Za-z_][A-Za-z0-9_]* > skip
|
BUILTINIDENTIFIER <- "@" < [A-Za-z_][A-Za-z0-9_]* > skip
|
||||||
|
|
||||||
CHAR_LITERAL <- "'" char_char "'" skip
|
|
||||||
FLOAT
|
FLOAT
|
||||||
<- "0x" hex_int "." hex_int ([pP] [-+]? dec_int)? skip
|
<- < dec_int "." dec_int ([eE] [-+]? dec_int)? > skip
|
||||||
/ dec_int "." dec_int ([eE] [-+]? dec_int)? skip
|
/ < dec_int "."? [eE] [-+]? dec_int > skip
|
||||||
/ "0x" hex_int "."? [pP] [-+]? dec_int skip
|
|
||||||
/ dec_int "."? [eE] [-+]? dec_int skip
|
|
||||||
|
|
||||||
STRINGLITERAL
|
STRINGLITERAL
|
||||||
<- STRINGLITERALSINGLE
|
<- STRINGLITERALSINGLE
|
||||||
|
@ -35,6 +35,8 @@ int main(void) {
|
|||||||
@print(abc);
|
@print(abc);
|
||||||
};
|
};
|
||||||
hello("world");
|
hello("world");
|
||||||
|
a = 0.1 / 100;
|
||||||
|
@print(a);
|
||||||
)";
|
)";
|
||||||
|
|
||||||
parser.enable_ast();
|
parser.enable_ast();
|
||||||
|
165
src/types.cpp
165
src/types.cpp
@ -7,7 +7,7 @@ Value Func::execute(Context& cxt, Args& args) {
|
|||||||
return nativeFunction(cxt, args);
|
return nativeFunction(cxt, args);
|
||||||
} else {
|
} else {
|
||||||
// TODO create scope
|
// TODO create scope
|
||||||
Value result = Value(Nil());
|
Value result = Value(cxt, Nil());
|
||||||
for (int i=0; i<args.args.size(); i++) {
|
for (int i=0; i<args.args.size(); i++) {
|
||||||
cxt.currentScope->writeVar(cxt, argNames[i].identifier, args.args[i]);
|
cxt.currentScope->writeVar(cxt, argNames[i].identifier, args.args[i]);
|
||||||
}
|
}
|
||||||
@ -17,32 +17,32 @@ Value Func::execute(Context& cxt, Args& args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::Value(Nil nil) : type(TypeNil) {
|
Value::Value(Context &cxt, Nil nil) : cxt(cxt), type(TypeNil) {
|
||||||
value.nil = Nil();
|
value.nil = Nil();
|
||||||
}
|
}
|
||||||
Value::Value(long int_) : type(TypeInt) {
|
Value::Value(Context &cxt, long int_) : cxt(cxt), type(TypeInt) {
|
||||||
value.int_ = int_;
|
value.int_ = int_;
|
||||||
}
|
}
|
||||||
Value::Value(double float_) : type(TypeFloat) {
|
Value::Value(Context &cxt, double float_) : cxt(cxt), type(TypeFloat) {
|
||||||
value.float_ = float_;
|
value.float_ = float_;
|
||||||
}
|
}
|
||||||
Value::Value(bool bool_) : type(TypeBoolean) {
|
Value::Value(Context &cxt, bool bool_) : cxt(cxt), type(TypeBoolean) {
|
||||||
value.bool_ = bool_;
|
value.bool_ = bool_;
|
||||||
}
|
}
|
||||||
Value::Value(const std::string &string) : type(TypeString) {
|
Value::Value(Context &cxt, const std::string &string) : cxt(cxt), type(TypeString) {
|
||||||
value.string = new std::string(string);
|
value.string = new std::string(string);
|
||||||
}
|
}
|
||||||
Value::Value(const Func &function) : type(TypeFunction) {
|
Value::Value(Context &cxt, const Func &function) : cxt(cxt), type(TypeFunction) {
|
||||||
value.function = new Func(function);
|
value.function = new Func(function);
|
||||||
}
|
}
|
||||||
Value::Value(const Args &args) : type(TypeArgs) {
|
Value::Value(Context &cxt, const Args &args) : cxt(cxt), type(TypeArgs) {
|
||||||
value.args = new Args(args);
|
value.args = new Args(args);
|
||||||
}
|
}
|
||||||
Value::Value(const Identifier &identifier) : type(TypeIdentifier) {
|
Value::Value(Context &cxt, const Identifier &identifier) : cxt(cxt), type(TypeIdentifier) {
|
||||||
value.identifier = new Identifier(identifier);
|
value.identifier = new Identifier(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::Value(const Value &val) {
|
Value::Value(const Value &val) : cxt(val.cxt) {
|
||||||
if (val.isNil()) {
|
if (val.isNil()) {
|
||||||
*this = Nil();
|
*this = Nil();
|
||||||
} else if (val.isInt()) {
|
} else if (val.isInt()) {
|
||||||
@ -178,87 +178,198 @@ bool Value::isIdentifier() const {
|
|||||||
return type == TypeIdentifier;
|
return type == TypeIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::assertNil(Context &cxt) {
|
void Value::assertNil(Context &cxt) const {
|
||||||
if (!isNil()) {
|
if (!isNil()) {
|
||||||
cxt.error("value is not nil");
|
cxt.error("value is not nil");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Value::assertInt(Context &cxt) {
|
void Value::assertInt(Context &cxt) const {
|
||||||
if (!isInt()) {
|
if (!isInt()) {
|
||||||
cxt.error("value is not an integer");
|
cxt.error("value is not an integer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Value::assertFloat(Context &cxt) {
|
void Value::assertFloat(Context &cxt) const {
|
||||||
if (!isFloat()) {
|
if (!isFloat()) {
|
||||||
cxt.error("value is not a float");
|
cxt.error("value is not a float");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Value::assertNumber(Context &cxt) {
|
void Value::assertNumber(Context &cxt) const {
|
||||||
if (!isNumber()) {
|
if (!isNumber()) {
|
||||||
cxt.error("value is not a number");
|
cxt.error("value is not a number");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Value::assertBoolean(Context &cxt) {
|
void Value::assertBoolean(Context &cxt) const {
|
||||||
if (!isBoolean()) {
|
if (!isBoolean()) {
|
||||||
cxt.error("value is not a boolean");
|
cxt.error("value is not a boolean");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Value::assertString(Context &cxt) {
|
void Value::assertString(Context &cxt) const {
|
||||||
if (!isString()) {
|
if (!isString()) {
|
||||||
cxt.error("value is not a string");
|
cxt.error("value is not a string");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Value::assertFunction(Context &cxt) {
|
void Value::assertFunction(Context &cxt) const {
|
||||||
if (!isFunction()) {
|
if (!isFunction()) {
|
||||||
cxt.error("value is not a function");
|
cxt.error("value is not a function");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Value::assertArgs(Context &cxt) {
|
void Value::assertArgs(Context &cxt) const {
|
||||||
if (!isArgs()) {
|
if (!isArgs()) {
|
||||||
cxt.error("value is not arguments");
|
cxt.error("value is not arguments");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Value::assertIdentifier(Context &cxt) {
|
void Value::assertIdentifier(Context &cxt) const {
|
||||||
if (!isIdentifier()) {
|
if (!isIdentifier()) {
|
||||||
cxt.error("value is not identifier");
|
cxt.error("value is not identifier");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Nil Value::getNil(Context &cxt) {
|
Nil Value::getNil(Context &cxt) const {
|
||||||
assertNil(cxt);
|
assertNil(cxt);
|
||||||
return value.nil;
|
return value.nil;
|
||||||
}
|
}
|
||||||
long Value::getInt(Context &cxt) {
|
long Value::getInt(Context &cxt) const {
|
||||||
assertNumber(cxt);
|
assertNumber(cxt);
|
||||||
if (isFloat())
|
if (isFloat())
|
||||||
return (long)value.float_;
|
return (long)value.float_;
|
||||||
else
|
else
|
||||||
return value.int_;
|
return value.int_;
|
||||||
}
|
}
|
||||||
double Value::getFloat(Context &cxt) {
|
double Value::getFloat(Context &cxt) const {
|
||||||
assertNumber(cxt);
|
assertNumber(cxt);
|
||||||
if (isInt())
|
if (isInt())
|
||||||
return (double)value.int_;
|
return (double)value.int_;
|
||||||
else
|
else
|
||||||
return value.float_;
|
return value.float_;
|
||||||
}
|
}
|
||||||
bool Value::getBoolean(Context &cxt) {
|
bool Value::getBoolean(Context &cxt) const {
|
||||||
assertBoolean(cxt);
|
assertBoolean(cxt);
|
||||||
return value.bool_;
|
return value.bool_;
|
||||||
}
|
}
|
||||||
std::string Value::getString(Context &cxt) {
|
std::string Value::getString(Context &cxt) const {
|
||||||
assertString(cxt);
|
assertString(cxt);
|
||||||
return *value.string;
|
return *value.string;
|
||||||
}
|
}
|
||||||
Func Value::getFunction(Context &cxt) {
|
Func Value::getFunction(Context &cxt) const {
|
||||||
assertFunction(cxt);
|
assertFunction(cxt);
|
||||||
return *value.function;
|
return *value.function;
|
||||||
}
|
}
|
||||||
Args Value::getArgs(Context &cxt) {
|
Args Value::getArgs(Context &cxt) const {
|
||||||
assertArgs(cxt);
|
assertArgs(cxt);
|
||||||
return *value.args;
|
return *value.args;
|
||||||
}
|
}
|
||||||
Identifier Value::getIdentifier(Context &cxt) {
|
Identifier Value::getIdentifier(Context &cxt) const {
|
||||||
assertIdentifier(cxt);
|
assertIdentifier(cxt);
|
||||||
return *value.identifier;
|
return *value.identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value Value::operator+(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) + rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) + rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator-(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) - rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) - rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator*(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) * rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) * rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator/(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) / rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) / rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator%(const Value &rhs) const {
|
||||||
|
assertInt(cxt);
|
||||||
|
rhs.assertInt(cxt);
|
||||||
|
return Value(cxt, getInt(cxt) % rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
Value Value::operator&(const Value &rhs) const {
|
||||||
|
assertInt(cxt);
|
||||||
|
rhs.assertInt(cxt);
|
||||||
|
return Value(cxt, getInt(cxt) & rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
Value Value::operator^(const Value &rhs) const {
|
||||||
|
assertInt(cxt);
|
||||||
|
rhs.assertInt(cxt);
|
||||||
|
return Value(cxt, getInt(cxt) ^ rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
Value Value::operator|(const Value &rhs) const {
|
||||||
|
assertInt(cxt);
|
||||||
|
rhs.assertInt(cxt);
|
||||||
|
return Value(cxt, getInt(cxt) | rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
Value Value::operator==(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) == rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) == rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator!=(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) != rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) != rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator<(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) < rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) < rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator>(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) > rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) > rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator<=(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) <= rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) <= rhs.getInt(cxt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value Value::operator>=(const Value &rhs) const {
|
||||||
|
assertNumber(cxt);
|
||||||
|
rhs.assertNumber(cxt);
|
||||||
|
if (isFloat() || rhs.isFloat()) {
|
||||||
|
return Value(cxt, getFloat(cxt) >= rhs.getFloat(cxt));
|
||||||
|
} else {
|
||||||
|
return Value(cxt, getInt(cxt) >= rhs.getInt(cxt));
|
||||||
|
}
|
||||||
}
|
}
|
66
src/types.h
66
src/types.h
@ -81,16 +81,17 @@ protected:
|
|||||||
|
|
||||||
Type type = TypeNil;
|
Type type = TypeNil;
|
||||||
TypeValues value;
|
TypeValues value;
|
||||||
|
Context &cxt;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Value(Nil nil);
|
Value(Context &cxt, Nil nil);
|
||||||
Value(long int_);
|
Value(Context &cxt, long int_);
|
||||||
Value(double float_);
|
Value(Context &cxt, double float_);
|
||||||
Value(bool bool_);
|
Value(Context &cxt, bool bool_);
|
||||||
Value(const std::string &string);
|
Value(Context &cxt, const std::string &string);
|
||||||
Value(const Func &function);
|
Value(Context &cxt, const Func &function);
|
||||||
Value(const Args &args);
|
Value(Context &cxt, const Args &args);
|
||||||
Value(const Identifier &identifier);
|
Value(Context &cxt, const Identifier &identifier);
|
||||||
|
|
||||||
Value(const Value &value);
|
Value(const Value &value);
|
||||||
Value& operator=(const Value &rhs);
|
Value& operator=(const Value &rhs);
|
||||||
@ -117,22 +118,37 @@ public:
|
|||||||
bool isArgs() const;
|
bool isArgs() const;
|
||||||
bool isIdentifier() const;
|
bool isIdentifier() const;
|
||||||
|
|
||||||
void assertNil(Context &cxt);
|
void assertNil(Context &cxt) const;
|
||||||
void assertInt(Context &cxt);
|
void assertInt(Context &cxt) const;
|
||||||
void assertFloat(Context &cxt);
|
void assertFloat(Context &cxt) const;
|
||||||
void assertNumber(Context &cxt);
|
void assertNumber(Context &cxt) const;
|
||||||
void assertBoolean(Context &cxt);
|
void assertBoolean(Context &cxt) const;
|
||||||
void assertString(Context &cxt);
|
void assertString(Context &cxt) const;
|
||||||
void assertFunction(Context &cxt);
|
void assertFunction(Context &cxt) const;
|
||||||
void assertArgs(Context &cxt);
|
void assertArgs(Context &cxt) const;
|
||||||
void assertIdentifier(Context &cxt);
|
void assertIdentifier(Context &cxt) const;
|
||||||
|
|
||||||
Nil getNil(Context &cxt);
|
Nil getNil(Context &cxt) const;
|
||||||
long getInt(Context &cxt);
|
long getInt(Context &cxt) const;
|
||||||
double getFloat(Context &cxt);
|
double getFloat(Context &cxt) const;
|
||||||
bool getBoolean(Context &cxt);
|
bool getBoolean(Context &cxt) const;
|
||||||
std::string getString(Context &cxt);
|
std::string getString(Context &cxt) const;
|
||||||
Func getFunction(Context &cxt);
|
Func getFunction(Context &cxt) const;
|
||||||
Args getArgs(Context &cxt);
|
Args getArgs(Context &cxt) const;
|
||||||
Identifier getIdentifier(Context &cxt);
|
Identifier getIdentifier(Context &cxt) const;
|
||||||
|
|
||||||
|
Value operator+(const Value &rhs) const;
|
||||||
|
Value operator-(const Value &rhs) const;
|
||||||
|
Value operator*(const Value &rhs) const;
|
||||||
|
Value operator/(const Value &rhs) const;
|
||||||
|
Value operator%(const Value &rhs) const;
|
||||||
|
Value operator&(const Value &rhs) const;
|
||||||
|
Value operator^(const Value &rhs) const;
|
||||||
|
Value operator|(const Value &rhs) const;
|
||||||
|
Value operator==(const Value &rhs) const;
|
||||||
|
Value operator!=(const Value &rhs) const;
|
||||||
|
Value operator<(const Value &rhs) const;
|
||||||
|
Value operator>(const Value &rhs) const;
|
||||||
|
Value operator<=(const Value &rhs) const;
|
||||||
|
Value operator>=(const Value &rhs) const;
|
||||||
};
|
};
|
@ -20,10 +20,12 @@ Value BuiltinFunctions::print(Context& cxt, Args& args) {
|
|||||||
std::cout << "false" << '\t';
|
std::cout << "false" << '\t';
|
||||||
} else if (var.isNil()) {
|
} else if (var.isNil()) {
|
||||||
std::cout << "nil" << '\t';
|
std::cout << "nil" << '\t';
|
||||||
|
} else if (var.isFloat()) {
|
||||||
|
std::cout << var.getFloat(cxt) << std::endl;
|
||||||
} else {
|
} else {
|
||||||
cxt.error("Attempt to print unsupported type");
|
cxt.error("Attempt to print unsupported type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
return Nil();
|
return Value(cxt, Nil());
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user