Browse Source

Implement some more math functions for the hell of it

master
Jennie Maes 5 years ago
parent
commit
9a4053c627
3 changed files with 78 additions and 0 deletions
  1. +72
    -0
      builtins.cc
  2. +4
    -0
      builtins.hh
  3. +2
    -0
      lisp.cc

+ 72
- 0
builtins.cc View File

@ -1,5 +1,6 @@
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include "builtins.hh"
@ -14,6 +15,7 @@ FunctionTable builtin_functions = FunctionTable({
, {"not", negate}
, {"atomp", atomp}
, {"listp", listp}
, {"flatp", flatp}
, {"null", null}
, {"eq", equal}
, {"ne", notequal}
@ -22,6 +24,9 @@ FunctionTable builtin_functions = FunctionTable({
, {"mult", mult}
, {"div", divide}
, {"mod", modulo}
, {"sqrt", sqroot}
, {"expt", power}
, {"log", logarithm}
, {"'", quote}
, {"=", equal}
, {"/=", notequal}
@ -34,6 +39,7 @@ FunctionTable builtin_functions = FunctionTable({
, {"*", mult}
, {"/", divide}
, {"%", modulo}
, {"**", power}
});
ParseTree *car(ParseTree *expr) {
@ -143,6 +149,14 @@ ParseTree *listp(ParseTree *expr) {
}
}
ParseTree *flatp(ParseTree *expr) {
if (expr->list.size() == 1) {
return new ParseTree(expr->list[0]->isflat());
} else {
return new ParseTree(AST::invalid_funccall);
}
}
ParseTree *null(ParseTree *expr) {
if (expr->list.size() == 1) {
return new ParseTree(expr->list[0]->isnil());
@ -419,3 +433,61 @@ ParseTree *modulo(ParseTree *expr) {
return new ParseTree(AST::invalid_funccall);
}
}
ParseTree *sqroot(ParseTree *expr) {
if (expr->list.size() == 1) {
char *end;
const char *arg = expr->list[0]->atom.c_str();
double num = std::strtod(arg, &end);
if ((num == 0 && end == arg)) {
return new ParseTree(AST::invalid_funccall);
}
return new ParseTree(sqrt(num));
} else {
return new ParseTree(AST::invalid_funccall);
}
}
ParseTree *power(ParseTree *expr) {
if (expr->list.size() == 2) {
char *end1, *end2;
const char *arg1 = expr->list[0]->atom.c_str();
const char *arg2 = expr->list[1]->atom.c_str();
double base = std::strtod(arg1, &end1);
double exp = std::strtod(arg2, &end2);
if ((base == 0 && end1 == arg1) || (exp == 0 && end2 == arg2)) {
return new ParseTree(AST::invalid_funccall);
}
return new ParseTree(pow(base, exp));
} else {
return new ParseTree(AST::invalid_funccall);
}
}
ParseTree *logarithm(ParseTree *expr) {
if (expr->list.size() == 2) {
char *end1, *end2;
const char *arg1 = expr->list[0]->atom.c_str();
const char *arg2 = expr->list[1]->atom.c_str();
double base = std::strtod(arg1, &end1);
double num = std::strtod(arg2, &end2);
if ((base == 0 && end1 == arg1) || (num == 0 && end2 == arg2) || log(base) == 0) {
return new ParseTree(AST::invalid_funccall);
}
return new ParseTree(log(num) / log(base));
} else {
return new ParseTree(AST::invalid_funccall);
}
}

+ 4
- 0
builtins.hh View File

@ -19,6 +19,7 @@ ParseTree *append(ParseTree *expr);
ParseTree *negate(ParseTree *expr);
ParseTree *atomp(ParseTree *expr);
ParseTree *listp(ParseTree *expr);
ParseTree *flatp(ParseTree *expr);
ParseTree *null(ParseTree *expr);
ParseTree *equal(ParseTree *expr);
ParseTree *notequal(ParseTree *expr);
@ -31,3 +32,6 @@ ParseTree *sub(ParseTree *expr);
ParseTree *mult(ParseTree *expr);
ParseTree *divide(ParseTree *expr);
ParseTree *modulo(ParseTree *expr);
ParseTree *sqroot(ParseTree *expr);
ParseTree *power(ParseTree *expr);
ParseTree *logarithm(ParseTree *expr);

+ 2
- 0
lisp.cc View File

@ -12,6 +12,7 @@ int main() {
// Some example expressions defined in the global scope
ParseTree *pi = AST::read("3.141592653589793");
ParseTree *tau = AST::read("6.283185307179586");
ParseTree *exp = AST::read("2.718281828459045");
ParseTree *dbl = AST::read("(lambda (x) (+ x x))");
ParseTree *even = AST::read("(lambda (n) (= 0 (% n 2)))");
ParseTree *conj = AST::read("(lambda (a b) (if a (if b t nil) nil))");
@ -20,6 +21,7 @@ int main() {
AST::SymbolTable *global_scope = new AST::SymbolTable(nullptr, {
{"pi", pi}
, {"tau", tau}
, {"e", exp}
, {"double", dbl}
, {"even", even}
, {"and", conj}


Loading…
Cancel
Save