]> git.mdlowis.com Git - archive/bitbucket.git/commitdiff
Initial Commit
authorMike D. Lowis <mike@mdlowis.com>
Sun, 12 Feb 2012 02:49:46 +0000 (21:49 -0500)
committerMike D. Lowis <mike@mdlowis.com>
Sun, 12 Feb 2012 02:49:46 +0000 (21:49 -0500)
82 files changed:
arduino/revcomm/revcomm.ino [new file with mode: 0644]
arduino/servo_test/servo_test.ino [new file with mode: 0644]
clojure/dsl.clj [new file with mode: 0644]
clojure/euler/euler1.clj [new file with mode: 0644]
clojure/euler/euler3.clj [new file with mode: 0644]
clojure/lex.clj [new file with mode: 0644]
clojure/lexer/.gitignore [new file with mode: 0644]
clojure/lexer/README [new file with mode: 0644]
clojure/lexer/project.clj [new file with mode: 0644]
clojure/lexer/src/lexer/core.clj [new file with mode: 0644]
clojure/lexer/test/lexer/test/core.clj [new file with mode: 0644]
clojure/parse.clj [new file with mode: 0644]
lang_design/recursive/config.rake [new file with mode: 0644]
lang_design/recursive/parser.exe [new file with mode: 0644]
lang_design/recursive/rakefile.rb [new file with mode: 0644]
lang_design/recursive/src/ast/ast.cpp [new file with mode: 0644]
lang_design/recursive/src/ast/ast.h [new file with mode: 0644]
lang_design/recursive/src/lexer/lexer.cpp [new file with mode: 0644]
lang_design/recursive/src/lexer/lexer.h [new file with mode: 0644]
lang_design/recursive/src/lexer/token/token.cpp [new file with mode: 0644]
lang_design/recursive/src/lexer/token/token.h [new file with mode: 0644]
lang_design/recursive/src/main.cpp [new file with mode: 0644]
lang_design/recursive/src/parsers/llkparser/llkparser.cpp [new file with mode: 0644]
lang_design/recursive/src/parsers/llkparser/llkparser.h [new file with mode: 0644]
lang_design/recursive/src/sexp/sexp.cpp [new file with mode: 0644]
lang_design/recursive/src/sexp/sexp.h [new file with mode: 0644]
lang_design/recursive/src/visitor/visitor.cpp [new file with mode: 0644]
lang_design/recursive/src/visitor/visitor.h [new file with mode: 0644]
lang_design/runtime/DELETE/ref/ref.h [new file with mode: 0644]
lang_design/runtime/config.rake [new file with mode: 0644]
lang_design/runtime/findex.dat [new file with mode: 0644]
lang_design/runtime/rakefile.rb [new file with mode: 0644]
lang_design/runtime/src/cast.h [new file with mode: 0644]
lang_design/runtime/src/cork/cork.cpp [new file with mode: 0644]
lang_design/runtime/src/cork/cork.h [new file with mode: 0644]
lang_design/runtime/src/gc/gc.h [new file with mode: 0644]
lang_design/runtime/src/gc/gc_obj/gc_obj.cpp [new file with mode: 0644]
lang_design/runtime/src/gc/gc_obj/gc_obj.h [new file with mode: 0644]
lang_design/runtime/src/gc/gc_ptr/gc_ptr.cpp [new file with mode: 0644]
lang_design/runtime/src/gc/gc_ptr/gc_ptr.h [new file with mode: 0644]
lang_design/runtime/src/runtime.c [new file with mode: 0644]
lang_design/runtime/src/runtime.h [new file with mode: 0644]
lang_design/runtime/src/type/atom/atom.cpp [new file with mode: 0644]
lang_design/runtime/src/type/atom/atom.h [new file with mode: 0644]
lang_design/runtime/src/type/func/func.cpp [new file with mode: 0644]
lang_design/runtime/src/type/func/func.h [new file with mode: 0644]
lang_design/runtime/src/type/list/list.cpp [new file with mode: 0644]
lang_design/runtime/src/type/list/list.h [new file with mode: 0644]
lang_design/runtime/src/type/num/num.cpp [new file with mode: 0644]
lang_design/runtime/src/type/num/num.h [new file with mode: 0644]
lang_design/runtime/src/type/type.cpp [new file with mode: 0644]
lang_design/runtime/src/type/type.h [new file with mode: 0644]
lang_design/runtime/src/type/vector/vector.cpp [new file with mode: 0644]
lang_design/runtime/src/type/vector/vector.h [new file with mode: 0644]
lang_design/runtime/test/test_main.cpp [new file with mode: 0644]
lang_design/runtime/test_runner.exe [new file with mode: 0644]
lang_design/runtime_debug/config.rake [new file with mode: 0644]
lang_design/runtime_debug/findex.dat [new file with mode: 0644]
lang_design/runtime_debug/rakefile.rb [new file with mode: 0644]
lang_design/runtime_debug/src/cork/cork.cpp [new file with mode: 0644]
lang_design/runtime_debug/src/cork/cork.h [new file with mode: 0644]
lang_design/runtime_debug/src/gc/gc.h [new file with mode: 0644]
lang_design/runtime_debug/src/gc/gc_obj/gc_obj.cpp [new file with mode: 0644]
lang_design/runtime_debug/src/gc/gc_obj/gc_obj.h [new file with mode: 0644]
lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.cpp [new file with mode: 0644]
lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.h [new file with mode: 0644]
lang_design/runtime_debug/src/ref/ref.cpp [new file with mode: 0644]
lang_design/runtime_debug/src/ref/ref.h [new file with mode: 0644]
lang_design/runtime_debug/src/runtime.c [new file with mode: 0644]
lang_design/runtime_debug/src/runtime.h [new file with mode: 0644]
lang_design/runtime_debug/src/type/atom/atom.cpp [new file with mode: 0644]
lang_design/runtime_debug/src/type/atom/atom.h [new file with mode: 0644]
lang_design/runtime_debug/src/type/list/list.cpp [new file with mode: 0644]
lang_design/runtime_debug/src/type/list/list.h [new file with mode: 0644]
lang_design/runtime_debug/src/type/type.cpp [new file with mode: 0644]
lang_design/runtime_debug/src/type/type.h [new file with mode: 0644]
lang_design/runtime_debug/test/test_main.cpp [new file with mode: 0644]
lang_design/runtime_debug/test_runner.exe [new file with mode: 0644]
python/micro/comm.py [new file with mode: 0644]
python/micro/controller.py [new file with mode: 0644]
python/micro/joy.py [new file with mode: 0644]
scheme/assoc_arrays.scm [new file with mode: 0644]

diff --git a/arduino/revcomm/revcomm.ino b/arduino/revcomm/revcomm.ino
new file mode 100644 (file)
index 0000000..f6e1d22
--- /dev/null
@@ -0,0 +1,37 @@
+#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);
+  }
+}
diff --git a/arduino/servo_test/servo_test.ino b/arduino/servo_test/servo_test.ino
new file mode 100644 (file)
index 0000000..72bb5b9
--- /dev/null
@@ -0,0 +1,19 @@
+#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);
+}
diff --git a/clojure/dsl.clj b/clojure/dsl.clj
new file mode 100644 (file)
index 0000000..782b3bb
--- /dev/null
@@ -0,0 +1,52 @@
+(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)) ))
diff --git a/clojure/euler/euler1.clj b/clojure/euler/euler1.clj
new file mode 100644 (file)
index 0000000..6a3f875
--- /dev/null
@@ -0,0 +1,21 @@
+(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 ))))
diff --git a/clojure/euler/euler3.clj b/clojure/euler/euler3.clj
new file mode 100644 (file)
index 0000000..b32b2ab
--- /dev/null
@@ -0,0 +1,33 @@
+(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)
diff --git a/clojure/lex.clj b/clojure/lex.clj
new file mode 100644 (file)
index 0000000..903648f
--- /dev/null
@@ -0,0 +1,49 @@
+(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")))
+
diff --git a/clojure/lexer/.gitignore b/clojure/lexer/.gitignore
new file mode 100644 (file)
index 0000000..b8c1b21
--- /dev/null
@@ -0,0 +1,5 @@
+pom.xml
+*jar
+/lib/
+/classes/
+.lein-deps-sum
diff --git a/clojure/lexer/README b/clojure/lexer/README
new file mode 100644 (file)
index 0000000..67a3f32
--- /dev/null
@@ -0,0 +1,13 @@
+# lexer
+
+FIXME: write description
+
+## Usage
+
+FIXME: write
+
+## License
+
+Copyright (C) 2011 FIXME
+
+Distributed under the Eclipse Public License, the same as Clojure.
diff --git a/clojure/lexer/project.clj b/clojure/lexer/project.clj
new file mode 100644 (file)
index 0000000..9806ec1
--- /dev/null
@@ -0,0 +1,3 @@
+(defproject lexer "1.0.0-SNAPSHOT"
+  :description "FIXME: write description"
+  :dependencies [[org.clojure/clojure "1.1.0"]])
diff --git a/clojure/lexer/src/lexer/core.clj b/clojure/lexer/src/lexer/core.clj
new file mode 100644 (file)
index 0000000..c7512b9
--- /dev/null
@@ -0,0 +1 @@
+(ns lexer.core)
diff --git a/clojure/lexer/test/lexer/test/core.clj b/clojure/lexer/test/lexer/test/core.clj
new file mode 100644 (file)
index 0000000..05100b2
--- /dev/null
@@ -0,0 +1,6 @@
+(ns lexer.test.core
+  (:use [lexer.core])
+  (:use [clojure.test]))
+
+(deftest replace-me ;; FIXME: write
+  (is false "No tests have been written."))
diff --git a/clojure/parse.clj b/clojure/parse.clj
new file mode 100644 (file)
index 0000000..4ccd7fe
--- /dev/null
@@ -0,0 +1,90 @@
+(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")))
+
diff --git a/lang_design/recursive/config.rake b/lang_design/recursive/config.rake
new file mode 100644 (file)
index 0000000..7ce50f4
--- /dev/null
@@ -0,0 +1,29 @@
+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 )
+
diff --git a/lang_design/recursive/parser.exe b/lang_design/recursive/parser.exe
new file mode 100644 (file)
index 0000000..a949163
Binary files /dev/null and b/lang_design/recursive/parser.exe differ
diff --git a/lang_design/recursive/rakefile.rb b/lang_design/recursive/rakefile.rb
new file mode 100644 (file)
index 0000000..c5500c0
--- /dev/null
@@ -0,0 +1,25 @@
+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
diff --git a/lang_design/recursive/src/ast/ast.cpp b/lang_design/recursive/src/ast/ast.cpp
new file mode 100644 (file)
index 0000000..8683e97
--- /dev/null
@@ -0,0 +1,69 @@
+#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);
+}
+
diff --git a/lang_design/recursive/src/ast/ast.h b/lang_design/recursive/src/ast/ast.h
new file mode 100644 (file)
index 0000000..6877fdf
--- /dev/null
@@ -0,0 +1,28 @@
+#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
diff --git a/lang_design/recursive/src/lexer/lexer.cpp b/lang_design/recursive/src/lexer/lexer.cpp
new file mode 100644 (file)
index 0000000..a4e40ef
--- /dev/null
@@ -0,0 +1,57 @@
+#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();
+       }
+}
+
+
diff --git a/lang_design/recursive/src/lexer/lexer.h b/lang_design/recursive/src/lexer/lexer.h
new file mode 100644 (file)
index 0000000..127f541
--- /dev/null
@@ -0,0 +1,27 @@
+#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
diff --git a/lang_design/recursive/src/lexer/token/token.cpp b/lang_design/recursive/src/lexer/token/token.cpp
new file mode 100644 (file)
index 0000000..6ea3b16
--- /dev/null
@@ -0,0 +1,21 @@
+#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;
+}
+
+
diff --git a/lang_design/recursive/src/lexer/token/token.h b/lang_design/recursive/src/lexer/token/token.h
new file mode 100644 (file)
index 0000000..69acf7e
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/lang_design/recursive/src/main.cpp b/lang_design/recursive/src/main.cpp
new file mode 100644 (file)
index 0000000..c1a0cc6
--- /dev/null
@@ -0,0 +1,321 @@
+#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;
+}
diff --git a/lang_design/recursive/src/parsers/llkparser/llkparser.cpp b/lang_design/recursive/src/parsers/llkparser/llkparser.cpp
new file mode 100644 (file)
index 0000000..e0b5f5d
--- /dev/null
@@ -0,0 +1,61 @@
+#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;
+}
+
+
diff --git a/lang_design/recursive/src/parsers/llkparser/llkparser.h b/lang_design/recursive/src/parsers/llkparser/llkparser.h
new file mode 100644 (file)
index 0000000..f79814c
--- /dev/null
@@ -0,0 +1,29 @@
+#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
diff --git a/lang_design/recursive/src/sexp/sexp.cpp b/lang_design/recursive/src/sexp/sexp.cpp
new file mode 100644 (file)
index 0000000..08ee2cb
--- /dev/null
@@ -0,0 +1,42 @@
+#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)
+{
+}
+
diff --git a/lang_design/recursive/src/sexp/sexp.h b/lang_design/recursive/src/sexp/sexp.h
new file mode 100644 (file)
index 0000000..beb888e
--- /dev/null
@@ -0,0 +1,24 @@
+#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
diff --git a/lang_design/recursive/src/visitor/visitor.cpp b/lang_design/recursive/src/visitor/visitor.cpp
new file mode 100644 (file)
index 0000000..71c3ccf
--- /dev/null
@@ -0,0 +1,35 @@
+#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 );
+}
+
diff --git a/lang_design/recursive/src/visitor/visitor.h b/lang_design/recursive/src/visitor/visitor.h
new file mode 100644 (file)
index 0000000..61fdde0
--- /dev/null
@@ -0,0 +1,30 @@
+#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
diff --git a/lang_design/runtime/DELETE/ref/ref.h b/lang_design/runtime/DELETE/ref/ref.h
new file mode 100644 (file)
index 0000000..943412e
--- /dev/null
@@ -0,0 +1,127 @@
+#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
diff --git a/lang_design/runtime/config.rake b/lang_design/runtime/config.rake
new file mode 100644 (file)
index 0000000..f96e315
--- /dev/null
@@ -0,0 +1,34 @@
+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 )
+
diff --git a/lang_design/runtime/findex.dat b/lang_design/runtime/findex.dat
new file mode 100644 (file)
index 0000000..41a38d2
--- /dev/null
@@ -0,0 +1,21 @@
+./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
diff --git a/lang_design/runtime/rakefile.rb b/lang_design/runtime/rakefile.rb
new file mode 100644 (file)
index 0000000..257e55f
--- /dev/null
@@ -0,0 +1,37 @@
+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
diff --git a/lang_design/runtime/src/cast.h b/lang_design/runtime/src/cast.h
new file mode 100644 (file)
index 0000000..b982d9f
--- /dev/null
@@ -0,0 +1,25 @@
+#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
diff --git a/lang_design/runtime/src/cork/cork.cpp b/lang_design/runtime/src/cork/cork.cpp
new file mode 100644 (file)
index 0000000..5fb3e09
--- /dev/null
@@ -0,0 +1,183 @@
+#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
diff --git a/lang_design/runtime/src/cork/cork.h b/lang_design/runtime/src/cork/cork.h
new file mode 100644 (file)
index 0000000..1aa8ab6
--- /dev/null
@@ -0,0 +1,18 @@
+#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
diff --git a/lang_design/runtime/src/gc/gc.h b/lang_design/runtime/src/gc/gc.h
new file mode 100644 (file)
index 0000000..460fe07
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef GC_H
+#define GC_H
+
+#include "gc_obj.h"
+#include "gc_ptr.h"
+
+#endif
diff --git a/lang_design/runtime/src/gc/gc_obj/gc_obj.cpp b/lang_design/runtime/src/gc/gc_obj/gc_obj.cpp
new file mode 100644 (file)
index 0000000..99e32b2
--- /dev/null
@@ -0,0 +1,24 @@
+#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;
+       }
+}
+
+
diff --git a/lang_design/runtime/src/gc/gc_obj/gc_obj.h b/lang_design/runtime/src/gc/gc_obj/gc_obj.h
new file mode 100644 (file)
index 0000000..6116d2e
--- /dev/null
@@ -0,0 +1,17 @@
+#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
diff --git a/lang_design/runtime/src/gc/gc_ptr/gc_ptr.cpp b/lang_design/runtime/src/gc/gc_ptr/gc_ptr.cpp
new file mode 100644 (file)
index 0000000..ab06c2b
--- /dev/null
@@ -0,0 +1,57 @@
+#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;
+//}
+
diff --git a/lang_design/runtime/src/gc/gc_ptr/gc_ptr.h b/lang_design/runtime/src/gc/gc_ptr/gc_ptr.h
new file mode 100644 (file)
index 0000000..29bdc5a
--- /dev/null
@@ -0,0 +1,98 @@
+#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
diff --git a/lang_design/runtime/src/runtime.c b/lang_design/runtime/src/runtime.c
new file mode 100644 (file)
index 0000000..a920200
--- /dev/null
@@ -0,0 +1,5 @@
+#include "runtime.h"
+
+Atom True;
+Atom False;
+Atom Nil;
diff --git a/lang_design/runtime/src/runtime.h b/lang_design/runtime/src/runtime.h
new file mode 100644 (file)
index 0000000..3323ad2
--- /dev/null
@@ -0,0 +1,17 @@
+#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
diff --git a/lang_design/runtime/src/type/atom/atom.cpp b/lang_design/runtime/src/type/atom/atom.cpp
new file mode 100644 (file)
index 0000000..f0ea81f
--- /dev/null
@@ -0,0 +1,20 @@
+#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();
+}
diff --git a/lang_design/runtime/src/type/atom/atom.h b/lang_design/runtime/src/type/atom/atom.h
new file mode 100644 (file)
index 0000000..0da7059
--- /dev/null
@@ -0,0 +1,14 @@
+#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
diff --git a/lang_design/runtime/src/type/func/func.cpp b/lang_design/runtime/src/type/func/func.cpp
new file mode 100644 (file)
index 0000000..53377ba
--- /dev/null
@@ -0,0 +1,20 @@
+#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();
+}
+
diff --git a/lang_design/runtime/src/type/func/func.h b/lang_design/runtime/src/type/func/func.h
new file mode 100644 (file)
index 0000000..226447e
--- /dev/null
@@ -0,0 +1,16 @@
+#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
diff --git a/lang_design/runtime/src/type/list/list.cpp b/lang_design/runtime/src/type/list/list.cpp
new file mode 100644 (file)
index 0000000..0902751
--- /dev/null
@@ -0,0 +1,49 @@
+#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;
+}
+
diff --git a/lang_design/runtime/src/type/list/list.h b/lang_design/runtime/src/type/list/list.h
new file mode 100644 (file)
index 0000000..9cd9492
--- /dev/null
@@ -0,0 +1,22 @@
+#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
diff --git a/lang_design/runtime/src/type/num/num.cpp b/lang_design/runtime/src/type/num/num.cpp
new file mode 100644 (file)
index 0000000..dd39d16
--- /dev/null
@@ -0,0 +1,54 @@
+#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;
+}
+
diff --git a/lang_design/runtime/src/type/num/num.h b/lang_design/runtime/src/type/num/num.h
new file mode 100644 (file)
index 0000000..11de030
--- /dev/null
@@ -0,0 +1,24 @@
+#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
diff --git a/lang_design/runtime/src/type/type.cpp b/lang_design/runtime/src/type/type.cpp
new file mode 100644 (file)
index 0000000..d3ee23a
--- /dev/null
@@ -0,0 +1,42 @@
+#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;
+}
+
diff --git a/lang_design/runtime/src/type/type.h b/lang_design/runtime/src/type/type.h
new file mode 100644 (file)
index 0000000..e457efb
--- /dev/null
@@ -0,0 +1,27 @@
+#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
diff --git a/lang_design/runtime/src/type/vector/vector.cpp b/lang_design/runtime/src/type/vector/vector.cpp
new file mode 100644 (file)
index 0000000..f5c5aba
--- /dev/null
@@ -0,0 +1,44 @@
+#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];
+}
+
diff --git a/lang_design/runtime/src/type/vector/vector.h b/lang_design/runtime/src/type/vector/vector.h
new file mode 100644 (file)
index 0000000..045b04e
--- /dev/null
@@ -0,0 +1,28 @@
+#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
diff --git a/lang_design/runtime/test/test_main.cpp b/lang_design/runtime/test/test_main.cpp
new file mode 100644 (file)
index 0000000..2bded26
--- /dev/null
@@ -0,0 +1,93 @@
+#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;
+}
diff --git a/lang_design/runtime/test_runner.exe b/lang_design/runtime/test_runner.exe
new file mode 100644 (file)
index 0000000..7fea1b0
Binary files /dev/null and b/lang_design/runtime/test_runner.exe differ
diff --git a/lang_design/runtime_debug/config.rake b/lang_design/runtime_debug/config.rake
new file mode 100644 (file)
index 0000000..f96e315
--- /dev/null
@@ -0,0 +1,34 @@
+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 )
+
diff --git a/lang_design/runtime_debug/findex.dat b/lang_design/runtime_debug/findex.dat
new file mode 100644 (file)
index 0000000..41a38d2
--- /dev/null
@@ -0,0 +1,21 @@
+./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
diff --git a/lang_design/runtime_debug/rakefile.rb b/lang_design/runtime_debug/rakefile.rb
new file mode 100644 (file)
index 0000000..257e55f
--- /dev/null
@@ -0,0 +1,37 @@
+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
diff --git a/lang_design/runtime_debug/src/cork/cork.cpp b/lang_design/runtime_debug/src/cork/cork.cpp
new file mode 100644 (file)
index 0000000..5fb3e09
--- /dev/null
@@ -0,0 +1,183 @@
+#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
diff --git a/lang_design/runtime_debug/src/cork/cork.h b/lang_design/runtime_debug/src/cork/cork.h
new file mode 100644 (file)
index 0000000..1aa8ab6
--- /dev/null
@@ -0,0 +1,18 @@
+#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
diff --git a/lang_design/runtime_debug/src/gc/gc.h b/lang_design/runtime_debug/src/gc/gc.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lang_design/runtime_debug/src/gc/gc_obj/gc_obj.cpp b/lang_design/runtime_debug/src/gc/gc_obj/gc_obj.cpp
new file mode 100644 (file)
index 0000000..64744f9
--- /dev/null
@@ -0,0 +1,60 @@
+#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;
+}
+
diff --git a/lang_design/runtime_debug/src/gc/gc_obj/gc_obj.h b/lang_design/runtime_debug/src/gc/gc_obj/gc_obj.h
new file mode 100644 (file)
index 0000000..c5b2485
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.cpp b/lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.cpp
new file mode 100644 (file)
index 0000000..64744f9
--- /dev/null
@@ -0,0 +1,60 @@
+#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;
+}
+
diff --git a/lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.h b/lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.h
new file mode 100644 (file)
index 0000000..c5b2485
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/lang_design/runtime_debug/src/ref/ref.cpp b/lang_design/runtime_debug/src/ref/ref.cpp
new file mode 100644 (file)
index 0000000..2dd0d12
--- /dev/null
@@ -0,0 +1,72 @@
+#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();
+}
+
+
diff --git a/lang_design/runtime_debug/src/ref/ref.h b/lang_design/runtime_debug/src/ref/ref.h
new file mode 100644 (file)
index 0000000..cb2c25f
--- /dev/null
@@ -0,0 +1,38 @@
+#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
diff --git a/lang_design/runtime_debug/src/runtime.c b/lang_design/runtime_debug/src/runtime.c
new file mode 100644 (file)
index 0000000..5e35357
--- /dev/null
@@ -0,0 +1,2 @@
+#include "runtime.h"
+
diff --git a/lang_design/runtime_debug/src/runtime.h b/lang_design/runtime_debug/src/runtime.h
new file mode 100644 (file)
index 0000000..ae016cb
--- /dev/null
@@ -0,0 +1,15 @@
+#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
diff --git a/lang_design/runtime_debug/src/type/atom/atom.cpp b/lang_design/runtime_debug/src/type/atom/atom.cpp
new file mode 100644 (file)
index 0000000..25a2aa7
--- /dev/null
@@ -0,0 +1,9 @@
+#include <string>
+#include <typeinfo>
+#include "atom.h"
+
+
+std::string Atom::type(void)
+{
+       return typeid(this).name();
+}
diff --git a/lang_design/runtime_debug/src/type/atom/atom.h b/lang_design/runtime_debug/src/type/atom/atom.h
new file mode 100644 (file)
index 0000000..c607cb0
--- /dev/null
@@ -0,0 +1,12 @@
+#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
diff --git a/lang_design/runtime_debug/src/type/list/list.cpp b/lang_design/runtime_debug/src/type/list/list.cpp
new file mode 100644 (file)
index 0000000..214bdc7
--- /dev/null
@@ -0,0 +1,22 @@
+#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;
+}
+
diff --git a/lang_design/runtime_debug/src/type/list/list.h b/lang_design/runtime_debug/src/type/list/list.h
new file mode 100644 (file)
index 0000000..0f8bb15
--- /dev/null
@@ -0,0 +1,22 @@
+#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
diff --git a/lang_design/runtime_debug/src/type/type.cpp b/lang_design/runtime_debug/src/type/type.cpp
new file mode 100644 (file)
index 0000000..ed37d1e
--- /dev/null
@@ -0,0 +1,78 @@
+#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;
+}
+
diff --git a/lang_design/runtime_debug/src/type/type.h b/lang_design/runtime_debug/src/type/type.h
new file mode 100644 (file)
index 0000000..3b26c60
--- /dev/null
@@ -0,0 +1,34 @@
+#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
diff --git a/lang_design/runtime_debug/test/test_main.cpp b/lang_design/runtime_debug/test/test_main.cpp
new file mode 100644 (file)
index 0000000..1adbf70
--- /dev/null
@@ -0,0 +1,20 @@
+#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;
+}
diff --git a/lang_design/runtime_debug/test_runner.exe b/lang_design/runtime_debug/test_runner.exe
new file mode 100644 (file)
index 0000000..64ad7f0
Binary files /dev/null and b/lang_design/runtime_debug/test_runner.exe differ
diff --git a/python/micro/comm.py b/python/micro/comm.py
new file mode 100644 (file)
index 0000000..e68e54e
--- /dev/null
@@ -0,0 +1,39 @@
+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
+
diff --git a/python/micro/controller.py b/python/micro/controller.py
new file mode 100644 (file)
index 0000000..fedbca2
--- /dev/null
@@ -0,0 +1,88 @@
+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()
+
diff --git a/python/micro/joy.py b/python/micro/joy.py
new file mode 100644 (file)
index 0000000..090f051
--- /dev/null
@@ -0,0 +1,20 @@
+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()
+
diff --git a/scheme/assoc_arrays.scm b/scheme/assoc_arrays.scm
new file mode 100644 (file)
index 0000000..de8215e
--- /dev/null
@@ -0,0 +1,135 @@
+;------------------------------------------------------------------------------
+; 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)