From: Mike D. Lowis Date: Sun, 12 Feb 2012 02:49:46 +0000 (-0500) Subject: Initial Commit X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=29c844b7f22f435b36d7cc6da4a4d691518e12c9;p=archive%2Fbitbucket.git Initial Commit --- 29c844b7f22f435b36d7cc6da4a4d691518e12c9 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 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 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 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 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 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 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)