--- /dev/null
+#include <Servo.h>
+
+Servo servo1;
+
+// Constants
+const int ACK = 0x01;
+const int INIT = 0x55;
+
+void setup()
+{
+ Serial.begin(115200);
+ servo1.attach(9);
+ init_comm();
+}
+
+void init_comm()
+{
+ while(!Serial.available())
+ {
+ int init_val = Serial.read();
+ if(init_val == INIT)
+ {
+ Serial.write(ACK);
+ break;
+ }
+ }
+}
+
+void loop()
+{
+ if(Serial.available())
+ {
+ int new_pos = Serial.read();
+ servo1.write(new_pos);
+ Serial.write(ACK);
+ }
+}
--- /dev/null
+#include <Servo.h>
+
+Servo servo1;
+int margin = 180;
+int pos = 1;
+int direct = -1;
+
+void setup()
+{
+ Serial.begin(115200);
+ servo1.attach(9);
+}
+
+void loop()
+{
+ pos = (pos + 1) % 180;
+ servo1.write(pos);
+ servo1.write(180 - pos);
+}
--- /dev/null
+(use '[clojure.java.io :only (reader)])
+
+;------------------------------------------------------------------------------
+; Commands
+;------------------------------------------------------------------------------
+(defn install-package [args]
+ (println "# install-package")
+ (println "ssh <user>@<host> apt-get install" (first args))
+ (println))
+
+(defn install-module [args]
+ (println "# install-module")
+ (println (str "cd submodules/" (first args)))
+ (println (str "<this-script> submodules/" (first args)))
+ (println "cd ../../")
+ (println))
+
+(defn run-script [args]
+ (println "# run-script")
+ (println "scp" (first args) "<user>@<host>")
+ (println "ssh <user>@<host> chmod +x" (first args))
+ (println "ssh <user>@<host>" (first args))
+ (println))
+
+(defn fetch-config [args]
+ (println "# fetch-config")
+ (println "scp" (first args) "<user>@<host>:<destination>")
+ (println))
+
+;------------------------------------------------------------------------------
+; Setup Functions and Input
+;------------------------------------------------------------------------------
+; Function to determine which lines we ignore
+(defn ignored-line? [str]
+ "Function to determine which lines we ignore"
+ (or
+ (empty? (.replaceAll str "\\s+" ""))
+ (.equals (.substring (.replaceAll str "^\\s+" "") 0 1) "#") ))
+
+; Read in the lines from our file
+(def input
+ (filter #(not (ignored-line? %)) (line-seq (reader "foo.hl"))))
+
+;------------------------------------------------------------------------------
+; Main
+;------------------------------------------------------------------------------
+; Loop through all of our valid lines
+(doseq [line input]
+ ; Tokenize the line
+ (let [cmd (.split line "\\s+")]
+ ; Call the first element as a function and pass the rest as a param
+ ((eval (symbol (first cmd))) (rest cmd)) ))
--- /dev/null
+(defn we-care? [a]
+ (or
+ (== 0 (rem a 3))
+ (== 0 (rem a 5)) ))
+
+(defn add-nums [accum min max]
+ (if (< min max)
+ (if (we-care? min)
+ (add-nums (+ accum min) (+ min 1) max)
+ (add-nums accum (+ min 1) max))
+ accum))
+
+(println (add-nums 0 0 1000000))
+(println
+ (reduce
+ +
+ (filter
+ we-care?
+ (range
+ 0
+ 1000000 ))))
--- /dev/null
+(use '[clojure.main :only [repl]])
+
+(defn factors [n]
+ (filter #(zero? (mod % n)) (range 2 n)))
+
+(defn isprime [n]
+ (empty? (filter #(zero? (rem n %)) (range 2 n))))
+
+(defn next-primes [p]
+ (let [z (if (zero? (mod p 2)) 1 2) ]
+ (loop [n (+ p z)]
+ (if (isprime n)
+ (cons n (lazy-seq (next-primes n)))
+ (recur (+ n z))))))
+
+(defn primes []
+"Return a lazy-seq of all prime numbers"
+ (lazy-cat [2 3]
+ (next-primes 3)))
+
+(defn e3 [n]
+"What is the largest prime factor of the number 600851475143"
+ (max
+ (filter
+ #(zero? (mod % n))
+ (filter isprime (range 1 (- n 1)))
+ )
+ )
+)
+
+(println 600851475143)
+
+(repl)
--- /dev/null
+(use '[clojure.java.io :only (reader)])
+
+(defn token? [re s]
+ (not (nil? (re-matches re s))))
+
+(defn token [res s]
+ (let [m (first (filter #(token? (first %) s) res))]
+ (if (not (nil? m))
+ (list (second m) (str s)) )))
+
+(defn eval-token [tok]
+ (if (symbol? (first tok))
+ ((eval (first tok)) (second tok))
+ tok))
+
+(defn char-seq [^java.io.BufferedReader rdr]
+ (when-let [c (.read rdr)]
+ (if (> c -1)
+ (cons (char c) (lazy-seq (char-seq rdr))))))
+
+(defn token-seq [types coll]
+ (loop [s ""
+ tok nil
+ c coll]
+ (if (not (empty? c))
+ (let [news (str s (first c))
+ m (token types news)]
+ (if (nil? m)
+ (cons (eval-token tok) (lazy-seq (token-seq types c)))
+ (recur news m (rest c)) )))))
+
+(defn lex [res ^java.io.BufferedReader rdr]
+ (filter #(not (nil? (first %))) (token-seq res (char-seq rdr))))
+
+;------------------------------------------------------------------------------
+; Main
+;------------------------------------------------------------------------------
+(defn handle-error [s]
+ (println (str "Lex Error near: " s)))
+
+(def tokens
+ '((#"[A-Za-z-]+" :word)
+ (#";" :terminator)
+ (#"#.+$") ; Ignore comments
+ (#"\s+") ; Ignore whitespace
+ (#"." handle-error)))
+
+(print (lex tokens (reader "foo.hl")))
+
--- /dev/null
+pom.xml
+*jar
+/lib/
+/classes/
+.lein-deps-sum
--- /dev/null
+# lexer
+
+FIXME: write description
+
+## Usage
+
+FIXME: write
+
+## License
+
+Copyright (C) 2011 FIXME
+
+Distributed under the Eclipse Public License, the same as Clojure.
--- /dev/null
+(defproject lexer "1.0.0-SNAPSHOT"
+ :description "FIXME: write description"
+ :dependencies [[org.clojure/clojure "1.1.0"]])
--- /dev/null
+(ns lexer.core)
--- /dev/null
+(ns lexer.test.core
+ (:use [lexer.core])
+ (:use [clojure.test]))
+
+(deftest replace-me ;; FIXME: write
+ (is false "No tests have been written."))
--- /dev/null
+(use '[clojure.java.io :only (reader)])
+(use 'clojure.pprint)
+
+;------------------------------------------------------------------------------
+; Lexer Functions
+;------------------------------------------------------------------------------
+(defn token? [re s]
+ (not (nil? (re-matches re s))))
+
+(defn token [res s]
+ (let [m (first (filter #(token? (first %) s) res))]
+ (if (not (nil? m))
+ (list (second m) (str s)) )))
+
+(defn eval-token [tok]
+ (if (symbol? (first tok))
+ ((eval (first tok)) (second tok))
+ tok))
+
+(defn char-seq [^java.io.BufferedReader rdr]
+ (when-let [c (.read rdr)]
+ (if (> c -1)
+ (cons (char c) (lazy-seq (char-seq rdr))))))
+
+(defn token-seq [types coll]
+ (loop [s ""
+ tok nil
+ c coll]
+ (if (not (empty? c))
+ (let [news (str s (first c))
+ m (token types news)]
+ (if (nil? m)
+ (cons (eval-token tok) (lazy-seq (token-seq types c)))
+ (recur news m (rest c)) )))))
+
+(defn lex [res ^java.io.BufferedReader rdr]
+ (filter #(not (nil? (first %))) (token-seq res (char-seq rdr))))
+
+;------------------------------------------------------------------------------
+; Parser Functions
+;------------------------------------------------------------------------------
+(defn lr-shift [])
+(defn lr-reduce [])
+(defn lr-accept [])
+(defn lr-action [])
+(defn lr-goto [])
+
+(defn rule [keyw & patterns]
+ (for [pat patterns]
+ (list keyw (first pat) (second pat)) ))
+
+(defmacro defgrammar [sym start & rules]
+ `(def ~sym
+ (concat
+ '((:start (~start)))
+ ~@rules) ))
+
+(defn lr-parse [toks sytx input]
+ (loop [stck '()
+ inpt input
+ outpt '() ]))
+
+;------------------------------------------------------------------------------
+; Main
+;------------------------------------------------------------------------------
+(defn lex-error [s]
+ (println (str "Lex Error near: " s)))
+
+(def tokens
+ '((#"[A-Za-z-]+" :word)
+ (#";" :terminator)
+ (#"#.+$") ; Ignore comments
+ (#"\s+") ; Ignore whitespace
+ (#"." lex-error)))
+
+; Sample Grammar DSL
+(defgrammar syntax :exp
+ (rule :exp
+ '((:exp \+ :num) act1)
+ '((:exp \* :num) act2)
+ '((:num) act3) )
+
+ (rule :num
+ '((0) act4)
+ '((1) act5) ))
+
+(pprint syntax)
+;(println)
+;(pprint (lex tokens (reader "foo.hl")))
+
--- /dev/null
+PROJECT_ROOT = File.expand_path(File.dirname(__FILE__))
+
+# Application
+APP_NAME = 'parser'
+APP_EXT = '.exe'
+APP_OUT = "#{APP_NAME}#{APP_EXT}"
+
+# Compiler Settings
+COMPILER_BIN = 'g++'
+COMPILER_OPTS = '-c -Wall -Werror'
+
+# Linker Settings
+LINKER_BIN = 'g++'
+LINKER_OPTS = ''
+
+# Source Code Settings
+SRC_FILES = FileList['src/**/*.c*']
+INCLUDE_DIRS = FileList['src/**/']
+DEFINES = []
+
+# Generated Lists
+OBJ_FILES = SRC_FILES.collect{|src| "build/#{File.basename(src).ext('o')}" }
+DEFINE_LIST = DEFINES.collect{|define| "-D#{define}" }
+INCLUDE_LIST = INCLUDE_DIRS.collect{|x| "-I#{x} "}
+
+# Clean Task
+CLEAN.include( 'build/*.o' )
+CLEAN.include( APP_OUT )
+
--- /dev/null
+require 'rake'
+require 'rake/clean'
+
+# Load the dependencies
+load 'config.rake'
+
+task :default => [:release]
+task :release => [APP_OUT]
+
+# Find and compile all source files
+def FindSourceByObj(obj)
+ return SRC_FILES.find { |s|
+ (File.basename(s, '.c') == File.basename(obj, '.o')) ||
+ (File.basename(s, '.cpp') == File.basename(obj, '.o'))
+ }
+end
+rule '.o' => lambda{|obj| FindSourceByObj(obj) } do |t|
+ sh "#{COMPILER_BIN} #{COMPILER_OPTS} #{INCLUDE_LIST} #{DEFINE_LIST} -o #{t.name} #{t.source}"
+end
+
+# Link the object files together
+task APP_OUT => OBJ_FILES do
+ puts "Linking #{APP_OUT}..."
+ sh "#{LINKER_BIN} #{LINKER_OPTS} -o #{APP_NAME} #{OBJ_FILES.collect{|x| x + ' '}}"
+end
--- /dev/null
+#include "ast.h"
+#include <sstream>
+#include <string.h>
+
+AST::AST(ASTNodeType type)
+{
+ node_type = type;
+ node_text = NULL;
+ node_children = new list<AST*>();
+}
+
+AST::~AST()
+{
+ list<AST*>::iterator it = node_children->begin();
+ for(; it != node_children->end(); it++)
+ {
+ delete *(it);
+ }
+ delete node_children;
+ delete node_text;
+}
+
+AST::AST(ASTNodeType type, char* text)
+{
+ node_type = type;
+ node_text = new string(text);
+ node_children = new list<AST*>();
+}
+
+AST::AST(ASTNodeType type, int child_count, ...)
+{
+ va_list arg_list;
+ int i = 0;
+ node_type = type;
+ node_text = NULL;
+ node_children = new list<AST*>();
+ va_start (arg_list, child_count);
+ for (i = 0; i < child_count ; i++)
+ {
+ node_children->push_back( (AST*)va_arg(arg_list, AST*) );
+ }
+ va_end(arg_list);
+}
+
+ASTNodeType AST::type()
+{
+ return node_type;
+}
+
+list<AST*>* AST::children()
+{
+ return node_children;
+}
+
+string AST::text()
+{
+ ostringstream oss;
+ if(node_text != NULL)
+ {
+ oss << node_text->c_str();
+ }
+ return oss.str();
+}
+
+void AST::addChild(AST* node)
+{
+ node_children->push_back(node);
+}
+
--- /dev/null
+#ifndef AST_H
+#define AST_H
+
+#include <stdarg.h>
+#include <list>
+#include <string>
+
+using namespace std;
+
+typedef unsigned int ASTNodeType;
+
+class AST {
+ protected:
+ ASTNodeType node_type;
+ string* node_text;
+ list<AST*>* node_children;
+ public:
+ AST(ASTNodeType type);
+ ~AST();
+ AST(ASTNodeType type, char* text);
+ AST(ASTNodeType type, int child_count, ...);
+ ASTNodeType type();
+ string text();
+ list<AST*>* children();
+ void addChild(AST* node);
+};
+
+#endif
--- /dev/null
+#include <exception>
+#include "lexer.h"
+
+Lexer::Lexer() : line(-1), column(-1), input(&std::cin)
+{
+ consume();
+}
+
+Lexer::Lexer(std::string in) : line(-1), column(-1)
+{
+ input = new std::istringstream(in);
+ consume();
+}
+
+Lexer::Lexer(std::istream* in) : line(-1), column(-1), input(in)
+{
+ consume();
+}
+
+bool Lexer::eof(void)
+{
+ return ((input == NULL) || (input->eof()));
+}
+
+void Lexer::consume(void)
+{
+ if(input->eof())
+ {
+ current = EOF;
+ }
+ else
+ {
+ current = input->get();
+ if(current == '\n')
+ {
+ line++;
+ column = 0;
+ }
+ else
+ {
+ column++;
+ }
+ }
+}
+
+void Lexer::match(char x) {
+ if ( current == x)
+ {
+ consume();
+ }
+ else
+ {
+ throw std::exception();
+ }
+}
+
+
--- /dev/null
+#ifndef LEXER_H
+#define LEXER_H
+
+#include <iostream>
+#include <sstream>
+#include <cstdio>
+#include "token.h"
+
+class Lexer
+{
+ public:
+ int line;
+ int column;
+ char current;
+ std::istream* input;
+
+ Lexer();
+ Lexer(std::string in);
+ Lexer(std::istream* in);
+ virtual ~Lexer(){}
+ void consume(void);
+ void match(char x);
+ bool eof(void);
+ virtual Token* next(void) = 0;
+};
+
+#endif
--- /dev/null
+#include "token.h"
+
+Token::Token(TokenType_T ttype, std::string ttext) : tok_type(ttype), tok_text(ttext)
+{
+}
+
+Token::Token(TokenType_T ttype) : tok_type(ttype)
+{
+}
+
+TokenType_T Token::type()
+{
+ return tok_type;
+}
+
+const std::string& Token::text()
+{
+ return tok_text;
+}
+
+
--- /dev/null
+#ifndef TOKEN_H
+#define TOKEN_H
+
+#include <string>
+
+typedef int TokenType_T;
+
+class Token
+{
+ private:
+ TokenType_T tok_type;
+ std::string tok_text;
+ public:
+ Token(TokenType_T ttype);
+ Token(TokenType_T ttype, std::string ttext);
+ TokenType_T type();
+ const std::string& text();
+};
+
+#endif
--- /dev/null
+#include <cstdio>
+#include <iostream>
+#include <sstream>
+#include <cstdio>
+
+#include "lexer.h"
+#include "llkparser.h"
+#include "sexp.h"
+
+using namespace std;
+
+typedef enum LexException
+{
+ UnexpectedCharacter,
+ InvalidCharacter
+} LexException_T;
+
+typedef enum TokenTypes
+{
+ ID = 0,
+ NUM = 1,
+ CHAR = 2,
+ LBRACK = 3,
+ RBRACK = 4,
+ LPAR = 5,
+ RPAR = 6,
+ LBRACE = 7,
+ RBRACE = 8,
+ COMMA = 9,
+ PIPE = 10,
+
+ // AST Node Types
+ PROGRAM = 11,
+ VECTOR = 12,
+ LIST = 13,
+ BLOCK = 14,
+ FUNC = 15
+} eTokenTypes;
+
+class LambdaLexer : public Lexer {
+ public:
+ LambdaLexer() : Lexer() {}
+ LambdaLexer(std::string in) : Lexer(in) {}
+ LambdaLexer(std::istream* in) : Lexer(in) {}
+
+ bool isWhiteSpace(void)
+ {
+ return (current == ' ') ||
+ (current == '\t') ||
+ (current == '\r') ||
+ (current == '\n');
+ }
+
+ bool isLetter(void)
+ {
+ return ((current >= 'a') && (current <= 'z')) ||
+ ((current >= 'A') && (current <= 'Z'));
+ }
+
+ bool isDigit(void)
+ {
+ return ((current >= '0') && (current <= '9'));
+ }
+
+ Token* next(void)
+ {
+ while ( ! input->eof() )
+ {
+ if (isWhiteSpace())
+ {
+ WS();
+ }
+ else if (isLetter())
+ {
+ return Id();
+ }
+ else if (isDigit())
+ {
+ return Number();
+ }
+ else
+ {
+ switch (current)
+ {
+ case '\'':
+ return Char();
+ case '|':
+ consume(); return new Token(PIPE);
+ case '[':
+ consume(); return new Token(LBRACK);
+ case ']':
+ consume(); return new Token(RBRACK);
+ case '(':
+ consume(); return new Token(LPAR);
+ case ')':
+ consume(); return new Token(RPAR);
+ case '{':
+ consume(); return new Token(LBRACE);
+ case '}':
+ consume(); return new Token(RBRACE);
+ case ',':
+ consume(); return new Token(COMMA);
+ default:
+ throw InvalidCharacter;
+ }
+ }
+ }
+ return NULL;
+ }
+
+ void WS(void)
+ {
+ do
+ {
+ consume();
+ }
+ while(isWhiteSpace());
+ }
+
+ Token* Id(void)
+ {
+ ostringstream oss;
+ do
+ {
+ oss << current;
+ consume();
+ }
+ while(isLetter() || isDigit() || current == '_');
+ return new Token(ID, oss.str());
+ }
+
+ Token* Number(void)
+ {
+ ostringstream oss;
+ do
+ {
+ oss << current;
+ consume();
+ }
+ while(isDigit());
+
+ if(current == '.')
+ {
+ return Decimal(oss);
+ }
+
+ return new Token(NUM, oss.str());
+ }
+
+ Token* Decimal(ostringstream& oss)
+ {
+ oss << current;
+ consume();
+
+ if(!isDigit())
+ {
+ throw UnexpectedCharacter;
+ }
+
+ do
+ {
+ oss << current;
+ consume();
+ }
+ while ( isDigit() );
+
+ return new Token(NUM,oss.str());
+ }
+
+ Token* Char(void)
+ {
+ ostringstream oss;
+
+ match('\'');
+ if(current != '\'')
+ {
+ oss << current;
+ consume();
+ }
+ else
+ {
+ throw UnexpectedCharacter;
+ }
+ match('\'');
+
+ return new Token( CHAR, oss.str() );
+ }
+};
+
+class LambdaParser : public LLKParser
+{
+ public:
+ LambdaParser(std::string in) : LLKParser(2,new LambdaLexer(in))
+ {
+ }
+
+ LambdaParser(std::istream* in) : LLKParser(2,new LambdaLexer(in))
+ {
+ }
+
+ AST* parse(void)
+ {
+ return program();
+ }
+
+ AST* program(void)
+ {
+ AST* node = new AST( PROGRAM );
+ while( lookaheadType(1) != EOF )
+ {
+ node->addChild( expression() );
+ }
+ return node;
+ }
+
+ AST* expression(void)
+ {
+ return literal();
+ }
+
+ AST* literal(void)
+ {
+ AST* node = NULL;
+ AST* child1 = NULL;
+ AST* child2 = NULL;
+ switch(lookaheadType(1))
+ {
+ // Literal = '[' ExpList? ']'
+ case LBRACK:
+ match(LBRACK);
+ node = explist(VECTOR, RBRACK);
+ match(RBRACK);
+ break;
+
+ // Literal = '(' ExpList? ')'
+ case LPAR:
+ match(LPAR);
+ node = explist(LIST, RPAR);
+ match(RPAR);
+ break;
+
+ // Literal = '{' ExpBlock? '}'
+ case LBRACE:
+ match(LBRACE);
+ node = expblock(BLOCK,RBRACE);
+ match(RBRACE);
+ break;
+
+ // Literal = '|' ExpList '|' '{' ExpBlock? '}'
+ case PIPE:
+ match(PIPE);
+ child1 = explist(LIST, PIPE);
+ match(PIPE);
+ match(LBRACE);
+ child2 = expblock(BLOCK, RBRACE);
+ match(RBRACE);
+ node = new AST(FUNC, 2, child1, child2);
+ break;
+
+ // Literal = ID
+ case ID:
+ node = new AST( ID,(char*)(lookaheadToken(1)->text().c_str()) );
+ consume();
+ break;
+
+ // Literal = NUM
+ case NUM:
+ node = new AST( NUM,(char*)(lookaheadToken(1)->text().c_str()) );
+ consume();
+ break;
+
+ // Literal = CHAR
+ case CHAR:
+ node = new AST( CHAR,(char*)(lookaheadToken(1)->text().c_str()) );
+ consume();
+ break;
+
+ default:
+ throw "Unexpected Token";
+ }
+ return node;
+ }
+
+ // ExpList = (Expression (',' Expression)*)?
+ AST* explist(TokenType_T node_type, TokenType_T terminator)
+ {
+ AST* node = new AST( node_type );
+ if(lookaheadType(1) != terminator)
+ {
+ node->addChild( expression() );
+ while(lookaheadType(1) == COMMA)
+ {
+ match(COMMA);
+ node->addChild( expression() );
+ }
+ }
+ return node;
+ }
+
+ // ExpBlock = Expression+
+ AST* expblock(TokenType_T node_type, TokenType_T terminator)
+ {
+ AST* node = new AST(node_type);
+ while(lookaheadType(1) != RBRACE)
+ {
+ node->addChild( expression() );
+ }
+ return node;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ istringstream input("asd asd1 as1d a_sd a_s1d 1 1.0 1.1 'a' 'b' 'c' [ ] ( ) { } [ 1, 'a', abc, [a]] { 1 2 3 { 1 } {} } ||{} |a,b,c,d|{ a b c d }");
+ LambdaParser parser(&input);
+ AST* ast = parser.parse();
+ Visitor* visitor = new SEXP(ast);
+ visitor->visit();
+ cout << visitor->str();
+ return 0;
+}
--- /dev/null
+#include "llkparser.h"
+
+LLKParser::LLKParser(int k_val, Lexer* lxer) : k(k_val), next(0), lexer(lxer)
+{
+ if ( lexer != NULL )
+ {
+ lookahead = new Token*[k];
+ for (int i = 0; i < k; i++)
+ {
+ consume();
+ }
+ }
+ else
+ {
+ throw std::exception();
+ }
+}
+
+void LLKParser::consume(void)
+{
+ if ( lookahead != NULL )
+ {
+ lookahead[next] = lexer->next();
+ next = (next + 1) % k;
+ }
+}
+
+void LLKParser::match(TokenType_T type)
+{
+ if( lookaheadType(1) == type )
+ {
+ consume();
+ }
+ else
+ {
+ throw std::exception();
+ }
+}
+
+Token* LLKParser::lookaheadToken(int i)
+{
+ Token* ret = NULL;
+ if( lookahead != NULL )
+ {
+ ret = lookahead[(next + i - 1) % k];
+ }
+ return ret;
+}
+
+TokenType_T LLKParser::lookaheadType(int i)
+{
+ TokenType_T ret = EOF;
+ if( lookahead != NULL )
+ {
+ Token* tok = lookaheadToken(i);
+ ret = (tok != NULL) ? tok->type() : EOF;
+ }
+ return ret;
+}
+
+
--- /dev/null
+#ifndef LLK_PARSER_H
+#define LLK_PARSER_H
+
+#include <exception>
+#include "lexer.h"
+#include "ast.h"
+
+class LLKParser
+{
+ public:
+ int k;
+ int next;
+ Lexer* lexer;
+ Token** lookahead;
+
+ // Constructors
+ LLKParser(int k_val, Lexer* lxer);
+
+ // Utility methods
+ void consume(void);
+ void match(TokenType_T type);
+ Token* lookaheadToken(int i);
+ TokenType_T lookaheadType(int i);
+
+ // Main parsing function
+ virtual AST* parse(void) = 0;
+};
+
+#endif
--- /dev/null
+#include "sexp.h"
+
+using namespace std;
+
+string SEXP::str()
+{
+ return stream.str();
+}
+
+void SEXP::beforeVisit(AST* cur, int depth)
+{
+}
+
+void SEXP::afterVisit(AST* cur, int depth)
+{
+ stream << endl;
+}
+
+void SEXP::beforeChildren(AST* cur, int depth)
+{
+ //stream << "(" << typeToString(cur->type()) << " " << cur->text();
+ stream << "(" << cur->type() << " " << cur->text();
+}
+
+void SEXP::afterChildren(AST* cur, int depth)
+{
+ stream << ")";
+}
+
+void SEXP::beforeChild(AST* cur, int depth)
+{
+ stream << endl;
+ for(int i = 0; i< depth; i++)
+ {
+ stream << " ";
+ }
+}
+
+void SEXP::afterChild(AST* cur, int depth)
+{
+}
+
--- /dev/null
+#ifndef SEXP_H
+#define SEXP_H
+
+#include "visitor.h"
+#include <iostream>
+#include <sstream>
+
+class SEXP : public Visitor {
+ protected:
+ ostringstream stream;
+ public:
+ SEXP(AST* root) : Visitor(root) {};
+ string str();
+ private:
+ //string typeToString(int type);
+ void beforeVisit(AST* cur, int depth);
+ void afterVisit(AST* cur, int depth);
+ void beforeChildren(AST* cur, int depth);
+ void afterChildren(AST* cur, int depth);
+ void beforeChild(AST* cur, int depth);
+ void afterChild(AST* cur, int depth);
+};
+
+#endif
--- /dev/null
+#include "visitor.h"
+#include <list>
+
+using namespace std;
+
+void Visitor::visit(AST* cur, int depth)
+{
+ list<AST*>* children;
+ list<AST*>::iterator it;
+
+ // If we are just starting then use the global tree
+ if(cur == NULL) cur = ast;
+
+ // Execute or pre-walk actions
+ if(depth == 0) beforeVisit( cur, depth );
+
+ // Setup our locals
+ children = cur->children();
+ it = children->begin();
+
+ // Visit the tree
+ beforeChildren(cur,depth);
+ depth++;
+ for(; it != children->end(); it++)
+ {
+ beforeChild( *it, depth );
+ visit( *it, depth );
+ afterChild( *it, depth );
+ }
+ afterChildren(cur,depth);
+
+ // Execute our post-walk actions
+ if(depth == 1) afterVisit( cur, depth );
+}
+
--- /dev/null
+#ifndef TRANSLATOR_H
+#define TRANSLATOR_H
+
+#include "ast.h"
+#include <string>
+#include <iostream>
+
+class Visitor {
+ protected:
+ AST* ast;
+ public:
+ Visitor(AST* tree) : ast(tree) {};
+ ~Visitor() { delete ast; }
+ void visit(AST* cur = NULL, int depth = 0);
+ virtual string str() = 0;
+ private:
+ virtual void beforeVisit(AST* cur, int depth) = 0;
+ virtual void afterVisit(AST* cur, int depth) = 0;
+ virtual void beforeChildren(AST* cur, int depth) = 0;
+ virtual void afterChildren(AST* cur, int depth) = 0;
+ virtual void beforeChild(AST* cur, int depth) = 0;
+ virtual void afterChild(AST* cur, int depth) = 0;
+};
+
+class VisitorFactory {
+ public:
+ virtual Visitor* createVisitor(AST* root) = 0;
+};
+
+#endif
--- /dev/null
+#ifndef REF_H
+#define REF_H
+
+#include <typeinfo>
+#include <string>
+#include <exception>
+#include "type.h"
+
+class NullRefException : public std::exception
+{
+ virtual const char* what() const throw()
+ {
+ return "Null Reference: A pointer was used without being initialized";
+ }
+};
+
+template <class T>
+class Ref {
+ protected:
+ T* ptr;
+ private:
+ // Disallow instantiation without a parameter
+ Ref() : ptr(0) {}
+ // Disallow direct instantiation on the heap
+ void*operator new( size_t );
+ void* operator new[]( size_t );
+ void operator delete( void* );
+ void operator delete[]( void* );
+ public:
+ Ref(T* p = 0);
+ Ref(const Ref& right);
+ ~Ref();
+ //Ref<T> operator [] (unsigned int index);
+ T* value(void);
+ Ref<T>& operator = (Ref<T>& right);
+ Ref<T>& operator = (T* right);
+ T& operator * (void);
+ T* operator -> (void);
+ std::string type(void);
+};
+
+template <class T>
+Ref<T>::Ref(T* p) : ptr(p)
+{
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ }
+}
+
+template<class T>
+Ref<T>::Ref(const Ref& right) : ptr(right.ptr)
+{
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ }
+}
+
+template <class T>
+Ref<T>::~Ref()
+{
+ if (ptr != 0)
+ {
+ ptr->decRefCount();
+ }
+}
+
+template <class T>
+T* Ref<T>::value(void)
+{
+ return ptr;
+}
+
+/*template <class T>*/
+//Ref<T> Ref<T>::operator [] (unsigned int index)
+//{
+ //return ptr[index];
+//}
+
+template <class T>
+Ref<T>& Ref<T>::operator = (Ref<T>& right)
+{
+ ptr->decRefCount();
+ ptr = right.value();
+ ptr->incRefCount();
+ return *this;
+}
+
+template <class T>
+Ref<T>& Ref<T>::operator = (T* right)
+{
+ ptr->decRefCount();
+ ptr = right;
+ ptr->incRefCount();
+ return *this;
+}
+
+template <class T>
+T& Ref<T>::operator * (void)
+{
+ if(ptr == 0)
+ {
+ NullRefException null_ref_exception;
+ throw null_ref_exception;
+ }
+ return *ptr;
+}
+
+template <class T>
+T* Ref<T>::operator -> (void)
+{
+ if(ptr == 0)
+ {
+ NullRefException null_ref_exception;
+ throw null_ref_exception;
+ }
+ return ptr;
+}
+
+template <class T>
+std::string Ref<T>::type(void)
+{
+ return typeid(this).name();
+}
+
+#endif
--- /dev/null
+PROJECT_ROOT = File.expand_path(File.dirname(__FILE__))
+
+# Application
+APP_NAME = 'stdlib'
+STATIC_APP_OUT = "#{APP_NAME}.a"
+SHARED_APP_OUT = "#{APP_NAME}.so"
+
+# Compiler Settings
+COMPILER_BIN = 'g++'
+COMPILER_OPTS = '-c -Wall -Werror'
+
+# Linker Settings
+STATIC_LINKER_BIN = 'ar'
+STATIC_LINKER_OPTS = 'rvs'
+SHARED_LINKER_BIN = 'g++'
+SHARED_LINKER_OPTS = '-shared -o'
+
+# Source Code Settings
+SRC_FILES = FileList['src/**/*.c*']
+INCLUDE_DIRS = FileList['src/**/']
+DEFINES = [
+ 'DETECT_MEM_LEAKS'
+]
+
+# Generated Lists
+OBJ_FILES = SRC_FILES.collect{|src| "build/#{File.basename(src).ext('o')}" }
+DEFINE_LIST = DEFINES.collect{|define| "-D#{define}" }
+INCLUDE_LIST = INCLUDE_DIRS.collect{|x| "-I#{x} "}
+
+# Clean Task
+CLEAN.include( 'build/*.o' )
+CLEAN.include( STATIC_APP_OUT )
+CLEAN.include( SHARED_APP_OUT )
+
--- /dev/null
+./src/gc/gc.cpp
+./src/gc/gc.h
+./src/runtime.c
+./src/runtime.h
+./src/type/array/array.cpp
+./src/type/array/array.h
+./src/type/atom/atom.cpp
+./src/type/atom/atom.h
+./src/type/func/func.cpp
+./src/type/func/func.h
+./src/type/list/list.cpp
+./src/type/list/list.h
+./src/type/map/map.cpp
+./src/type/map/map.h
+./src/type/num/num.cpp
+./src/type/num/num.h
+./src/type/ref/ref.cpp
+./src/type/ref/ref.h
+./src/type/type.cpp
+./src/type/type.h
+./test/test_main.cpp
--- /dev/null
+require 'rake'
+require 'rake/clean'
+
+# Load the dependencies
+load 'config.rake'
+
+task :default => [:release]
+task :release => [STATIC_APP_OUT, SHARED_APP_OUT]
+
+# Find and compile all source files
+def FindSourceByObj(obj)
+ return SRC_FILES.find { |s|
+ (File.basename(s, '.c') == File.basename(obj, '.o')) ||
+ (File.basename(s, '.cpp') == File.basename(obj, '.o'))
+ }
+end
+rule '.o' => lambda{|obj| FindSourceByObj(obj) } do |t|
+ sh "#{COMPILER_BIN} #{COMPILER_OPTS} #{INCLUDE_LIST} #{DEFINE_LIST} -o #{t.name} #{t.source}"
+end
+
+# Link the object files together
+task STATIC_APP_OUT => OBJ_FILES do
+ puts "Linking #{STATIC_APP_OUT}..."
+ sh "#{STATIC_LINKER_BIN} #{STATIC_LINKER_OPTS} #{STATIC_APP_OUT} #{OBJ_FILES.collect{|x| x + ' '}}"
+end
+
+task SHARED_APP_OUT => OBJ_FILES do
+ puts "Linking #{SHARED_APP_OUT}..."
+ sh "#{SHARED_LINKER_BIN} #{SHARED_LINKER_OPTS} #{SHARED_APP_OUT} #{OBJ_FILES.collect{|x| x + ' '}}"
+end
+
+task :test => OBJ_FILES do
+ puts "compiling test_main..."
+ sh "#{COMPILER_BIN} #{COMPILER_OPTS} #{INCLUDE_LIST} #{DEFINE_LIST} -o build/test_main.o test/test_main.cpp"
+ puts "Linking test_runner.exe..."
+ sh "#{SHARED_LINKER_BIN} -o test_runner.exe #{OBJ_FILES.collect{|x| x + ' '}} build/test_main.o"
+end
--- /dev/null
+#ifndef CAST_H
+#define CAST_H
+
+#include "type.h"
+
+class BadCastException : public std::exception
+{
+ virtual const char* what() const throw()
+ {
+ return "Bad Cast: Incompatible types";
+ }
+};
+
+template <class T>
+T* cast(type_ptr ptr)
+{
+ T* new_ptr = dynamic_cast<T*>( ptr.value() );
+ if (!new_ptr)
+ {
+ throw BadCastException();
+ }
+ return new_ptr;
+}
+
+#endif
--- /dev/null
+#include "cork.h"
+
+#ifdef DETECT_MEM_LEAKS
+
+// We want to use the real malloc and free in this file
+#undef malloc
+#undef free
+
+#include <iostream>
+#include <exception> // for std::bad_alloc
+#include <cstdlib> // for malloc() and free()
+#include <string.h>
+
+// Set the namespace
+using namespace std;
+/******************************************************************************
+ * Typedefs
+ *****************************************************************************/
+typedef struct BlockTableEntry
+{
+ void * ptr;
+ unsigned int size;
+ const char* file;
+ int line;
+ void * next;
+} BlockTableEntry_T;
+
+typedef struct BlockTable
+{
+ unsigned int size;
+ BlockTableEntry_T* blocks[TBL_SIZE];
+} BlockTable_T;
+
+/******************************************************************************
+ * Prototypes
+ *****************************************************************************/
+void insert_record(void * ptr, BlockTable_T* entry);
+void erase_record(void * ptr);
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+unsigned int allocated;
+static BlockTable_T Block_Table = { 0, {0} };
+
+/******************************************************************************
+ * Function Definitions
+ *****************************************************************************/
+void insert_record(void * ptr, BlockTableEntry_T* entry)
+{
+ unsigned int index = ((unsigned int)ptr) % TBL_SIZE;
+ BlockTableEntry_T* last = Block_Table.blocks[ index ];
+ BlockTableEntry_T* curr = last;
+
+ while (curr != NULL)
+ {
+ if ( curr->ptr == ptr )
+ {
+ curr->size = entry->size;
+ free(entry);
+ break;
+ }
+ last = curr;
+ curr = (BlockTableEntry_T*)curr->next;
+ }
+
+ if(curr == NULL)
+ {
+ if (last != NULL)
+ {
+ last->next = entry;
+ }
+ else
+ {
+ Block_Table.blocks[index] = entry;
+ }
+ Block_Table.size++;
+ }
+}
+
+void erase_record(void * ptr)
+{
+ int depth = 0;
+ unsigned int index = ((unsigned int)ptr) % TBL_SIZE;
+ BlockTableEntry_T* last = Block_Table.blocks[ index ];
+ BlockTableEntry_T* curr = last;
+
+ while( curr != NULL )
+ {
+ depth = 1;
+ if( curr->ptr == ptr )
+ {
+ depth = 2;
+ if(last == curr)
+ {
+ depth = 3;
+ Block_Table.blocks[ index ] = (BlockTableEntry_T*)curr->next;
+ }
+ else
+ {
+ depth = 4;
+ last->next = curr->next;
+ }
+ free(curr);
+ Block_Table.size--;
+ break;
+ }
+ last = curr;
+ curr = (BlockTableEntry_T*)curr->next;
+ }
+}
+
+void Cork_ReportMemoryLeaks(void)
+{
+ unsigned int index = 0;
+ cout << "-----------------------------------------------------------------" << endl;
+ cout << "Cork: Memory Allocation Analysis" << endl;
+ cout << "-----------------------------------------------------------------" << endl;
+ cout << "You have " << Block_Table.size << " Unclaimed objects." << endl;
+
+ for(; index < TBL_SIZE; index++)
+ {
+ BlockTableEntry_T* entry = Block_Table.blocks[ index ];
+ while(entry != NULL)
+ {
+ cout << "\t" << entry->size << "\t" << entry->ptr;
+ if( entry->file != NULL )
+ {
+ cout << "\t" << entry->line << "\t" << entry->file;
+ }
+ cout << endl;
+ entry = (BlockTableEntry_T*)entry->next;
+ }
+ }
+}
+
+void * operator new (size_t size, string file, unsigned int line)
+{
+ void * ptr = malloc(size);
+ char * fname = (char*)malloc(file.length());
+ if(ptr == NULL)
+ {
+ throw bad_alloc();
+ }
+ else
+ {
+ BlockTableEntry_T* entry = (BlockTableEntry_T*)malloc(sizeof(BlockTableEntry_T));
+ strcpy( fname, file.c_str() );
+ entry->ptr = ptr;
+ entry->size = size;
+ entry->file = fname;
+ entry->line = line;
+ entry->next = NULL;
+ insert_record(ptr,entry);
+ }
+ return ptr;
+}
+
+void * operator new(size_t size) throw(bad_alloc) {
+ void * ptr = malloc(size);
+ if(ptr == NULL)
+ {
+ throw bad_alloc();
+ }
+ else
+ {
+ BlockTableEntry_T* entry = (BlockTableEntry_T*)malloc(sizeof(BlockTableEntry_T));
+ entry->ptr = ptr;
+ entry->size = size;
+ entry->file = NULL;
+ entry->line = 0;
+ entry->next = NULL;
+ insert_record(ptr,entry);
+ }
+ return ptr;
+}
+
+void operator delete(void * p) {
+ free(p);
+ erase_record(p);
+}
+
+#endif
--- /dev/null
+#ifndef CORK_H
+#define CORK_H
+
+#ifdef DETECT_MEM_LEAKS
+ #include <string>
+ typedef unsigned int size_t;
+
+ void Cork_ReportMemoryLeaks(void);
+ void * operator new (size_t size, std::string file, unsigned int line);
+ #define TBL_SIZE 512
+ #define REPORT_LEAKS() Cork_ReportMemoryLeaks()
+ #define _new new (__FILE__,__LINE__)
+#else
+ #define REPORT_LEAKS()
+ #define _new new
+#endif
+
+#endif
--- /dev/null
+#ifndef GC_H
+#define GC_H
+
+#include "gc_obj.h"
+#include "gc_ptr.h"
+
+#endif
--- /dev/null
+#include "gc_obj.h"
+
+gc_obj::gc_obj() : ref_count(0)
+{
+}
+
+gc_obj::~gc_obj()
+{
+}
+
+void gc_obj::incRefCount(void)
+{
+ ref_count++;
+}
+
+void gc_obj::decRefCount(void)
+{
+ if ( (--ref_count) == 0 )
+ {
+ delete this;
+ }
+}
+
+
--- /dev/null
+#ifndef GC_OBJ_H
+#define GC_OBJ_H
+
+#include <iostream>
+
+class gc_obj
+{
+ private:
+ unsigned int ref_count;
+ public:
+ gc_obj();
+ virtual ~gc_obj();
+ void incRefCount();
+ void decRefCount();
+};
+
+#endif
--- /dev/null
+#include "gc_ptr.h"
+
+/*gc_ptr::gc_ptr(gc_obj* p) : ptr(p)*/
+//{
+ //if (ptr != 0)
+ //{
+ //ptr->incRefCount();
+ //}
+//}
+
+//gc_ptr::gc_ptr(const gc_ptr& right) : ptr(right.ptr)
+//{
+ //if (ptr != 0)
+ //{
+ //ptr->incRefCount();
+ //}
+//}
+
+//gc_ptr::~gc_ptr()
+//{
+ //if (ptr != 0)
+ //{
+ //ptr->decRefCount();
+ //}
+//}
+
+//gc_obj* gc_ptr::value(void)
+//{
+ //return ptr;
+//}
+
+//gc_ptr& gc_ptr::operator = (gc_ptr& right)
+//{
+ //ptr->decRefCount();
+ //ptr = right.value();
+ //ptr->incRefCount();
+ //return *this;
+//}
+
+//gc_ptr& gc_ptr::operator = (gc_obj* right)
+//{
+ //ptr->decRefCount();
+ //ptr = right;
+ //ptr->incRefCount();
+ //return *this;
+//}
+
+//gc_obj& gc_ptr::operator * (void)
+//{
+ //return *ptr;
+//}
+
+//gc_obj* gc_ptr::operator -> (void)
+//{
+ //return ptr;
+//}
+
--- /dev/null
+#ifndef REF_H
+#define REF_H
+
+#include <typeinfo>
+#include <string>
+#include <exception>
+
+class NullRefException : public std::exception
+{
+ virtual const char* what() const throw()
+ {
+ return "Null Reference: A pointer was used without being initialized";
+ }
+};
+
+template <class T>
+class gc_ptr {
+ protected:
+ T* ptr;
+ private:
+ // Disallow direct instantiation on the heap
+ void*operator new( size_t );
+ void operator delete( void* );
+ public:
+ gc_ptr(T* p = 0);
+ gc_ptr(const gc_ptr& right);
+ ~gc_ptr();
+ T* value(void);
+ gc_ptr& operator = (gc_ptr& right);
+ gc_ptr& operator = (T* right);
+ T& operator * (void);
+ T* operator -> (void);
+};
+
+template <class T>
+gc_ptr<T>::gc_ptr(T* p) : ptr(p)
+{
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ }
+}
+
+template <class T>
+gc_ptr<T>::gc_ptr(const gc_ptr& right) : ptr(right.ptr)
+{
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ }
+}
+
+template <class T>
+gc_ptr<T>::~gc_ptr()
+{
+ if (ptr != 0)
+ {
+ ptr->decRefCount();
+ }
+}
+
+template <class T>
+T* gc_ptr<T>::value(void)
+{
+ return ptr;
+}
+
+template <class T>
+gc_ptr<T>& gc_ptr<T>::operator = (gc_ptr& right)
+{
+ if(ptr) ptr->decRefCount();
+ ptr = right.value();
+ if(ptr) ptr->incRefCount();
+ return *this;
+}
+
+template <class T>
+gc_ptr<T>& gc_ptr<T>::operator = (T* right)
+{
+ if(ptr) ptr->decRefCount();
+ ptr = right;
+ if(ptr) ptr->incRefCount();
+ return *this;
+}
+
+template <class T>
+T& gc_ptr<T>::operator * (void)
+{
+ return *ptr;
+}
+
+template <class T>
+T* gc_ptr<T>::operator -> (void)
+{
+ return ptr;
+}
+
+#endif
--- /dev/null
+#include "runtime.h"
+
+Atom True;
+Atom False;
+Atom Nil;
--- /dev/null
+#ifndef RUNTIME_H
+#define RUNTIME_H
+
+#include <exception>
+#include "type.h"
+#include "cast.h"
+#include "atom.h"
+#include "num.h"
+#include "func.h"
+#include "list.h"
+#include "vector.h"
+
+extern Atom True;
+extern Atom False;
+extern Atom Nil;
+
+#endif
--- /dev/null
+#include <string>
+#include <typeinfo>
+#include <sstream>
+#include "atom.h"
+
+Atom::~Atom(void)
+{
+}
+
+const std::type_info& Atom::type(void) const
+{
+ return typeid(this);
+}
+
+const std::string Atom::toString(void) const
+{
+ std::ostringstream oss;
+ oss << "<" << type().name() << ":" << this << ">";
+ return oss.str();
+}
--- /dev/null
+#ifndef ATOM_H
+#define ATOM_H
+
+#include "type.h"
+
+class Atom : public Type
+{
+ public:
+ ~Atom(void);
+ const std::type_info& type(void) const;
+ const std::string toString(void) const;
+};
+
+#endif
--- /dev/null
+#include <typeinfo>
+#include <sstream>
+#include "func.h"
+
+Func::~Func(void)
+{
+}
+
+const std::type_info& Func::type(void) const
+{
+ return typeid(this);
+}
+
+const std::string Func::toString(void) const
+{
+ std::ostringstream oss;
+ oss << "<" << type().name() << ":" << this << ">";
+ return oss.str();
+}
+
--- /dev/null
+#ifndef FUNC_H
+#define FUNC_H
+
+#include "type.h"
+#include "vector.h"
+
+class Func : public Type
+{
+ public:
+ ~Func(void);
+ const std::type_info& type(void) const;
+ const std::string toString(void) const;
+ virtual type_ptr operator () (Vector& args) const = 0;
+};
+
+#endif
--- /dev/null
+#include <typeinfo>
+#include <sstream>
+#include "list.h"
+
+List::List(Type* hd, List* tl) : lst_head(hd), lst_tail(tl)
+{
+}
+
+List::List(int count, ...)
+{
+ va_list arg_list;
+ int i = 0;
+ List* prev = NULL;
+ va_start (arg_list, count);
+ for (i = 0; i < count; i++)
+ {
+ prev = new List( va_arg(arg_list, Type*), prev);
+ }
+ lst_head = va_arg(arg_list, Type*);
+ lst_tail = prev;
+ va_end(arg_list);
+}
+
+List::~List(void)
+{
+}
+
+const std::type_info& List::type(void) const
+{
+ return typeid(this);
+}
+
+const std::string List::toString(void) const
+{
+ std::ostringstream oss;
+ oss << "<" << type().name() << ":" << this << ">";
+ return oss.str();
+}
+
+const type_ptr& List::head(void) const
+{
+ return lst_head;
+}
+
+const type_ptr& List::tail(void) const
+{
+ return lst_tail;
+}
+
--- /dev/null
+#ifndef LIST_H
+#define LIST_H
+
+#include <stdarg.h>
+#include "type.h"
+
+class List : public Type
+{
+ private:
+ type_ptr lst_head;
+ type_ptr lst_tail;
+ public:
+ List(Type* hd, List* tl);
+ List(int count, ...);
+ ~List(void);
+ const std::type_info& type(void) const;
+ const std::string toString(void) const;
+ const type_ptr& head(void) const;
+ const type_ptr& tail(void) const;
+};
+
+#endif
--- /dev/null
+#include <typeinfo>
+#include <sstream>
+#include "num.h"
+#include "cast.h"
+
+Num::Num(double num) : val(num)
+{
+}
+
+Num::~Num(void)
+{
+}
+
+const std::type_info& Num::type(void) const
+{
+ return typeid(this);
+}
+
+const std::string Num::toString(void) const
+{
+ std::ostringstream oss;
+ oss << value();
+ return oss.str();
+}
+
+double Num::value(void) const
+{
+ return val;
+}
+
+const type_ptr Num::operator + (Num& right) const
+{
+ type_ptr res = new Num( value() + right.value() );
+ return res;
+}
+
+const type_ptr Num::operator - (Num& right) const
+{
+ type_ptr res = new Num( value() - right.value() );
+ return res;
+}
+
+const type_ptr Num::operator * (Num& right) const
+{
+ type_ptr res = new Num( value() * right.value() );
+ return res;
+}
+
+const type_ptr Num::operator / (Num& right) const
+{
+ type_ptr res = new Num( value() / right.value() );
+ return res;
+}
+
--- /dev/null
+#ifndef NUM_H
+#define NUM_H
+
+#include "type.h"
+
+class Num : public Type
+{
+ protected:
+ double val;
+ public:
+ Num(double num);
+ ~Num(void);
+ const std::type_info& type(void) const;
+ const std::string toString(void) const;
+
+ double value(void) const;
+
+ const type_ptr operator + (Num& right) const;
+ const type_ptr operator - (Num& right) const;
+ const type_ptr operator * (Num& right) const;
+ const type_ptr operator / (Num& right) const;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <sstream>
+#include "type.h"
+
+/******************************************************************************
+ * Constructors and Destructors
+ *****************************************************************************/
+Type::Type(void)
+{
+}
+
+Type::~Type(void)
+{
+}
+
+/******************************************************************************
+ * Type Related Methods
+ *****************************************************************************/
+const Type* Type::value(void) const
+{
+ return this;
+}
+
+/******************************************************************************
+ * Operators
+ *****************************************************************************/
+bool Type::operator == (const Type& right) const
+{
+ return (this == &right) || (value() == right.value());
+}
+
+bool Type::operator != (const Type& right) const
+{
+ return (this != &right) || (value() != right.value());
+}
+
+std::ostream& operator << (std::ostream &out, Type& type)
+{
+ out << type.toString();
+ return out;
+}
+
--- /dev/null
+#ifndef TYPE_H
+#define TYPE_H
+
+#include <string>
+#include <typeinfo>
+#include "gc.h"
+
+class Type : public gc_obj
+{
+ public:
+ Type(void);
+ ~Type(void);
+
+ // Default Type Functionality and Behavior
+ virtual const std::type_info& type(void) const = 0;
+ virtual const std::string toString(void) const = 0;
+ const Type* value(void) const;
+
+ // Overloaded Operators
+ bool operator == (const Type& right) const;
+ bool operator != (const Type& right) const;
+ friend std::ostream& operator << (std::ostream &out, Type& type);
+};
+
+typedef gc_ptr<Type> type_ptr;
+
+#endif
--- /dev/null
+#include <typeinfo>
+#include <sstream>
+#include <cstdlib>
+#include "vector.h"
+
+VectorIndexException out_of_bounds;
+
+Vector::Vector(int count, ...) : start(NULL), end(NULL)
+{
+ va_list arg_list;
+ int i = 0;
+ start = new type_ptr[count];
+ end = &start[count-1];
+
+ va_start (arg_list, count);
+ for (i = 0; i < count; i++)
+ {
+ start[i] = va_arg(arg_list, Type*);
+ }
+ va_end(arg_list);
+}
+
+Vector::~Vector(void)
+{
+ delete [] start;
+}
+
+const std::type_info& Vector::type(void) const
+{
+ return typeid(this);
+}
+
+const std::string Vector::toString(void) const
+{
+ std::ostringstream oss;
+ oss << "<" << type().name() << ":" << this << ">";
+ return oss.str();
+}
+
+const type_ptr& Vector::operator [] (unsigned int index) const
+{
+ return start[index];
+}
+
--- /dev/null
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include <exception>
+#include <stdarg.h>
+#include "type.h"
+
+class VectorIndexException : public std::exception
+{
+ virtual const char* what() const throw()
+ {
+ return "VectorIndexException: Vector index was out of bounds.";
+ }
+};
+
+class Vector : public Type {
+ protected:
+ type_ptr* start;
+ type_ptr* end;
+ public:
+ Vector(int count, ...);
+ ~Vector(void);
+ const std::type_info& type(void) const;
+ const std::string toString(void) const;
+ const type_ptr& operator [] (unsigned int index) const;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include "runtime.h"
+#include "cork.h"
+
+using namespace std;
+
+void test_vectors(void)
+{
+ type_ptr foo = _new Vector(3, _new Atom(), _new Atom(), _new Atom());
+}
+
+void test_atoms(void)
+{
+ Atom foo;
+ Atom True;
+ if(foo.value() == foo.value()) cout << "yes!" << endl;
+ if(foo == foo) cout << "yes!" << endl;
+ if(foo == True) cout << "yes!" << endl;
+ if(foo.value() == True.value()) cout << "yes!" << endl;
+ cout << foo << endl;
+ cout << sizeof(foo) << endl;
+ cout << sizeof(Atom) << endl;
+}
+
+void test_gc(void)
+{
+ type_ptr ref1( _new Atom() );
+ type_ptr ref2(_new Atom());
+ type_ptr ref3(ref2);
+ type_ptr ref4( _new List(_new Atom(), 0) );
+
+ Atom foo1 = *(cast<Atom>(ref2.value()));
+ Type* t1 = ref2.value();
+ Atom* t2 = cast<Atom>(t1);
+ (void)t2;
+
+ try
+ {
+ type_ptr ref((Atom*)0);
+ Atom foo = *(cast<Atom>(ref.value()));
+ (void) foo;
+ }
+ catch(exception& e)
+ {
+ cout << e.what() << endl;
+ }
+
+ // Explicit heap allocation is disallowed:
+ //type_ptr* foo = _new Ref<Atom>(_new Atom());
+}
+
+void test_lists(void)
+{
+ type_ptr foo( _new List( 2, _new Atom(), _new Atom() ) );
+ cout << *foo << endl;
+ cout << foo->toString() << endl;
+}
+
+void test_nums(void)
+{
+ type_ptr a = _new Num(2);
+ type_ptr b = _new Num(3);
+
+ type_ptr c = *(cast<Num>(a)) + *(cast<Num>(b));
+ cout << "2 + 3 = " << *c << endl;
+
+ type_ptr d = *(cast<Num>(a)) - *(cast<Num>(b));
+ cout << "2 - 3 = " << *d << endl;
+
+ type_ptr e = *(cast<Num>(a)) * *(cast<Num>(b));
+ cout << "2 * 3 = " << *e << endl;
+
+ type_ptr f = *(cast<Num>(a)) / *(cast<Num>(b));
+ cout << "2 / 3 = " << *f << endl;
+}
+
+void test_funcs(void)
+{
+}
+
+int main(int argc, char** argv)
+{
+ test_vectors();
+ test_atoms();
+ test_lists();
+ test_gc();
+
+ test_nums();
+ test_funcs();
+
+ REPORT_LEAKS();
+ return 0;
+}
--- /dev/null
+PROJECT_ROOT = File.expand_path(File.dirname(__FILE__))
+
+# Application
+APP_NAME = 'stdlib'
+STATIC_APP_OUT = "#{APP_NAME}.a"
+SHARED_APP_OUT = "#{APP_NAME}.so"
+
+# Compiler Settings
+COMPILER_BIN = 'g++'
+COMPILER_OPTS = '-c -Wall -Werror'
+
+# Linker Settings
+STATIC_LINKER_BIN = 'ar'
+STATIC_LINKER_OPTS = 'rvs'
+SHARED_LINKER_BIN = 'g++'
+SHARED_LINKER_OPTS = '-shared -o'
+
+# Source Code Settings
+SRC_FILES = FileList['src/**/*.c*']
+INCLUDE_DIRS = FileList['src/**/']
+DEFINES = [
+ 'DETECT_MEM_LEAKS'
+]
+
+# Generated Lists
+OBJ_FILES = SRC_FILES.collect{|src| "build/#{File.basename(src).ext('o')}" }
+DEFINE_LIST = DEFINES.collect{|define| "-D#{define}" }
+INCLUDE_LIST = INCLUDE_DIRS.collect{|x| "-I#{x} "}
+
+# Clean Task
+CLEAN.include( 'build/*.o' )
+CLEAN.include( STATIC_APP_OUT )
+CLEAN.include( SHARED_APP_OUT )
+
--- /dev/null
+./src/gc/gc.cpp
+./src/gc/gc.h
+./src/runtime.c
+./src/runtime.h
+./src/type/array/array.cpp
+./src/type/array/array.h
+./src/type/atom/atom.cpp
+./src/type/atom/atom.h
+./src/type/func/func.cpp
+./src/type/func/func.h
+./src/type/list/list.cpp
+./src/type/list/list.h
+./src/type/map/map.cpp
+./src/type/map/map.h
+./src/type/num/num.cpp
+./src/type/num/num.h
+./src/type/ref/ref.cpp
+./src/type/ref/ref.h
+./src/type/type.cpp
+./src/type/type.h
+./test/test_main.cpp
--- /dev/null
+require 'rake'
+require 'rake/clean'
+
+# Load the dependencies
+load 'config.rake'
+
+task :default => [:release]
+task :release => [STATIC_APP_OUT, SHARED_APP_OUT]
+
+# Find and compile all source files
+def FindSourceByObj(obj)
+ return SRC_FILES.find { |s|
+ (File.basename(s, '.c') == File.basename(obj, '.o')) ||
+ (File.basename(s, '.cpp') == File.basename(obj, '.o'))
+ }
+end
+rule '.o' => lambda{|obj| FindSourceByObj(obj) } do |t|
+ sh "#{COMPILER_BIN} #{COMPILER_OPTS} #{INCLUDE_LIST} #{DEFINE_LIST} -o #{t.name} #{t.source}"
+end
+
+# Link the object files together
+task STATIC_APP_OUT => OBJ_FILES do
+ puts "Linking #{STATIC_APP_OUT}..."
+ sh "#{STATIC_LINKER_BIN} #{STATIC_LINKER_OPTS} #{STATIC_APP_OUT} #{OBJ_FILES.collect{|x| x + ' '}}"
+end
+
+task SHARED_APP_OUT => OBJ_FILES do
+ puts "Linking #{SHARED_APP_OUT}..."
+ sh "#{SHARED_LINKER_BIN} #{SHARED_LINKER_OPTS} #{SHARED_APP_OUT} #{OBJ_FILES.collect{|x| x + ' '}}"
+end
+
+task :test => OBJ_FILES do
+ puts "compiling test_main..."
+ sh "#{COMPILER_BIN} #{COMPILER_OPTS} #{INCLUDE_LIST} #{DEFINE_LIST} -o build/test_main.o test/test_main.cpp"
+ puts "Linking test_runner.exe..."
+ sh "#{SHARED_LINKER_BIN} -o test_runner.exe #{OBJ_FILES.collect{|x| x + ' '}} build/test_main.o"
+end
--- /dev/null
+#include "cork.h"
+
+#ifdef DETECT_MEM_LEAKS
+
+// We want to use the real malloc and free in this file
+#undef malloc
+#undef free
+
+#include <iostream>
+#include <exception> // for std::bad_alloc
+#include <cstdlib> // for malloc() and free()
+#include <string.h>
+
+// Set the namespace
+using namespace std;
+/******************************************************************************
+ * Typedefs
+ *****************************************************************************/
+typedef struct BlockTableEntry
+{
+ void * ptr;
+ unsigned int size;
+ const char* file;
+ int line;
+ void * next;
+} BlockTableEntry_T;
+
+typedef struct BlockTable
+{
+ unsigned int size;
+ BlockTableEntry_T* blocks[TBL_SIZE];
+} BlockTable_T;
+
+/******************************************************************************
+ * Prototypes
+ *****************************************************************************/
+void insert_record(void * ptr, BlockTable_T* entry);
+void erase_record(void * ptr);
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+unsigned int allocated;
+static BlockTable_T Block_Table = { 0, {0} };
+
+/******************************************************************************
+ * Function Definitions
+ *****************************************************************************/
+void insert_record(void * ptr, BlockTableEntry_T* entry)
+{
+ unsigned int index = ((unsigned int)ptr) % TBL_SIZE;
+ BlockTableEntry_T* last = Block_Table.blocks[ index ];
+ BlockTableEntry_T* curr = last;
+
+ while (curr != NULL)
+ {
+ if ( curr->ptr == ptr )
+ {
+ curr->size = entry->size;
+ free(entry);
+ break;
+ }
+ last = curr;
+ curr = (BlockTableEntry_T*)curr->next;
+ }
+
+ if(curr == NULL)
+ {
+ if (last != NULL)
+ {
+ last->next = entry;
+ }
+ else
+ {
+ Block_Table.blocks[index] = entry;
+ }
+ Block_Table.size++;
+ }
+}
+
+void erase_record(void * ptr)
+{
+ int depth = 0;
+ unsigned int index = ((unsigned int)ptr) % TBL_SIZE;
+ BlockTableEntry_T* last = Block_Table.blocks[ index ];
+ BlockTableEntry_T* curr = last;
+
+ while( curr != NULL )
+ {
+ depth = 1;
+ if( curr->ptr == ptr )
+ {
+ depth = 2;
+ if(last == curr)
+ {
+ depth = 3;
+ Block_Table.blocks[ index ] = (BlockTableEntry_T*)curr->next;
+ }
+ else
+ {
+ depth = 4;
+ last->next = curr->next;
+ }
+ free(curr);
+ Block_Table.size--;
+ break;
+ }
+ last = curr;
+ curr = (BlockTableEntry_T*)curr->next;
+ }
+}
+
+void Cork_ReportMemoryLeaks(void)
+{
+ unsigned int index = 0;
+ cout << "-----------------------------------------------------------------" << endl;
+ cout << "Cork: Memory Allocation Analysis" << endl;
+ cout << "-----------------------------------------------------------------" << endl;
+ cout << "You have " << Block_Table.size << " Unclaimed objects." << endl;
+
+ for(; index < TBL_SIZE; index++)
+ {
+ BlockTableEntry_T* entry = Block_Table.blocks[ index ];
+ while(entry != NULL)
+ {
+ cout << "\t" << entry->size << "\t" << entry->ptr;
+ if( entry->file != NULL )
+ {
+ cout << "\t" << entry->line << "\t" << entry->file;
+ }
+ cout << endl;
+ entry = (BlockTableEntry_T*)entry->next;
+ }
+ }
+}
+
+void * operator new (size_t size, string file, unsigned int line)
+{
+ void * ptr = malloc(size);
+ char * fname = (char*)malloc(file.length());
+ if(ptr == NULL)
+ {
+ throw bad_alloc();
+ }
+ else
+ {
+ BlockTableEntry_T* entry = (BlockTableEntry_T*)malloc(sizeof(BlockTableEntry_T));
+ strcpy( fname, file.c_str() );
+ entry->ptr = ptr;
+ entry->size = size;
+ entry->file = fname;
+ entry->line = line;
+ entry->next = NULL;
+ insert_record(ptr,entry);
+ }
+ return ptr;
+}
+
+void * operator new(size_t size) throw(bad_alloc) {
+ void * ptr = malloc(size);
+ if(ptr == NULL)
+ {
+ throw bad_alloc();
+ }
+ else
+ {
+ BlockTableEntry_T* entry = (BlockTableEntry_T*)malloc(sizeof(BlockTableEntry_T));
+ entry->ptr = ptr;
+ entry->size = size;
+ entry->file = NULL;
+ entry->line = 0;
+ entry->next = NULL;
+ insert_record(ptr,entry);
+ }
+ return ptr;
+}
+
+void operator delete(void * p) {
+ free(p);
+ erase_record(p);
+}
+
+#endif
--- /dev/null
+#ifndef CORK_H
+#define CORK_H
+
+#ifdef DETECT_MEM_LEAKS
+ #include <string>
+ typedef unsigned int size_t;
+
+ void Cork_ReportMemoryLeaks(void);
+ void * operator new (size_t size, std::string file, unsigned int line);
+ #define TBL_SIZE 512
+ #define REPORT_LEAKS() Cork_ReportMemoryLeaks()
+ #define _new new (__FILE__,__LINE__)
+#else
+ #define REPORT_LEAKS()
+ #define _new new
+#endif
+
+#endif
--- /dev/null
+#include "ref.h"
+#include "type.h"
+
+#include <iostream>
+
+gc_ptr::gc_ptr(Type* p) : ptr(p)
+{
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ }
+}
+
+gc_ptr::gc_ptr(const gc_ptr& right) : ptr(right.ptr)
+{
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ }
+}
+
+gc_ptr::~gc_ptr()
+{
+ if (ptr != 0)
+ {
+ ptr->decRefCount();
+ }
+}
+
+Type* gc_ptr::value(void)
+{
+ return ptr;
+}
+
+gc_ptr& gc_ptr::operator = (gc_ptr& right)
+{
+ ptr->decRefCount();
+ ptr = right.value();
+ ptr->incRefCount();
+ return *this;
+}
+
+gc_ptr& gc_ptr::operator = (Type* right)
+{
+ ptr->decRefCount();
+ ptr = right;
+ ptr->incRefCount();
+ return *this;
+}
+
+Type& gc_ptr::operator * (void)
+{
+ return *ptr;
+}
+
+Type* gc_ptr::operator -> (void)
+{
+ return ptr;
+}
+
--- /dev/null
+#ifndef REF_H
+#define REF_H
+
+#include <typeinfo>
+#include <string>
+#include <exception>
+#include "type.h"
+
+class NullRefException : public std::exception
+{
+ virtual const char* what() const throw()
+ {
+ return "Null Reference: A pointer was used without being initialized";
+ }
+};
+
+class gc_ptr {
+ protected:
+ Type* ptr;
+ private:
+ // Disallow direct instantiation on the heap
+ void*operator new( size_t );
+ void* operator new[]( size_t );
+ void operator delete( void* );
+ void operator delete[]( void* );
+ public:
+ gc_ptr(Type* p = 0);
+ gc_ptr(const gc_ptr& right);
+ ~gc_ptr();
+ Type* value(void);
+ gc_ptr& operator = (gc_ptr& right);
+ gc_ptr& operator = (Type* right);
+ Type& operator * (void);
+ Type* operator -> (void);
+};
+
+#endif
--- /dev/null
+#include "ref.h"
+#include "type.h"
+
+#include <iostream>
+
+gc_ptr::gc_ptr(Type* p) : ptr(p)
+{
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ }
+}
+
+gc_ptr::gc_ptr(const gc_ptr& right) : ptr(right.ptr)
+{
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ }
+}
+
+gc_ptr::~gc_ptr()
+{
+ if (ptr != 0)
+ {
+ ptr->decRefCount();
+ }
+}
+
+Type* gc_ptr::value(void)
+{
+ return ptr;
+}
+
+gc_ptr& gc_ptr::operator = (gc_ptr& right)
+{
+ ptr->decRefCount();
+ ptr = right.value();
+ ptr->incRefCount();
+ return *this;
+}
+
+gc_ptr& gc_ptr::operator = (Type* right)
+{
+ ptr->decRefCount();
+ ptr = right;
+ ptr->incRefCount();
+ return *this;
+}
+
+Type& gc_ptr::operator * (void)
+{
+ return *ptr;
+}
+
+Type* gc_ptr::operator -> (void)
+{
+ return ptr;
+}
+
--- /dev/null
+#ifndef REF_H
+#define REF_H
+
+#include <typeinfo>
+#include <string>
+#include <exception>
+#include "type.h"
+
+class NullRefException : public std::exception
+{
+ virtual const char* what() const throw()
+ {
+ return "Null Reference: A pointer was used without being initialized";
+ }
+};
+
+class gc_ptr {
+ protected:
+ Type* ptr;
+ private:
+ // Disallow direct instantiation on the heap
+ void*operator new( size_t );
+ void* operator new[]( size_t );
+ void operator delete( void* );
+ void operator delete[]( void* );
+ public:
+ gc_ptr(Type* p = 0);
+ gc_ptr(const gc_ptr& right);
+ ~gc_ptr();
+ Type* value(void);
+ gc_ptr& operator = (gc_ptr& right);
+ gc_ptr& operator = (Type* right);
+ Type& operator * (void);
+ Type* operator -> (void);
+};
+
+#endif
--- /dev/null
+#include "ref.h"
+#include "type.h"
+
+#include <iostream>
+gc_ptr::gc_ptr(Type* p) : ptr(p)
+{
+ std::cout << "created" << std::endl;
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ std::cout << "c_ref " << ptr->ref_count << std::endl;
+ }
+}
+
+gc_ptr::gc_ptr(const gc_ptr& right) : ptr(right.ptr)
+{
+ std::cout << "created" << std::endl;
+ if (ptr != 0)
+ {
+ ptr->incRefCount();
+ std::cout << "c_ref " << ptr->ref_count << std::endl;
+ }
+}
+
+gc_ptr::~gc_ptr()
+{
+ std::cout << "deleted" << std::endl;
+ if (ptr != 0)
+ {
+ std::cout << "b_ref " << ptr->ref_count << std::endl;
+ ptr->decRefCount();
+ std::cout << "a_ref " << ptr->ref_count << std::endl;
+ }
+}
+
+Type* gc_ptr::value(void)
+{
+ return ptr;
+}
+
+gc_ptr& gc_ptr::operator = (gc_ptr& right)
+{
+ ptr->decRefCount();
+ ptr = right.value();
+ ptr->incRefCount();
+ return *this;
+}
+
+gc_ptr& gc_ptr::operator = (Type* right)
+{
+ ptr->decRefCount();
+ ptr = right;
+ ptr->incRefCount();
+ return *this;
+}
+
+Type& gc_ptr::operator * (void)
+{
+ return *ptr;
+}
+
+Type* gc_ptr::operator -> (void)
+{
+ return ptr;
+}
+
+std::string gc_ptr::type(void)
+{
+ return typeid(this).name();
+}
+
+
--- /dev/null
+#ifndef REF_H
+#define REF_H
+
+#include <typeinfo>
+#include <string>
+#include <exception>
+#include "type.h"
+
+class NullRefException : public std::exception
+{
+ virtual const char* what() const throw()
+ {
+ return "Null Reference: A pointer was used without being initialized";
+ }
+};
+
+class gc_ptr {
+ protected:
+ Type* ptr;
+ private:
+ // Disallow direct instantiation on the heap
+ void*operator new( size_t );
+ void* operator new[]( size_t );
+ void operator delete( void* );
+ void operator delete[]( void* );
+ public:
+ gc_ptr(Type* p = 0);
+ gc_ptr(const gc_ptr& right);
+ ~gc_ptr();
+ Type* value(void);
+ gc_ptr& operator = (gc_ptr& right);
+ gc_ptr& operator = (Type* right);
+ Type& operator * (void);
+ Type* operator -> (void);
+ std::string type(void);
+};
+
+#endif
--- /dev/null
+#include "runtime.h"
+
--- /dev/null
+#ifndef RUNTIME_H
+#define RUNTIME_H
+
+#include "type.h"
+#include "ref.h"
+#include "atom.h"
+//#include "func.h"
+#include "list.h"
+//#include "array.h"
+
+extern Atom True;
+extern Atom False;
+extern Atom Nil;
+
+#endif
--- /dev/null
+#include <string>
+#include <typeinfo>
+#include "atom.h"
+
+
+std::string Atom::type(void)
+{
+ return typeid(this).name();
+}
--- /dev/null
+#ifndef ATOM_H
+#define ATOM_H
+
+#include "type.h"
+
+class Atom : public Type {
+ public:
+ ~Atom(){ std::cout << "Deconstructing Atom: " << this << std::endl; }
+ std::string type(void);
+};
+
+#endif
--- /dev/null
+#include <typeinfo>
+#include "list.h"
+
+List::List(Type* hd, List* tl) : lst_head(hd), lst_tail(tl)
+{
+}
+
+std::string List::type(void)
+{
+ return typeid(this).name();
+}
+
+const gc_ptr& List::head(void) const
+{
+ return lst_head;
+}
+
+const gc_ptr& List::tail(void) const
+{
+ return lst_tail;
+}
+
--- /dev/null
+#ifndef LIST_H
+#define LIST_H
+
+#include <stdarg.h>
+#include "type.h"
+#include "ref.h"
+
+class List : public Type
+{
+ protected:
+ gc_ptr lst_head;
+ gc_ptr lst_tail;
+ public:
+ List(Type* hd, List* tl);
+ List(int count, ...);
+ ~List(){ std::cout << "Deconstructing List: " << this << std::endl; }
+ std::string type(void);
+ const gc_ptr& head(void) const;
+ const gc_ptr& tail(void) const;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <sstream>
+#include "type.h"
+
+/******************************************************************************
+ * Constructors and Destructors
+ *****************************************************************************/
+Type::Type() : ref_count(0)
+{
+}
+
+//Type::~Type()
+//{
+//}
+
+/******************************************************************************
+ * Garbage Collection Methods
+ *****************************************************************************/
+int Type::refCount(void)
+{
+ return ref_count;
+}
+
+void Type::incRefCount(void)
+{
+ ++ref_count;
+}
+
+void Type::decRefCount(void)
+{
+ std::cout << "removing ref" << std::endl;
+ if((--ref_count) == 0)
+ {
+ std::cout << "deleting self" << std::endl;
+ delete this;
+ }
+}
+
+/******************************************************************************
+ * Type Related Methods
+ *****************************************************************************/
+const Type* Type::value(void) const
+{
+ return this;
+}
+
+
+const std::type_info& Type::type(void) const
+{
+ return typeid(this);
+}
+
+std::string Type::toString(void) const
+{
+ std::ostringstream oss;
+ oss << "<" << type().name() << ":" << this << ">";
+ return oss.str();
+}
+
+/******************************************************************************
+ * Operators
+ *****************************************************************************/
+bool Type::operator == (const Type& right) const
+{
+ return (this == &right) || (value() == right.value());
+}
+
+bool Type::operator != (const Type& right) const
+{
+ return (this != &right) || (value() != right.value());
+}
+
+std::ostream& operator << (std::ostream &out, Type& type)
+{
+ out << type.toString();
+ return out;
+}
+
--- /dev/null
+#ifndef TYPE_H
+#define TYPE_H
+
+#include <string>
+#include <typeinfo>
+#include <iostream>
+
+class gc_ptr;
+class Type
+{
+ protected:
+ int ref_count;
+ private:
+ // Garbage Collection Methods
+ int refCount(void);
+ void incRefCount(void);
+ void decRefCount(void);
+
+ // Make sure References can access the garbage collection methods
+ friend class gc_ptr;
+ public:
+ Type();
+ virtual ~Type() { std::cout << "Deconstructing Type: " << this << std::endl; };
+ // Default Type Functionality and Behavior
+ const Type* value(void) const;
+ const std::type_info& type(void) const;
+ virtual std::string type(void) = 0;
+ std::string toString(void) const;
+ bool operator == (const Type& right) const;
+ bool operator != (const Type& right) const;
+ friend std::ostream& operator << (std::ostream &out, Type& type);
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include "runtime.h"
+#include "cork.h"
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ {
+ gc_ptr foo1( _new Atom() );
+ gc_ptr foo2(
+ _new List(
+ _new Atom(),
+ _new List(
+ _new Atom(),
+ 0 )));
+ }
+ REPORT_LEAKS();
+ return 0;
+}
--- /dev/null
+import serial
+
+# Constants
+ACK = chr(0x01)
+INIT = chr(0x55)
+
+def init(port,baud):
+ conn = serial.Serial(port - 1)
+ conn.baudrate = baud
+ conn.timeout = 1
+
+ # try sending the magic byte a few times to see if we get a response
+ success = False
+ tries = 10
+ while tries > 0:
+ conn.write( INIT )
+ success = recv_ack(conn)
+ if success:
+ tries = 0
+ else:
+ tries -= 1
+
+ if not success:
+ raise "Could not communicate with device"
+
+ return conn
+
+def send(conn,byte):
+ ack_byte = None
+ conn.write( chr(byte) )
+ return recv_ack( conn )
+
+def recv_ack(conn):
+ ack_byte = conn.read()
+ if (ack_byte == ACK):
+ return True
+ else:
+ return False
+
--- /dev/null
+import pygame
+from pygame.locals import *
+
+# State of all Buttons and Axes on the controller
+state = {
+ 'buttons': {
+ 'A': 0,
+ 'B': 0,
+ 'X': 0,
+ 'Y': 0,
+ 'LB': 0,
+ 'RB': 0,
+ 'BACK': 0,
+ 'START': 0,
+ 'LS': 0,
+ 'RS': 0,
+ },
+ 'dpad': (0,0),
+ 'left_stick': {
+ 'x': 0,
+ 'y': 0
+ },
+ 'right_stick': {
+ 'x': 0,
+ 'y': 0
+ },
+ 'trigger': 0
+}
+
+# Queue of button events
+button_events = []
+
+# Button ID 0 1 2 3 4 5 6 7 8 9
+button_id_lookup = [ 'A', 'B', 'X', 'Y', 'LB', 'RB', 'BACK', 'START', 'LS', 'RS' ]
+
+def handleButtonUp(event):
+ btn_name = button_id_lookup[event.button]
+ state['buttons'][ btn_name ] = 0
+
+def handleButtonDown(event):
+ btn_name = button_id_lookup[event.button]
+ state['buttons'][ btn_name ] = 1
+
+def handleJoyAxisMotion(event):
+ if (event.axis == 0):
+ state['left_stick']['x'] = event.value
+ elif (event.axis == 1):
+ state['left_stick']['y'] = event.value
+ elif (event.axis == 2):
+ state['trigger'] = event.value
+ elif (event.axis == 3):
+ state['right_stick']['y'] = event.value
+ elif (event.axis == 4):
+ state['right_stick']['x'] = event.value
+
+def handleJoyHatMotion(event):
+ state['dpad'] = event.value
+
+# process queued events
+def processEvents():
+ events = pygame.event.get()
+ for event in events:
+ if event.type == JOYAXISMOTION:
+ handleJoyAxisMotion(event)
+ elif event.type == JOYHATMOTION:
+ handleJoyHatMotion(event)
+ elif event.type == JOYBUTTONDOWN:
+ handleButtonDown(event)
+ elif event.type == JOYBUTTONUP:
+ handleButtonUp(event)
+ else:
+ print("Unhandled event: ", event)
+
+def get_state():
+ return state
+
+# System initialization
+def init():
+ pygame.init()
+ if pygame.joystick.get_count() > 0:
+ gamepad = pygame.joystick.Joystick(0)
+ gamepad.init()
+ else:
+ raise "No joystick connected"
+
+def quit():
+ pygame.quit()
+
--- /dev/null
+import controller
+import comm
+import time
+import math
+
+def update_servo_pos(conn):
+ state = controller.get_state()
+ new_pos = int((-1 * math.degrees( math.asin( state['trigger'] ) )) + 90)
+ print new_pos
+ comm.send(conn,new_pos)
+
+# Main entry
+if __name__ == "__main__":
+ conn = comm.init(6,115200)
+ controller.init()
+ while True:
+ controller.processEvents()
+ update_servo_pos(conn)
+ conn.close()
+
--- /dev/null
+;------------------------------------------------------------------------------
+; Associative Arrays (aka Tables)
+;------------------------------------------------------------------------------
+; entry? - determines whether the argument is a table entry
+(define entry? pair?)
+
+; entry - constructs a new table entry from the key and value passed in
+(define entry cons)
+
+; table? - determines whether the argument is a table
+(define table? list?)
+
+; table - constructs a new table from 0 or more entries
+(define table list)
+
+; table-get - retrieves a value from the table for the corresponding key
+(define (table-get tbl key)
+ (if (null? tbl)
+ '()
+ (let*
+ ((e (car tbl))
+ (k (car e))
+ (v (cdr e)))
+ (if (equal? k key)
+ v
+ (table-get (cdr tbl) key) ))))
+
+; table-put - associates a value with a specific key and stores it in the table
+(define (table-put tbl key val)
+ (if (null? tbl)
+ (table (entry key val))
+ (let*
+ ((e (car tbl))
+ (k (car e))
+ (v (cdr e)))
+ (if (equal? k key)
+ (cons (entry key val) (cdr tbl))
+ (if (null? (cdr tbl))
+ (table e (entry key val))
+ (cons e (table-put (cdr tbl) key val)) )))))
+
+;------------------------------------------------------------------------------
+; Scope Chain (Symbol Table)
+;------------------------------------------------------------------------------
+(define (scope-start!)
+ (set! symbol-table (cons (table) symbol-table)))
+
+(define (scope-end!)
+ (set! symbol-table (cdr symbol-table)))
+
+(define (scope-register! sym val)
+ (set! symbol-table
+ (cons
+ (table-put (car symbol-table) sym val)
+ (cdr symbol-table) )))
+
+(define (scope-resolve tbl key)
+ (if (not (null? tbl))
+ (let*
+ ((scp (car tbl))
+ (val (table-get scp key)))
+ (if (not (null? val))
+ val
+ (if (not (null? (cdr tbl)))
+ (scope-resolve (cdr tbl) key) )))))
+
+;------------------------------------------------------------------------------
+; Symbol Table
+;------------------------------------------------------------------------------
+(define symbol-table (list (table)))
+
+; Global Scope
+(scope-register! "foo1" "bar1")
+(scope-register! "foo2" "bar2")
+(scope-register! "foo3" "bar3")
+(print "Symbol Table:")
+(print symbol-table)
+(print)
+
+(print "Access bindings for Global Scope")
+(print (scope-resolve symbol-table "foo1"))
+(print (scope-resolve symbol-table "foo2"))
+(print (scope-resolve symbol-table "foo3"))
+(print (scope-resolve symbol-table "foo4"))
+(print (scope-resolve symbol-table "foo5"))
+
+(print "Local Scope")
+(scope-start!)
+
+(scope-register! "foo1" "bar1_1")
+(scope-register! "foo4" "bar4")
+(print "Symbol Table:")
+(print symbol-table)
+(print)
+
+(print "Access bindings for Local Scope")
+(print (scope-resolve symbol-table "foo1"))
+(print (scope-resolve symbol-table "foo2"))
+(print (scope-resolve symbol-table "foo3"))
+(print (scope-resolve symbol-table "foo4"))
+(print (scope-resolve symbol-table "foo5"))
+
+(print "Nested Local Scope")
+(scope-start!)
+
+(scope-register! "foo1" "bar1_2")
+(scope-register! "foo5" "bar5")
+(print "Symbol Table:")
+(print symbol-table)
+(print)
+
+(print "Access bindings for Nested Local Scope")
+(print (scope-resolve symbol-table "foo1"))
+(print (scope-resolve symbol-table "foo2"))
+(print (scope-resolve symbol-table "foo3"))
+(print (scope-resolve symbol-table "foo4"))
+(print (scope-resolve symbol-table "foo5"))
+
+(scope-end!)
+(print "Access bindings for Local Scope")
+(print (scope-resolve symbol-table "foo1"))
+(print (scope-resolve symbol-table "foo2"))
+(print (scope-resolve symbol-table "foo3"))
+(print (scope-resolve symbol-table "foo4"))
+(print (scope-resolve symbol-table "foo5"))
+
+(scope-end!)
+(print "Access bindings for Global Scope")
+(print (scope-resolve symbol-table "foo1"))
+(print (scope-resolve symbol-table "foo2"))
+(print (scope-resolve symbol-table "foo3"))
+(print (scope-resolve symbol-table "foo4"))
+(print (scope-resolve symbol-table "foo5"))
+
+(exit)