#t and #f added to language, datetime fixes

This commit is contained in:
2021-10-12 13:26:38 +02:00
parent adca8a452b
commit 4359012190
13 changed files with 90 additions and 55 deletions

44
ml.cpp
View File

@@ -51,6 +51,7 @@
#define INT_TYPE "int"
#define FLOAT_TYPE "float"
#define NIL_TYPE "nil"
#define TRUE_TYPE "#t"
#define FUNCTION_TYPE "function"
#define ATOM_TYPE "atom"
#define QUOTE_TYPE "quote"
@@ -70,11 +71,8 @@ MlValue::MlValue(long i) : type(INT) { stack_data.i = i; }
MlValue::MlValue(double f) : type(FLOAT) { stack_data.f = f; }
MlValue::MlValue(bool b) {
if (b) {
type = INT;
stack_data.i = 1;
}
else { type = NIL; }
if (b) type = TRUE;
else type = NIL;
}
MlValue::MlValue(const std::vector<MlValue> &list) : type(LIST), list(list) {}
@@ -186,7 +184,7 @@ bool MlValue::is_list() const {
}
bool MlValue::as_bool() const {
return type != NIL && *this != MlValue(0l); // TODO remove 0 as false
return type != NIL;
}
long MlValue::as_int() const {
@@ -313,6 +311,8 @@ bool MlValue::operator==(MlValue other) const {
return list[0] == other.list[0];
case NIL:
return other.type == NIL;
case TRUE:
return other.type == TRUE;
default:
return true;
}
@@ -515,6 +515,8 @@ std::string MlValue::get_type_name() const {
return FUNCTION_TYPE;
case NIL:
return NIL_TYPE;
case TRUE:
return TRUE_TYPE;
default:
// This should never be reached.
throw MlError(*this, MlEnvironment(), INTERNAL_ERROR);
@@ -550,6 +552,8 @@ std::string MlValue::display() const {
return "<" + str + " at " + std::to_string(long(stack_data.b)) + ">";
case NIL:
return "nil";
case TRUE:
return "#t";
default:
// This should never be reached.
throw MlError(*this, MlEnvironment(), INTERNAL_ERROR);
@@ -589,6 +593,8 @@ std::string MlValue::debug() const {
return "<" + str + " at " + std::to_string(long(stack_data.b)) + ">";
case NIL:
return "nil";
case TRUE:
return "#t";
default:
// This should never be reached.
throw MlError(*this, MlEnvironment(), INTERNAL_ERROR);
@@ -840,6 +846,10 @@ MlValue parse(std::string &s, int &ptr) {
skip_whitespace(s, ptr);
if (x == "nil")
return MlValue::nil();
else if(x == "#f")
return MlValue(false);
else if (x == "#t")
return MlValue(true);
else
return MlValue::atom(x);
@@ -872,6 +882,9 @@ std::vector<MlValue> parse(std::string s) {
MlValue run(const std::string &code, MlEnvironment &env) {
// Parse the code
std::vector<MlValue> parsed = parse(code);
if (parsed.empty())
return MlValue::nil();
// Iterate over the expressions and evaluate them
// in this environment.
for (size_t i = 0; i < parsed.size() - 1; i++)
@@ -1033,7 +1046,7 @@ MlValue do_and(std::vector<MlValue> args, MlEnvironment &env) {
for (size_t i = 0; i < args.size(); i++)
if (!args[i].eval(env).as_bool()) return MlValue::nil();
return MlValue{1l};
return MlValue{true};
}
// Evaluate logical or on a list of expressions (SPECIAL FORM)
@@ -1042,7 +1055,7 @@ MlValue do_or(std::vector<MlValue> args, MlEnvironment &env) {
throw MlError(MlValue("or", do_or), env, TOO_FEW_ARGS);
for (size_t i = 0; i < args.size(); i++)
if (args[i].eval(env).as_bool()) return MlValue{1l};
if (args[i].eval(env).as_bool()) return MlValue{true};
return MlValue::nil();
}
@@ -1153,7 +1166,7 @@ MlValue write_file(std::vector<MlValue> args, MlEnvironment &env) {
if (args.size() != 2)
throw MlError(MlValue("write-file", write_file), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
return MlValue((long) write_file_contents(args[0].as_string(), args[1].as_string()));
return MlValue(write_file_contents(args[0].as_string(), args[1].as_string()));
}
// Read URL to (code content)
@@ -1210,6 +1223,16 @@ MlValue get_universal_time(std::vector<MlValue> args, MlEnvironment &env) {
return MlValue(now());
}
// Get offsets in secs between local timezone and gmt
MlValue get_localtime_offset(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
if (args.size() != 0)
throw MlError(MlValue("get-localtime-offset", get_localtime_offset), env, TOO_MANY_ARGS);
return MlValue(get_gmt_localtime_offset());
}
// Converts date to formated string.
MlValue date_to_str(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
@@ -1624,7 +1647,7 @@ MlValue string_regex(std::vector<MlValue> args, MlEnvironment &env) {
if (args.size() != 2) // if (args.size() < 2 || args.size() > 3)
throw MlError(MlValue("string-regex?", string_regex), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
return MlValue((long) regexp_search(args[0].as_string(), args[1].as_string()));
return MlValue(regexp_search(args[0].as_string(), args[1].as_string()));
}
// Splits string by regexp and returns list containing splited parts
@@ -2042,6 +2065,7 @@ MlValue MlEnvironment::get(const std::string &name) const {
// Datetime operations
if (name == "get-universal-time") return MlValue("get-universal-time", builtin::get_universal_time);
if (name == "get-localtime-offset") return MlValue("get-localtime-offset", builtin::get_localtime_offset);
if (name == "date-to-str") return MlValue("date-to-str", builtin::date_to_str);
if (name == "str-to-date") return MlValue("str-to-date", builtin::str_to_date);
if (name == "date-add") return MlValue("date-add", builtin::date_add);