Skip to content

Commit

Permalink
Refactor Default implementation for Environment
Browse files Browse the repository at this point in the history
  • Loading branch information
cowuake committed Apr 17, 2024
1 parent ec16018 commit e2a804d
Showing 1 changed file with 98 additions and 110 deletions.
208 changes: 98 additions & 110 deletions schemius/src/core/environment.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::collections::HashMap;

use lazy_static::lazy_static;

use super::{
accessor::*,
builtins::*,
Expand Down Expand Up @@ -80,119 +82,105 @@ impl SchemeEnvironment for Environment {
}
}

macro_rules! bind_numerical_constants {
($env:expr, { $($name:expr => $value:ident)* }) => {
$(
$env.define($name, &SExpr::Number(NumericalConstant::$value)).unwrap();
)*
};
}

macro_rules! bind_primitives {
($env:expr, { $($name:expr => $value:ident)* }) => {
$(
$env.define($name, &SExpr::Procedure(Procedure::Primitive(Primitive::$value))).unwrap();
)*
};
}

macro_rules! bind_special_forms {
($env:expr, { $($name:expr => $value:ident)* }) => {
$(
$env.define($name, &SExpr::Procedure(Procedure::SpecialForm(SpecialForm::$value))).unwrap();
)*
};
}

impl Default for Environment {
fn default() -> Self {
let mut new_env = Environment::new();
let default_table: HashMap<String, SExpr> = HashMap::from([
(String::from("π"), SExpr::Number(NumericalConstant::PI)),
(String::from("pi"), SExpr::Number(NumericalConstant::PI)),
(String::from("avogadro"), SExpr::Number(NumericalConstant::AVOGADRO)),
(String::from("boltzmann"), SExpr::Number(NumericalConstant::BOLTZMANN)),
(String::from("e"), SExpr::Number(NumericalConstant::EULER)),
(String::from("euler"), SExpr::Number(NumericalConstant::EULER)),
(String::from("golden-ratio"), SExpr::Number(NumericalConstant::GOLDEN_RATIO)),
(
String::from("gravitational-constant"),
SExpr::Number(NumericalConstant::GRAVITATIONAL_CONSTANT),
),
(String::from("h"), SExpr::Number(NumericalConstant::PLANCK)),
(String::from("planck"), SExpr::Number(NumericalConstant::PLANCK)),
(String::from("exit"), SExpr::Procedure(Procedure::Primitive(Primitive::EXIT))),
(String::from("+"), SExpr::Procedure(Procedure::Primitive(Primitive::SUM))),
(String::from("-"), SExpr::Procedure(Procedure::Primitive(Primitive::DIFF))),
(String::from("*"), SExpr::Procedure(Procedure::Primitive(Primitive::PROD))),
(String::from("/"), SExpr::Procedure(Procedure::Primitive(Primitive::QUOT))),
(String::from("="), SExpr::Procedure(Procedure::Primitive(Primitive::EQUAL))),
(String::from(">"), SExpr::Procedure(Procedure::Primitive(Primitive::GT))),
(String::from(">="), SExpr::Procedure(Procedure::Primitive(Primitive::GE))),
(String::from("<"), SExpr::Procedure(Procedure::Primitive(Primitive::LT))),
(String::from("<="), SExpr::Procedure(Procedure::Primitive(Primitive::LE))),
(String::from("'"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::QUOTE))),
(String::from("quote"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::QUOTE))),
(String::from("`"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::QUASIQUOTE))),
(
String::from("quasiquote"),
SExpr::Procedure(Procedure::SpecialForm(SpecialForm::QUASIQUOTE)),
),
(String::from("λ"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::LAMBDA))),
(String::from("lambda"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::LAMBDA))),
(String::from("let"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::LET))),
(String::from("let*"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::LET_STAR))),
(String::from("eval"), SExpr::Procedure(Procedure::Primitive(Primitive::EVAL))),
(String::from("apply"), SExpr::Procedure(Procedure::Primitive(Primitive::APPLY))),
(String::from("car"), SExpr::Procedure(Procedure::Primitive(Primitive::CAR))),
(String::from("cdr"), SExpr::Procedure(Procedure::Primitive(Primitive::CDR))),
(String::from("define"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::DEFINE))),
(String::from("set!"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::SET))),
(String::from("cons"), SExpr::Procedure(Procedure::Primitive(Primitive::CONS))),
(String::from("list"), SExpr::Procedure(Procedure::Primitive(Primitive::LIST))),
(String::from("set-car!"), SExpr::Procedure(Procedure::Primitive(Primitive::SET_CAR))),
(String::from("begin"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::BEGIN))),
(String::from("if"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::IF))),
(String::from("not"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::NOT))),
(String::from("cond"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::COND))),
(String::from("display"), SExpr::Procedure(Procedure::Primitive(Primitive::DISPLAY))),
(String::from("char?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_CHAR))),
(String::from("symbol?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_SYMBOL))),
(String::from("string?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_STRING))),
(
String::from("boolean?"),
SExpr::Procedure(Procedure::Primitive(Primitive::IS_BOOLEAN)),
),
(String::from("number?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_NUMBER))),
(String::from("exact?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_EXACT))),
(String::from("list?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_LIST))),
(String::from("pair?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_PAIR))),
(String::from("vector?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_VECTOR))),
(
String::from("procedure?"),
SExpr::Procedure(Procedure::Primitive(Primitive::IS_PROCEDURE)),
),
(String::from("null?"), SExpr::Procedure(Procedure::Primitive(Primitive::IS_NULL))),
(String::from("time"), SExpr::Procedure(Procedure::SpecialForm(SpecialForm::TIME))),
(
String::from("environment-bindings"),
SExpr::Procedure(Procedure::Primitive(Primitive::ENVIRONMENT_BINDINGS)),
),
(String::from("string"), SExpr::Procedure(Procedure::Primitive(Primitive::STRING))),
(
String::from("make-string"),
SExpr::Procedure(Procedure::Primitive(Primitive::MAKE_STRING)),
),
(
String::from("string-append"),
SExpr::Procedure(Procedure::Primitive(Primitive::STRING_APPEND)),
),
(
String::from("string-length"),
SExpr::Procedure(Procedure::Primitive(Primitive::STRING_LENGTH)),
),
(
String::from("string-ref"),
SExpr::Procedure(Procedure::Primitive(Primitive::STRING_REF)),
),
(
String::from("string-set!"),
SExpr::Procedure(Procedure::Primitive(Primitive::STRING_SET)),
),
(
String::from("string-upcase"),
SExpr::Procedure(Procedure::Primitive(Primitive::STRING_UPCASE)),
),
(
String::from("string-downcase"),
SExpr::Procedure(Procedure::Primitive(Primitive::STRING_DOWNCASE)),
),
(String::from("flatten"), SExpr::Procedure(Procedure::Primitive(Primitive::FLATTEN))),
(
String::from("unflatten"),
SExpr::Procedure(Procedure::Primitive(Primitive::UNFLATTEN)),
),
]);

for (key, value) in default_table.iter() {
new_env.define(key, value).unwrap();
}
bind_numerical_constants!(new_env, {
"π" => PI
"pi" => PI
"avogadro" => AVOGADRO
"boltzmann" => BOLTZMANN
"e" => EULER
"euler" => EULER
"golden-ratio" => GOLDEN_RATIO
"gravitational-constant" => GRAVITATIONAL_CONSTANT
"h" => PLANCK
"planck" => PLANCK
});
bind_primitives!(new_env, {
"+" => SUM
"-" => DIFF
"*" => PROD
"/" => QUOT
"=" => EQUAL
">" => GT
">=" => GE
"<" => LT
"<=" => LE
"exit" => EXIT
"eval" => EVAL
"apply" => APPLY
"car" => CAR
"cdr" => CDR
"cons" => CONS
"list" => LIST
"set-car!" => SET_CAR
"display" => DISPLAY
"char?" => IS_CHAR
"symbol?" => IS_SYMBOL
"string?" => IS_STRING
"boolean?" => IS_BOOLEAN
"number?" => IS_NUMBER
"exact?" => IS_EXACT
"list?" => IS_LIST
"pair?" => IS_PAIR
"vector?" => IS_VECTOR
"procedure?" => IS_PROCEDURE
"null?" => IS_NULL
"environment-bindings" => ENVIRONMENT_BINDINGS
"string" => STRING
"make-string" => MAKE_STRING
"string-append" => STRING_APPEND
"string-length" => STRING_LENGTH
"string-ref" => STRING_REF
"string-set!" => STRING_SET
"string-upcase" => STRING_UPCASE
"string-downcase" => STRING_DOWNCASE
"flatten" => FLATTEN
"unflatten" => UNFLATTEN
});
bind_special_forms!(new_env,
{
"'" => QUOTE
"quote" => QUOTE
"`" => QUASIQUOTE
"quasiquote" => QUASIQUOTE
"λ" => LAMBDA
"lambda" => LAMBDA
"let" => LET
"let*" => LET_STAR
"define" => DEFINE
"set!" => SET
"if" => IF
"time" => TIME
"begin" => BEGIN
"not" => NOT
"cond" => COND
});

new_env
}
Expand Down

0 comments on commit e2a804d

Please sign in to comment.