mlisp/ml.h

210 lines
5.3 KiB
C++

#pragma once
// Comment this define out to drop support for standard library functions.
// This allows the program to run without a runtime.
#define USE_STD
#include <map>
#include <string>
#include <vector>
#include <sstream>
#include <exception>
// // Forward declaration for MlEnvironment class definition
class MlValue;
// An instance of a function's scope.
class MlEnvironment {
public:
// Default constructor
MlEnvironment() : parent_scope(NULL) {}
// Does this environment, or its parent environment,
// have this atom in scope?
// This is only used to determine which atoms to capture when
// creating a lambda function.
bool has(std::string name) const;
// Get the value associated with this name in this scope
MlValue get(std::string name) const;
// Set the value associated with this name in this scope
void set(std::string name, MlValue value);
void combine(MlEnvironment const &other);
void set_parent_scope(MlEnvironment *parent) {
parent_scope = parent;
}
// Output this scope in readable form to a stream.
friend std::ostream &operator<<(std::ostream &os, MlEnvironment const &v);
private:
// The definitions in the scope.
std::map<std::string, MlValue> defs;
MlEnvironment *parent_scope;
};
// An exception thrown by the lisp
class MlError {
public:
// Create an error with the value that caused the error,
// the scope where the error was found, and the message.
MlError(const MlValue &v, MlEnvironment const &env, const char *msg);
// Copy constructor is needed to prevent double frees
MlError(MlError const &other);
~MlError();
// Get the printable error description.
std::string description();
private:
MlValue *cause;
MlEnvironment env;
const char *msg;
};
// The type for a builtin function, which takes a list of values,
// and the environment to run the function in.
typedef MlValue (*Builtin)(std::vector<MlValue>, MlEnvironment &);
class MlValue {
public:
// Constructs a unit value
MlValue();
// Constructs an integer
MlValue(int i);
// Constructs a floating point value
MlValue(double f);
// Constructs a list
MlValue(const std::vector<MlValue> &list);
// Construct a quoted value
static MlValue quote(const MlValue& quoted);
// Construct an atom
static MlValue atom(const std::string &s);
// Construct a string
static MlValue string(const std::string &s);
// Construct a lambda function
MlValue(const std::vector<MlValue> &params, MlValue ret, MlEnvironment const &env);
// Construct a builtin function
MlValue(const std::string &name, Builtin b);
std::vector<std::string> get_used_atoms();
// Is this a builtin function?
bool is_builtin();
// Apply this as a function to a list of arguments in a given environment.
MlValue apply(std::vector<MlValue> args, MlEnvironment &env);
// Evaluate this value as lisp code.
MlValue eval(MlEnvironment &env);
bool is_number() const;
// Get the "truthy" boolean value of this value.
bool as_bool() const;
// Get this item's integer value
int as_int() const;
// Get this item's floating point value
double as_float() const;
// Get this item's string value
std::string as_string() const;
// Get this item's atom value
std::string as_atom() const;
// Get this item's list value
std::vector<MlValue> as_list() const;
// Push an item to the end of this list
void push(MlValue val);
// Push an item from the end of this list
MlValue pop();
// Cast this to an integer value
MlValue cast_to_int() const;
// Cast this to a floating point value
MlValue cast_to_float() const;
bool operator==(MlValue other) const;
bool operator!=(const MlValue &other) const;
bool operator>=(const MlValue &other) const;
bool operator<=(const MlValue &other) const;
bool operator>(const MlValue &other) const;
bool operator<(const MlValue &other) const;
// This function adds two lisp values, and returns the lisp value result.
MlValue operator+(const MlValue &other) const;
// This function subtracts two lisp values, and returns the lisp value result.
MlValue operator-(const MlValue &other) const;
// This function multiplies two lisp values, and returns the lisp value result.
MlValue operator*(const MlValue &other) const;
// This function divides two lisp values, and returns the lisp value result.
MlValue operator/(const MlValue &other) const;
// This function finds the remainder of two lisp values, and returns the lisp value result.
MlValue operator%(const MlValue &other) const;
// Get the name of the type of this value
std::string get_type_name();
std::string display() const;
std::string debug() const;
friend std::ostream &operator<<(std::ostream &os, MlValue const &v);
private:
enum {
QUOTE,
ATOM,
INT,
FLOAT,
LIST,
STRING,
LAMBDA,
BUILTIN,
UNIT
} type;
union {
int i;
double f;
Builtin b;
} stack_data;
std::string str;
std::vector<MlValue> list;
MlEnvironment lambda_scope;
};