From 29c844b7f22f435b36d7cc6da4a4d691518e12c9 Mon Sep 17 00:00:00 2001 From: "Mike D. Lowis" Date: Sat, 11 Feb 2012 21:49:46 -0500 Subject: [PATCH] Initial Commit --- arduino/revcomm/revcomm.ino | 37 ++ arduino/servo_test/servo_test.ino | 19 ++ clojure/dsl.clj | 52 +++ clojure/euler/euler1.clj | 21 ++ clojure/euler/euler3.clj | 33 ++ clojure/lex.clj | 49 +++ clojure/lexer/.gitignore | 5 + clojure/lexer/README | 13 + clojure/lexer/project.clj | 3 + clojure/lexer/src/lexer/core.clj | 1 + clojure/lexer/test/lexer/test/core.clj | 6 + clojure/parse.clj | 90 +++++ lang_design/recursive/config.rake | 29 ++ lang_design/recursive/parser.exe | Bin 0 -> 61206 bytes lang_design/recursive/rakefile.rb | 25 ++ lang_design/recursive/src/ast/ast.cpp | 69 ++++ lang_design/recursive/src/ast/ast.h | 28 ++ lang_design/recursive/src/lexer/lexer.cpp | 57 ++++ lang_design/recursive/src/lexer/lexer.h | 27 ++ .../recursive/src/lexer/token/token.cpp | 21 ++ lang_design/recursive/src/lexer/token/token.h | 20 ++ lang_design/recursive/src/main.cpp | 321 ++++++++++++++++++ .../src/parsers/llkparser/llkparser.cpp | 61 ++++ .../src/parsers/llkparser/llkparser.h | 29 ++ lang_design/recursive/src/sexp/sexp.cpp | 42 +++ lang_design/recursive/src/sexp/sexp.h | 24 ++ lang_design/recursive/src/visitor/visitor.cpp | 35 ++ lang_design/recursive/src/visitor/visitor.h | 30 ++ lang_design/runtime/DELETE/ref/ref.h | 127 +++++++ lang_design/runtime/config.rake | 34 ++ lang_design/runtime/findex.dat | 21 ++ lang_design/runtime/rakefile.rb | 37 ++ lang_design/runtime/src/cast.h | 25 ++ lang_design/runtime/src/cork/cork.cpp | 183 ++++++++++ lang_design/runtime/src/cork/cork.h | 18 + lang_design/runtime/src/gc/gc.h | 7 + lang_design/runtime/src/gc/gc_obj/gc_obj.cpp | 24 ++ lang_design/runtime/src/gc/gc_obj/gc_obj.h | 17 + lang_design/runtime/src/gc/gc_ptr/gc_ptr.cpp | 57 ++++ lang_design/runtime/src/gc/gc_ptr/gc_ptr.h | 98 ++++++ lang_design/runtime/src/runtime.c | 5 + lang_design/runtime/src/runtime.h | 17 + lang_design/runtime/src/type/atom/atom.cpp | 20 ++ lang_design/runtime/src/type/atom/atom.h | 14 + lang_design/runtime/src/type/func/func.cpp | 20 ++ lang_design/runtime/src/type/func/func.h | 16 + lang_design/runtime/src/type/list/list.cpp | 49 +++ lang_design/runtime/src/type/list/list.h | 22 ++ lang_design/runtime/src/type/num/num.cpp | 54 +++ lang_design/runtime/src/type/num/num.h | 24 ++ lang_design/runtime/src/type/type.cpp | 42 +++ lang_design/runtime/src/type/type.h | 27 ++ .../runtime/src/type/vector/vector.cpp | 44 +++ lang_design/runtime/src/type/vector/vector.h | 28 ++ lang_design/runtime/test/test_main.cpp | 93 +++++ lang_design/runtime/test_runner.exe | Bin 0 -> 65527 bytes lang_design/runtime_debug/config.rake | 34 ++ lang_design/runtime_debug/findex.dat | 21 ++ lang_design/runtime_debug/rakefile.rb | 37 ++ lang_design/runtime_debug/src/cork/cork.cpp | 183 ++++++++++ lang_design/runtime_debug/src/cork/cork.h | 18 + lang_design/runtime_debug/src/gc/gc.h | 0 .../runtime_debug/src/gc/gc_obj/gc_obj.cpp | 60 ++++ .../runtime_debug/src/gc/gc_obj/gc_obj.h | 37 ++ .../runtime_debug/src/gc/gc_ptr/gc_ptr.cpp | 60 ++++ .../runtime_debug/src/gc/gc_ptr/gc_ptr.h | 37 ++ lang_design/runtime_debug/src/ref/ref.cpp | 72 ++++ lang_design/runtime_debug/src/ref/ref.h | 38 +++ lang_design/runtime_debug/src/runtime.c | 2 + lang_design/runtime_debug/src/runtime.h | 15 + .../runtime_debug/src/type/atom/atom.cpp | 9 + .../runtime_debug/src/type/atom/atom.h | 12 + .../runtime_debug/src/type/list/list.cpp | 22 ++ .../runtime_debug/src/type/list/list.h | 22 ++ lang_design/runtime_debug/src/type/type.cpp | 78 +++++ lang_design/runtime_debug/src/type/type.h | 34 ++ lang_design/runtime_debug/test/test_main.cpp | 20 ++ lang_design/runtime_debug/test_runner.exe | Bin 0 -> 48756 bytes python/micro/comm.py | 39 +++ python/micro/controller.py | 88 +++++ python/micro/joy.py | 20 ++ scheme/assoc_arrays.scm | 135 ++++++++ 82 files changed, 3363 insertions(+) create mode 100644 arduino/revcomm/revcomm.ino create mode 100644 arduino/servo_test/servo_test.ino create mode 100644 clojure/dsl.clj create mode 100644 clojure/euler/euler1.clj create mode 100644 clojure/euler/euler3.clj create mode 100644 clojure/lex.clj create mode 100644 clojure/lexer/.gitignore create mode 100644 clojure/lexer/README create mode 100644 clojure/lexer/project.clj create mode 100644 clojure/lexer/src/lexer/core.clj create mode 100644 clojure/lexer/test/lexer/test/core.clj create mode 100644 clojure/parse.clj create mode 100644 lang_design/recursive/config.rake create mode 100644 lang_design/recursive/parser.exe create mode 100644 lang_design/recursive/rakefile.rb create mode 100644 lang_design/recursive/src/ast/ast.cpp create mode 100644 lang_design/recursive/src/ast/ast.h create mode 100644 lang_design/recursive/src/lexer/lexer.cpp create mode 100644 lang_design/recursive/src/lexer/lexer.h create mode 100644 lang_design/recursive/src/lexer/token/token.cpp create mode 100644 lang_design/recursive/src/lexer/token/token.h create mode 100644 lang_design/recursive/src/main.cpp create mode 100644 lang_design/recursive/src/parsers/llkparser/llkparser.cpp create mode 100644 lang_design/recursive/src/parsers/llkparser/llkparser.h create mode 100644 lang_design/recursive/src/sexp/sexp.cpp create mode 100644 lang_design/recursive/src/sexp/sexp.h create mode 100644 lang_design/recursive/src/visitor/visitor.cpp create mode 100644 lang_design/recursive/src/visitor/visitor.h create mode 100644 lang_design/runtime/DELETE/ref/ref.h create mode 100644 lang_design/runtime/config.rake create mode 100644 lang_design/runtime/findex.dat create mode 100644 lang_design/runtime/rakefile.rb create mode 100644 lang_design/runtime/src/cast.h create mode 100644 lang_design/runtime/src/cork/cork.cpp create mode 100644 lang_design/runtime/src/cork/cork.h create mode 100644 lang_design/runtime/src/gc/gc.h create mode 100644 lang_design/runtime/src/gc/gc_obj/gc_obj.cpp create mode 100644 lang_design/runtime/src/gc/gc_obj/gc_obj.h create mode 100644 lang_design/runtime/src/gc/gc_ptr/gc_ptr.cpp create mode 100644 lang_design/runtime/src/gc/gc_ptr/gc_ptr.h create mode 100644 lang_design/runtime/src/runtime.c create mode 100644 lang_design/runtime/src/runtime.h create mode 100644 lang_design/runtime/src/type/atom/atom.cpp create mode 100644 lang_design/runtime/src/type/atom/atom.h create mode 100644 lang_design/runtime/src/type/func/func.cpp create mode 100644 lang_design/runtime/src/type/func/func.h create mode 100644 lang_design/runtime/src/type/list/list.cpp create mode 100644 lang_design/runtime/src/type/list/list.h create mode 100644 lang_design/runtime/src/type/num/num.cpp create mode 100644 lang_design/runtime/src/type/num/num.h create mode 100644 lang_design/runtime/src/type/type.cpp create mode 100644 lang_design/runtime/src/type/type.h create mode 100644 lang_design/runtime/src/type/vector/vector.cpp create mode 100644 lang_design/runtime/src/type/vector/vector.h create mode 100644 lang_design/runtime/test/test_main.cpp create mode 100644 lang_design/runtime/test_runner.exe create mode 100644 lang_design/runtime_debug/config.rake create mode 100644 lang_design/runtime_debug/findex.dat create mode 100644 lang_design/runtime_debug/rakefile.rb create mode 100644 lang_design/runtime_debug/src/cork/cork.cpp create mode 100644 lang_design/runtime_debug/src/cork/cork.h create mode 100644 lang_design/runtime_debug/src/gc/gc.h create mode 100644 lang_design/runtime_debug/src/gc/gc_obj/gc_obj.cpp create mode 100644 lang_design/runtime_debug/src/gc/gc_obj/gc_obj.h create mode 100644 lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.cpp create mode 100644 lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.h create mode 100644 lang_design/runtime_debug/src/ref/ref.cpp create mode 100644 lang_design/runtime_debug/src/ref/ref.h create mode 100644 lang_design/runtime_debug/src/runtime.c create mode 100644 lang_design/runtime_debug/src/runtime.h create mode 100644 lang_design/runtime_debug/src/type/atom/atom.cpp create mode 100644 lang_design/runtime_debug/src/type/atom/atom.h create mode 100644 lang_design/runtime_debug/src/type/list/list.cpp create mode 100644 lang_design/runtime_debug/src/type/list/list.h create mode 100644 lang_design/runtime_debug/src/type/type.cpp create mode 100644 lang_design/runtime_debug/src/type/type.h create mode 100644 lang_design/runtime_debug/test/test_main.cpp create mode 100644 lang_design/runtime_debug/test_runner.exe create mode 100644 python/micro/comm.py create mode 100644 python/micro/controller.py create mode 100644 python/micro/joy.py create mode 100644 scheme/assoc_arrays.scm diff --git a/arduino/revcomm/revcomm.ino b/arduino/revcomm/revcomm.ino new file mode 100644 index 0000000..f6e1d22 --- /dev/null +++ b/arduino/revcomm/revcomm.ino @@ -0,0 +1,37 @@ +#include + +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 index 0000000..72bb5b9 --- /dev/null +++ b/arduino/servo_test/servo_test.ino @@ -0,0 +1,19 @@ +#include + +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 index 0000000..782b3bb --- /dev/null +++ b/clojure/dsl.clj @@ -0,0 +1,52 @@ +(use '[clojure.java.io :only (reader)]) + +;------------------------------------------------------------------------------ +; Commands +;------------------------------------------------------------------------------ +(defn install-package [args] + (println "# install-package") + (println "ssh @ apt-get install" (first args)) + (println)) + +(defn install-module [args] + (println "# install-module") + (println (str "cd submodules/" (first args))) + (println (str " submodules/" (first args))) + (println "cd ../../") + (println)) + +(defn run-script [args] + (println "# run-script") + (println "scp" (first args) "@") + (println "ssh @ chmod +x" (first args)) + (println "ssh @" (first args)) + (println)) + +(defn fetch-config [args] + (println "# fetch-config") + (println "scp" (first args) "@:") + (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 index 0000000..6a3f875 --- /dev/null +++ b/clojure/euler/euler1.clj @@ -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 index 0000000..b32b2ab --- /dev/null +++ b/clojure/euler/euler3.clj @@ -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 index 0000000..903648f --- /dev/null +++ b/clojure/lex.clj @@ -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 index 0000000..b8c1b21 --- /dev/null +++ b/clojure/lexer/.gitignore @@ -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 index 0000000..67a3f32 --- /dev/null +++ b/clojure/lexer/README @@ -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 index 0000000..9806ec1 --- /dev/null +++ b/clojure/lexer/project.clj @@ -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 index 0000000..c7512b9 --- /dev/null +++ b/clojure/lexer/src/lexer/core.clj @@ -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 index 0000000..05100b2 --- /dev/null +++ b/clojure/lexer/test/lexer/test/core.clj @@ -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 index 0000000..4ccd7fe --- /dev/null +++ b/clojure/parse.clj @@ -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 index 0000000..7ce50f4 --- /dev/null +++ b/lang_design/recursive/config.rake @@ -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 index 0000000000000000000000000000000000000000..a94916384fdd1aac7b4ae603f065bbf150c6941c GIT binary patch literal 61206 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 literal 0 HcmV?d00001 diff --git a/lang_design/recursive/rakefile.rb b/lang_design/recursive/rakefile.rb new file mode 100644 index 0000000..c5500c0 --- /dev/null +++ b/lang_design/recursive/rakefile.rb @@ -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 index 0000000..8683e97 --- /dev/null +++ b/lang_design/recursive/src/ast/ast.cpp @@ -0,0 +1,69 @@ +#include "ast.h" +#include +#include + +AST::AST(ASTNodeType type) +{ + node_type = type; + node_text = NULL; + node_children = new list(); +} + +AST::~AST() +{ + list::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(ASTNodeType type, int child_count, ...) +{ + va_list arg_list; + int i = 0; + node_type = type; + node_text = NULL; + node_children = new list(); + 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::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 index 0000000..6877fdf --- /dev/null +++ b/lang_design/recursive/src/ast/ast.h @@ -0,0 +1,28 @@ +#ifndef AST_H +#define AST_H + +#include +#include +#include + +using namespace std; + +typedef unsigned int ASTNodeType; + +class AST { + protected: + ASTNodeType node_type; + string* node_text; + list* node_children; + public: + AST(ASTNodeType type); + ~AST(); + AST(ASTNodeType type, char* text); + AST(ASTNodeType type, int child_count, ...); + ASTNodeType type(); + string text(); + list* 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 index 0000000..a4e40ef --- /dev/null +++ b/lang_design/recursive/src/lexer/lexer.cpp @@ -0,0 +1,57 @@ +#include +#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 index 0000000..127f541 --- /dev/null +++ b/lang_design/recursive/src/lexer/lexer.h @@ -0,0 +1,27 @@ +#ifndef LEXER_H +#define LEXER_H + +#include +#include +#include +#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 index 0000000..6ea3b16 --- /dev/null +++ b/lang_design/recursive/src/lexer/token/token.cpp @@ -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 index 0000000..69acf7e --- /dev/null +++ b/lang_design/recursive/src/lexer/token/token.h @@ -0,0 +1,20 @@ +#ifndef TOKEN_H +#define TOKEN_H + +#include + +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 index 0000000..c1a0cc6 --- /dev/null +++ b/lang_design/recursive/src/main.cpp @@ -0,0 +1,321 @@ +#include +#include +#include +#include + +#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 index 0000000..e0b5f5d --- /dev/null +++ b/lang_design/recursive/src/parsers/llkparser/llkparser.cpp @@ -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 index 0000000..f79814c --- /dev/null +++ b/lang_design/recursive/src/parsers/llkparser/llkparser.h @@ -0,0 +1,29 @@ +#ifndef LLK_PARSER_H +#define LLK_PARSER_H + +#include +#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 index 0000000..08ee2cb --- /dev/null +++ b/lang_design/recursive/src/sexp/sexp.cpp @@ -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 index 0000000..beb888e --- /dev/null +++ b/lang_design/recursive/src/sexp/sexp.h @@ -0,0 +1,24 @@ +#ifndef SEXP_H +#define SEXP_H + +#include "visitor.h" +#include +#include + +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 index 0000000..71c3ccf --- /dev/null +++ b/lang_design/recursive/src/visitor/visitor.cpp @@ -0,0 +1,35 @@ +#include "visitor.h" +#include + +using namespace std; + +void Visitor::visit(AST* cur, int depth) +{ + list* children; + list::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 index 0000000..61fdde0 --- /dev/null +++ b/lang_design/recursive/src/visitor/visitor.h @@ -0,0 +1,30 @@ +#ifndef TRANSLATOR_H +#define TRANSLATOR_H + +#include "ast.h" +#include +#include + +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 index 0000000..943412e --- /dev/null +++ b/lang_design/runtime/DELETE/ref/ref.h @@ -0,0 +1,127 @@ +#ifndef REF_H +#define REF_H + +#include +#include +#include +#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 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 operator [] (unsigned int index); + T* value(void); + Ref& operator = (Ref& right); + Ref& operator = (T* right); + T& operator * (void); + T* operator -> (void); + std::string type(void); +}; + +template +Ref::Ref(T* p) : ptr(p) +{ + if (ptr != 0) + { + ptr->incRefCount(); + } +} + +template +Ref::Ref(const Ref& right) : ptr(right.ptr) +{ + if (ptr != 0) + { + ptr->incRefCount(); + } +} + +template +Ref::~Ref() +{ + if (ptr != 0) + { + ptr->decRefCount(); + } +} + +template +T* Ref::value(void) +{ + return ptr; +} + +/*template */ +//Ref Ref::operator [] (unsigned int index) +//{ + //return ptr[index]; +//} + +template +Ref& Ref::operator = (Ref& right) +{ + ptr->decRefCount(); + ptr = right.value(); + ptr->incRefCount(); + return *this; +} + +template +Ref& Ref::operator = (T* right) +{ + ptr->decRefCount(); + ptr = right; + ptr->incRefCount(); + return *this; +} + +template +T& Ref::operator * (void) +{ + if(ptr == 0) + { + NullRefException null_ref_exception; + throw null_ref_exception; + } + return *ptr; +} + +template +T* Ref::operator -> (void) +{ + if(ptr == 0) + { + NullRefException null_ref_exception; + throw null_ref_exception; + } + return ptr; +} + +template +std::string Ref::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 index 0000000..f96e315 --- /dev/null +++ b/lang_design/runtime/config.rake @@ -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 index 0000000..41a38d2 --- /dev/null +++ b/lang_design/runtime/findex.dat @@ -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 index 0000000..257e55f --- /dev/null +++ b/lang_design/runtime/rakefile.rb @@ -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 index 0000000..b982d9f --- /dev/null +++ b/lang_design/runtime/src/cast.h @@ -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 +T* cast(type_ptr ptr) +{ + T* new_ptr = dynamic_cast( 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 index 0000000..5fb3e09 --- /dev/null +++ b/lang_design/runtime/src/cork/cork.cpp @@ -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 +#include // for std::bad_alloc +#include // for malloc() and free() +#include + +// 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 index 0000000..1aa8ab6 --- /dev/null +++ b/lang_design/runtime/src/cork/cork.h @@ -0,0 +1,18 @@ +#ifndef CORK_H +#define CORK_H + +#ifdef DETECT_MEM_LEAKS + #include + 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 index 0000000..460fe07 --- /dev/null +++ b/lang_design/runtime/src/gc/gc.h @@ -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 index 0000000..99e32b2 --- /dev/null +++ b/lang_design/runtime/src/gc/gc_obj/gc_obj.cpp @@ -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 index 0000000..6116d2e --- /dev/null +++ b/lang_design/runtime/src/gc/gc_obj/gc_obj.h @@ -0,0 +1,17 @@ +#ifndef GC_OBJ_H +#define GC_OBJ_H + +#include + +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 index 0000000..ab06c2b --- /dev/null +++ b/lang_design/runtime/src/gc/gc_ptr/gc_ptr.cpp @@ -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 index 0000000..29bdc5a --- /dev/null +++ b/lang_design/runtime/src/gc/gc_ptr/gc_ptr.h @@ -0,0 +1,98 @@ +#ifndef REF_H +#define REF_H + +#include +#include +#include + +class NullRefException : public std::exception +{ + virtual const char* what() const throw() + { + return "Null Reference: A pointer was used without being initialized"; + } +}; + +template +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 +gc_ptr::gc_ptr(T* p) : ptr(p) +{ + if (ptr != 0) + { + ptr->incRefCount(); + } +} + +template +gc_ptr::gc_ptr(const gc_ptr& right) : ptr(right.ptr) +{ + if (ptr != 0) + { + ptr->incRefCount(); + } +} + +template +gc_ptr::~gc_ptr() +{ + if (ptr != 0) + { + ptr->decRefCount(); + } +} + +template +T* gc_ptr::value(void) +{ + return ptr; +} + +template +gc_ptr& gc_ptr::operator = (gc_ptr& right) +{ + if(ptr) ptr->decRefCount(); + ptr = right.value(); + if(ptr) ptr->incRefCount(); + return *this; +} + +template +gc_ptr& gc_ptr::operator = (T* right) +{ + if(ptr) ptr->decRefCount(); + ptr = right; + if(ptr) ptr->incRefCount(); + return *this; +} + +template +T& gc_ptr::operator * (void) +{ + return *ptr; +} + +template +T* gc_ptr::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 index 0000000..a920200 --- /dev/null +++ b/lang_design/runtime/src/runtime.c @@ -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 index 0000000..3323ad2 --- /dev/null +++ b/lang_design/runtime/src/runtime.h @@ -0,0 +1,17 @@ +#ifndef RUNTIME_H +#define RUNTIME_H + +#include +#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 index 0000000..f0ea81f --- /dev/null +++ b/lang_design/runtime/src/type/atom/atom.cpp @@ -0,0 +1,20 @@ +#include +#include +#include +#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 index 0000000..0da7059 --- /dev/null +++ b/lang_design/runtime/src/type/atom/atom.h @@ -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 index 0000000..53377ba --- /dev/null +++ b/lang_design/runtime/src/type/func/func.cpp @@ -0,0 +1,20 @@ +#include +#include +#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 index 0000000..226447e --- /dev/null +++ b/lang_design/runtime/src/type/func/func.h @@ -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 index 0000000..0902751 --- /dev/null +++ b/lang_design/runtime/src/type/list/list.cpp @@ -0,0 +1,49 @@ +#include +#include +#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 index 0000000..9cd9492 --- /dev/null +++ b/lang_design/runtime/src/type/list/list.h @@ -0,0 +1,22 @@ +#ifndef LIST_H +#define LIST_H + +#include +#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 index 0000000..dd39d16 --- /dev/null +++ b/lang_design/runtime/src/type/num/num.cpp @@ -0,0 +1,54 @@ +#include +#include +#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 index 0000000..11de030 --- /dev/null +++ b/lang_design/runtime/src/type/num/num.h @@ -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 index 0000000..d3ee23a --- /dev/null +++ b/lang_design/runtime/src/type/type.cpp @@ -0,0 +1,42 @@ +#include +#include +#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 index 0000000..e457efb --- /dev/null +++ b/lang_design/runtime/src/type/type.h @@ -0,0 +1,27 @@ +#ifndef TYPE_H +#define TYPE_H + +#include +#include +#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_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 index 0000000..f5c5aba --- /dev/null +++ b/lang_design/runtime/src/type/vector/vector.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#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 index 0000000..045b04e --- /dev/null +++ b/lang_design/runtime/src/type/vector/vector.h @@ -0,0 +1,28 @@ +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include +#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 index 0000000..2bded26 --- /dev/null +++ b/lang_design/runtime/test/test_main.cpp @@ -0,0 +1,93 @@ +#include +#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(ref2.value())); + Type* t1 = ref2.value(); + Atom* t2 = cast(t1); + (void)t2; + + try + { + type_ptr ref((Atom*)0); + Atom foo = *(cast(ref.value())); + (void) foo; + } + catch(exception& e) + { + cout << e.what() << endl; + } + + // Explicit heap allocation is disallowed: + //type_ptr* foo = _new Ref(_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(a)) + *(cast(b)); + cout << "2 + 3 = " << *c << endl; + + type_ptr d = *(cast(a)) - *(cast(b)); + cout << "2 - 3 = " << *d << endl; + + type_ptr e = *(cast(a)) * *(cast(b)); + cout << "2 * 3 = " << *e << endl; + + type_ptr f = *(cast(a)) / *(cast(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 index 0000000000000000000000000000000000000000..7fea1b01cf161489cab895f043770bd2500e45d7 GIT binary patch literal 65527 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 literal 0 HcmV?d00001 diff --git a/lang_design/runtime_debug/config.rake b/lang_design/runtime_debug/config.rake new file mode 100644 index 0000000..f96e315 --- /dev/null +++ b/lang_design/runtime_debug/config.rake @@ -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 index 0000000..41a38d2 --- /dev/null +++ b/lang_design/runtime_debug/findex.dat @@ -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 index 0000000..257e55f --- /dev/null +++ b/lang_design/runtime_debug/rakefile.rb @@ -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 index 0000000..5fb3e09 --- /dev/null +++ b/lang_design/runtime_debug/src/cork/cork.cpp @@ -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 +#include // for std::bad_alloc +#include // for malloc() and free() +#include + +// 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 index 0000000..1aa8ab6 --- /dev/null +++ b/lang_design/runtime_debug/src/cork/cork.h @@ -0,0 +1,18 @@ +#ifndef CORK_H +#define CORK_H + +#ifdef DETECT_MEM_LEAKS + #include + 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 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 index 0000000..64744f9 --- /dev/null +++ b/lang_design/runtime_debug/src/gc/gc_obj/gc_obj.cpp @@ -0,0 +1,60 @@ +#include "ref.h" +#include "type.h" + +#include + +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 index 0000000..c5b2485 --- /dev/null +++ b/lang_design/runtime_debug/src/gc/gc_obj/gc_obj.h @@ -0,0 +1,37 @@ +#ifndef REF_H +#define REF_H + +#include +#include +#include +#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 index 0000000..64744f9 --- /dev/null +++ b/lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.cpp @@ -0,0 +1,60 @@ +#include "ref.h" +#include "type.h" + +#include + +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 index 0000000..c5b2485 --- /dev/null +++ b/lang_design/runtime_debug/src/gc/gc_ptr/gc_ptr.h @@ -0,0 +1,37 @@ +#ifndef REF_H +#define REF_H + +#include +#include +#include +#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 index 0000000..2dd0d12 --- /dev/null +++ b/lang_design/runtime_debug/src/ref/ref.cpp @@ -0,0 +1,72 @@ +#include "ref.h" +#include "type.h" + +#include +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 index 0000000..cb2c25f --- /dev/null +++ b/lang_design/runtime_debug/src/ref/ref.h @@ -0,0 +1,38 @@ +#ifndef REF_H +#define REF_H + +#include +#include +#include +#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 index 0000000..5e35357 --- /dev/null +++ b/lang_design/runtime_debug/src/runtime.c @@ -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 index 0000000..ae016cb --- /dev/null +++ b/lang_design/runtime_debug/src/runtime.h @@ -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 index 0000000..25a2aa7 --- /dev/null +++ b/lang_design/runtime_debug/src/type/atom/atom.cpp @@ -0,0 +1,9 @@ +#include +#include +#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 index 0000000..c607cb0 --- /dev/null +++ b/lang_design/runtime_debug/src/type/atom/atom.h @@ -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 index 0000000..214bdc7 --- /dev/null +++ b/lang_design/runtime_debug/src/type/list/list.cpp @@ -0,0 +1,22 @@ +#include +#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 index 0000000..0f8bb15 --- /dev/null +++ b/lang_design/runtime_debug/src/type/list/list.h @@ -0,0 +1,22 @@ +#ifndef LIST_H +#define LIST_H + +#include +#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 index 0000000..ed37d1e --- /dev/null +++ b/lang_design/runtime_debug/src/type/type.cpp @@ -0,0 +1,78 @@ +#include +#include +#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 index 0000000..3b26c60 --- /dev/null +++ b/lang_design/runtime_debug/src/type/type.h @@ -0,0 +1,34 @@ +#ifndef TYPE_H +#define TYPE_H + +#include +#include +#include + +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 index 0000000..1adbf70 --- /dev/null +++ b/lang_design/runtime_debug/test/test_main.cpp @@ -0,0 +1,20 @@ +#include +#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 index 0000000000000000000000000000000000000000..64ad7f0872fabf6b0b968b017c59755ae54393f0 GIT binary patch literal 48756 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

    Rea|%(H6U}+IT;vg@T`M{`3s~L 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 literal 0 HcmV?d00001 diff --git a/python/micro/comm.py b/python/micro/comm.py new file mode 100644 index 0000000..e68e54e --- /dev/null +++ b/python/micro/comm.py @@ -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 index 0000000..fedbca2 --- /dev/null +++ b/python/micro/controller.py @@ -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 index 0000000..090f051 --- /dev/null +++ b/python/micro/joy.py @@ -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 index 0000000..de8215e --- /dev/null +++ b/scheme/assoc_arrays.scm @@ -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) -- 2.54.0