Permalink
Browse files

ch4

  • Loading branch information...
1 parent d470443 commit d740efd1dce991eddb2ed007faa2a2bd6c058db8 @flaming0 committed Sep 1, 2012
View
35 ch4/interpreter-cpp/schint/environment.cpp
@@ -7,11 +7,46 @@
#include "environment.h"
+#include "expression.h"
+
Environment::Environment(Environment *baseEnv)
: m_baseEnvironment(baseEnv)
{
}
+shared_ptr<Expression> Environment::lookupVariableValue(const Var var) const
+{
+ if (m_frame.find(var) == m_frame.end())
+ {
+ if (m_baseEnvironment)
+ return m_baseEnvironment->lookupVariableValue(var);
+ }
+ else
+ return m_frame.find(var)->second;
+
+ return nullexpr;
+}
+
+void Environment::addBindingForFrame(const Var var, const Val val)
+{
+ m_frame[var] = val;
+}
+
+Environment *Environment::extendEnvironment(std::list<Var> vars, std::list<Val> vals)
+{
+ if (vars.size() != vals.size())
+ throw std::runtime_error("Sizes doesn't match.");
+
+ Environment *newEnv = new Environment(this);
+
+ auto var = vars.begin();
+ auto val = vals.begin();
+ for ( ; var != vars.end(); var++, val++)
+ newEnv->addBindingForFrame(*var, *val);
+
+ return newEnv;
+}
+
Environment *globalEnvironment()
{
static Environment globalEnv(nullptr);
View
26 ch4/interpreter-cpp/schint/environment.h
@@ -8,19 +8,37 @@
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
-#include <map>
-#include <string>
+#include "utils.h"
+#include "expression.h"
-class Evaluable;
+// WHY std::less<VariableExpression> doesn't work?????
+struct compare
+{
+ bool operator() (const shared_ptr<VariableExpression> &a, const shared_ptr<VariableExpression> &b) const
+ {
+ return *a < *b;
+ }
+};
class Environment
{
Environment *m_baseEnvironment;
- std::map<std::string, Evaluable *> m_frame;
+ typedef shared_ptr<VariableExpression> Var;
+ typedef shared_ptr<Expression> Val;
+
+ std::map<Var, Val, compare> m_frame;
public:
Environment(Environment *baseEnv);
+
+ shared_ptr<Expression> lookupVariableValue(const Var var) const;
+ void addBindingForFrame(const Var var, const Val val);
+
+ Environment *extendEnvironment(std::list<Var> vars, std::list<Val> vals);
+
+private:
+// static boost::function
};
Environment *globalEnvironment();
View
13 ch4/interpreter-cpp/schint/eval.cpp
@@ -1,13 +0,0 @@
-/*
- * eval.cpp
- *
- * Author: flamingo
- * E-mail: epiforce57@gmail.com
- */
-
-#include "eval.h"
-
-Evaluable *eval(Evaluable *exp, Environment *env)
-{
- return exp->eval(env);
-}
View
26 ch4/interpreter-cpp/schint/eval.h
@@ -1,26 +0,0 @@
-/*
- * eval.h
- *
- * Author: flamingo
- * E-mail: epiforce57@gmail.com
- */
-
-#ifndef EVAL_H
-#define EVAL_H
-
-#include <string>
-
-class Environment;
-
-class Evaluable
-{
-public:
- Evaluable() { }
- virtual ~Evaluable() { }
-
- virtual Evaluable *eval(Environment *env) = 0;
-};
-
-Evaluable *eval(Evaluable *exp, Environment *env);
-
-#endif // EVAL_H
View
103 ch4/interpreter-cpp/schint/expression.cpp
@@ -6,46 +6,94 @@
*/
#include "expression.h"
+
#include "schemelist.h"
+#include "environment.h"
-#include <stdexcept>
+/*
+;; lambdas
+(define (lambda? exp) (tagged-list? exp 'lambda))
+(define (lambda-parameters exp) (cadr exp))
+(define (lambda-body exp) (cddr exp))
+(define (make-lambda parameters body)
+ (cons 'lambda (cons parameters body)))
+ */
-Expression::Expression()
-{
-}
+/*
+(define (analyze-lambda exp)
+ (let ((vars (lambda-parameters exp))
+ (bproc (analyze-sequence (lambda-body exp))))
+ (lambda (env) (make-procedure vars bproc env))))
+
+(define (analyze-sequence exps)
+ (define (sequentially proc1 proc2)
+ (lambda (env) (proc1 env) (proc2 env)))
+ (define (loop first-proc rest-procs)
+ (if (null? rest-procs)
+ first-proc ;; only one combination
+ (loop (sequentially first-proc (car rest-procs)) ;; otherwise, loop through combinations
+ (cdr rest-procs))))
+ (let ((procs (map analyze exps)))
+ (if (null? procs)
+ (error "Empty sequence -- ANALYZE"))
+ (loop (car procs) (cdr procs))))
+ */
-//Expression::ExpressionType Expression::typeBySExpression(const std::string &sexpr)
-//{
-// std::string tag = sexpr.substr(1, sexpr.find(' ') - 1);
+/*
+(define (make-procedure parameters body env)
+ (list 'procedure parameters body env))
+(define (compound-procedure? p)
+ (tagged-list? p 'procedure))
+(define (procedure-parameters p) (cadr p))
+(define (procedure-body p) (caddr p))
+(define (procedure-environment p) (cadddr p))
+*/
-// throw std::runtime_error(std::string("Unknown expression type ") + tag + " .");
-//}
+shared_ptr<DefinitionExpression> analyzeDefinition(const SchemeList &str)
+{
+ SchemeList defVarStr = str.car();
-Expression *Expression::analyzeExpression(const std::string &str)
+ return make_shared<DefinitionExpression>(make_shared<VariableExpression>(defVarStr),
+ Expression::analyzeExpression(str.cdr()));
+}
+
+Expression::Expression()
+{
+}
+
+shared_ptr<Expression> Expression::analyzeExpression(const std::string &str)
{
SchemeList lst(str);
- std::string tag = lst.car();
+ SchemeList tag = lst.car();
if (tag == "\'")
- return nullptr;
+ return nullexpr;
if (tag == "set!")
- return nullptr;
+ return nullexpr;
if (tag == "define")
- return new DefinitionExpression(0 /* analyze (rest) */, 0);
+ return analyzeDefinition(lst.cdr());
if (tag == "if")
- return nullptr;
+ return nullexpr;
if (tag == "lambda")
- return nullptr;
+ return nullexpr;
if (tag == "begin")
- return nullptr;
+ return nullexpr;
+ if (isDouble(tag))
+ return make_shared<NumberExpression<double> >(toDouble(tag));
+ if (isInt(tag))
+ return make_shared<NumberExpression<int> >(toInt(tag));
+ if (isLispString(tag))
+ return nullexpr;
+
+// std::isxdigit
// if (tag == number);
// if (tag == symbol);
// if (tag == pair);
- throw std::runtime_error(std::string("Unknown expression type ") + tag + " .");
+// throw std::runtime_error(std::string("Unknown expression type ") + tag + " .");
// ExpressionType exprType = typeBySExpression(expr);
// new DefinitionExpr(cadr(expr), createExpression(caddr(expr)));
@@ -63,7 +111,7 @@ Expression *Expression::analyzeExpression(const std::string &str)
// if (exprType == Begin)
// return new BeginExpression("");
-// return nullptr;
+ return nullexpr;
}
Expression *Expression::car() const
@@ -74,19 +122,23 @@ Expression *Expression::cdr() const
{
}
-/*
-VariableExpression::VariableExpression(const std::string &value)
+
+VariableExpression::VariableExpression(const std::string &varSymbol)
+ : m_symbol(varSymbol)
{
}
-Expression *VariableExpression::eval(Environment *env)
+shared_ptr<Expression> VariableExpression::eval(Environment *env)
{
+// auto var = make_shared<VariableExpression>(this);
+// return env->lookupVariableValue(var);
+// env->lookupVariableValue
}
std::string VariableExpression::toString() const
{
}
-
+/*
QuotedExpression::QuotedExpression(const std::string &value)
{
}
@@ -111,11 +163,12 @@ std::string AssignmentExpression::toString() const
{
}*/
-DefinitionExpression::DefinitionExpression(Expression *variable, Expression *value)
+DefinitionExpression::DefinitionExpression(shared_ptr<VariableExpression> variable, shared_ptr<Expression> value)
+ : m_var(variable), m_value(value)
{
}
-Expression *DefinitionExpression::eval(Environment *env)
+shared_ptr<Expression> DefinitionExpression::eval(Environment *env)
{
}
View
86 ch4/interpreter-cpp/schint/expression.h
@@ -8,59 +8,66 @@
#ifndef EXPRESSION_H
#define EXPRESSION_H
-#include "eval.h"
+#include "utils.h"
-class Expression : public Evaluable
+class Environment;
+
+class Expression
{
protected:
Expression();
public:
+ virtual ~Expression() { }
// maybe analyze
- static Expression *analyzeExpression(const std::string &str);
+ static shared_ptr<Expression> analyzeExpression(const std::string &str);
+ virtual shared_ptr<Expression> eval(Environment *env) = 0;
virtual std::string toString() const = 0;
Expression *car() const;
Expression *cdr() const;
};
-///**
-// * Number.
-// */
-//template<typename T>
-//class NumberExpression : public Expression
-//{
-// T m_value;
-//public:
-// NumberExpression(T value)
-// {
-// m_value = value;
-// }
-
-// virtual std::string toString() const
-// {
-// return std::to_string(m_value);
-// }
-
-// Evaluable *eval(Environment *env)
-// {
-// return nullptr;
-// }
-//};
+/**
+ * Number.
+ */
+template<typename T>
+class NumberExpression : public Expression
+{
+ T m_value;
+public:
+ NumberExpression(T value)
+ {
+ m_value = value;
+ }
+
+ virtual std::string toString() const
+ {
+ return std::to_string(m_value);
+ }
+
+ shared_ptr<Expression> eval(Environment *env)
+ {
+ return nullexpr;
+ }
+};
-///**
-// * Variable.
-// */
-//class VariableExpression : public Expression
-//{
-//public:
-// VariableExpression(const std::string &value);
+/**
+ * Variable.
+ */
+class VariableExpression : public Expression
+{
+ std::string m_symbol;
+public:
+ VariableExpression(const std::string &varSymbol);
-// virtual Expression *eval(Environment *env);
+ virtual shared_ptr<Expression> eval(Environment *env);
-// virtual std::string toString() const;
-//};
+ virtual std::string toString() const;
+
+ bool operator< (const VariableExpression &other) const { return m_symbol < other.m_symbol; }
+};
///**
// * Quotation.
@@ -93,10 +100,13 @@ class Expression : public Evaluable
*/
class DefinitionExpression : public Expression
{
+ shared_ptr<VariableExpression> m_var;
+ shared_ptr<Expression> m_value;
+
public:
- DefinitionExpression(Expression *variable, Expression *value);
+ DefinitionExpression(shared_ptr<VariableExpression> variable, shared_ptr<Expression> value);
- virtual Expression *eval(Environment *env);
+ virtual shared_ptr<Expression> eval(Environment *env);
virtual std::string toString() const;
};
View
11 ch4/interpreter-cpp/schint/main.cpp
@@ -1,7 +1,4 @@
-#include <iostream>
-#include <string>
-#include <stdexcept>
-
+#include "utils.h"
#include "expression.h"
#include "environment.h"
@@ -22,7 +19,7 @@ int main() try
bool exit = false;
std::string input;
- Expression *exp;
+ shared_ptr<Expression> exp;
while (!exit)
{
@@ -32,11 +29,11 @@ int main() try
// Expression *output = static_cast<Expression *>(eval(exp, globalEnvironment()));
// promtOutput(output);
- delete exp;
+// delete exp;
// delete output;
}
- delete exp;
+// delete exp;
return 0;
}
View
10 ch4/interpreter-cpp/schint/schemelist.cpp
@@ -6,7 +6,6 @@
*/
#include "schemelist.h"
-#include <stdexcept>
void SchemeList::eraseWhiteSpaces()
{
@@ -34,7 +33,7 @@ SchemeList::SchemeList(const std::string &expr)
{
eraseWhiteSpaces();
- if (m_listString.empty() || m_listString[0] != '(' || m_listString[m_listString.size() - 1] != ')')
+ if (m_listString.empty()/* || m_listString[0] != '(' || m_listString[m_listString.size() - 1] != ')'*/)
throw std::runtime_error("Bad expression.");
}
@@ -43,7 +42,12 @@ SchemeList SchemeList::car() const
if (m_listString == "()" || m_listString.at(0) != '(')
throw std::runtime_error("Unable to get car.");
- return SchemeList(m_listString.substr(1, m_listString.find(' ') - 1));
+ if (m_listString.find(' ') != std::string::npos)
+ return SchemeList(m_listString.substr(1, m_listString.find(' ') - 1));
+ else if (m_listString.find(')') != std::string::npos)
+ return SchemeList(m_listString.substr(1, m_listString.find(')') - 1));
+ else
+ throw std::runtime_error("Unable to get car.");
}
SchemeList SchemeList::cdr() const
View
3 ch4/interpreter-cpp/schint/schemelist.h
@@ -8,7 +8,7 @@
#ifndef SCHEMELIST_H
#define SCHEMELIST_H
-#include <string>
+#include "utils.h"
/**
* Lisp list string representation.
@@ -26,6 +26,7 @@ class SchemeList
SchemeList cdr() const;
operator std::string() { return m_listString; }
+ bool operator== (const std::string &str) const { return m_listString == str; }
};
#endif // SCHEMELIST_H
View
5 ch4/interpreter-cpp/schint/schint.pro
@@ -5,14 +5,13 @@ CONFIG -= qt
QMAKE_CXXFLAGS += -std=gnu++0x
SOURCES += main.cpp \
- eval.cpp \
environment.cpp \
expression.cpp \
schemelist.cpp
HEADERS += \
- eval.h \
environment.h \
expression.h \
- schemelist.h
+ schemelist.h \
+ utils.h
View
72 ch4/interpreter-cpp/schint/utils.h
@@ -0,0 +1,72 @@
+/*
+ * utils.h
+ *
+ * Author: flamingo
+ * E-mail: epiforce57@gmail.com
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <map>
+#include <stdexcept>
+#include <algorithm>
+#include <functional>
+#include <list>
+
+#include <boost/smart_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/function.hpp>
+
+#define nullexpr shared_ptr<Expression>()
+
+using boost::shared_ptr;
+using boost::make_shared;
+
+inline bool isDouble(const std::string &str)
+{
+ std::istringstream inpStream(str);
+ double inpValue = 0.0;
+ if (inpStream >> inpValue)
+ return true;
+ else
+ return false;
+}
+
+inline double toDouble(const std::string &str)
+{
+ std::istringstream inpStream(str);
+ double inpValue = 0.0;
+ inpStream >> inpValue;
+ return inpValue;
+}
+
+inline bool isInt(const std::string &str)
+{
+ std::istringstream inpStream(str);
+ int inpValue = 0.0;
+ if (inpStream >> inpValue)
+ return true;
+ else
+ return false;
+}
+
+inline double toInt(const std::string &str)
+{
+ std::istringstream inpStream(str);
+ int inpValue = 0.0;
+ inpStream >> inpValue;
+ return inpValue;
+}
+
+// Not an a list. Thus, without parentheses
+inline bool isLispString(const std::string &str)
+{
+ return (str.find('(') == std::string::npos) &&
+ (str.find(')') == std::string::npos);
+}
+
+#endif // UTILS_H

0 comments on commit d740efd

Please sign in to comment.