DLang
==============================================
- Version: 0.2
+ Version: 0.3
Created By: Michael D. Lowis
Email: mike@mdlowis.com
----------------------------------------------
Unless explicitly stated otherwise, all code and documentation in this project
-is released under the FreeBSD License. You can find a copy of the license text
-in the LICENSE.md file.
+is released under the BSD 2-Clause License. You can find a copy of the license
+text in the LICENSE.md file.
Requirements For Building
----------------------------------------------
-* Ruby and Rake
+* Ruby
+* Rake (>= 0.9.2)
* Chicken Scheme Compiler
-* A C++ compiler
-* Python (For unit test generation)
+* Chicken Scheme vector-lib Egg
+* A C++ compiler (Tested with gcc)
Build Instructions
----------------------------------------------
Installation
----------------------------------------------
-There are no installation instructions at the moment. This is a work in
-progress.
+There are no installation instructions at the moment. The binary is self
+contained and can be placed anywhere you want it.
Project Files and Directories
----------------------------------------------
rakefile.rb Script containing the build configuration and tasks.
README.md You're reading this file right now!
-Know Issues or Bugs
+Known Issues or Bugs
----------------------------------------------
This is a non-comprehensive list of known issues and bugs that I intend to fix.
-* The parser segfaults on \*nix systems due to freeing invalid pointers and other memory management issues
+* The debug build segfaults on \*nix systems due to freeing invalid pointers and other memory management issues
* Error messages are obtuse and unfriendly.
* Parser and Lexer have 0 error recovery.
Version History
----------------------------------------------
+### Version 0.3
+
### Version 0.2
This version includes a much improved macro syntax with support for multiple
Very first version ever. Its buggy, has obtuse error messages, and supports
about 1/20 of what I would like to see. Lets call it a proof of concept.
-
Feature Wish List
----------------------------------------------
* Command line options
* Multi-file support
+* UTF-8 Support
More Info
----------------------------------------------
foo := 1
foo = 1.0
foo = 1.0e1
-foo = 1.0e1.0
foo = -1
foo = -1.0
foo = -1.0e-1
-foo = -1.0e-1.0
# Char
foo = 'a'
foo = {
$foo : 1 + 1,
"stuff" : 2 + 2,
+ $stuff : 2 + 2,
$bar : 3 + 3,
}
+# Setting map elements
+foo["stuff"] = 3
+foo.stuff = 5
+
+# Accessing map elements
print( foo[$bar] )
print( foo["stuff"] )
print( foo.stuff )
foo = foo[1]
foo = [1,2,3,4,5][2]
+# Setting Vector Elements
+foo[2] = 6
+
# List
foo = ()
foo = (1,)
foo = foo[1]
foo = (1,2,3,4,5)[2]
+# Setting List Elements
+foo[2] = 6
+
# Block
foo = { 1 + 1 }
foo = {|a| a + 1}
(define dl/print print)
(define dl/error error)
-; Map
+; map function definitions
(define dl/list_map map)
(define dl/vector_map vector-map)
(define dl/string_map string-map)
((hash-table? ls) (apply hash-table-concatenate args))
((string? ls) (apply string-concatenate args)) )))
+(define (obj-set! obj idx val)
+ (cond
+ ((vector? obj) (vector-set! obj idx val))
+ ((hash-table? obj) (hash-table-set! obj idx val))
+ ((string? obj) (string-set! obj idx val)) ))
+
(define (error reason . args)
(display "Error: ")
(display reason)
(set! result x)
result))))))))
-(define dl/force
- (lambda (object)
- (object)))
-
;------------------------------------------------------------------------------
; Start User Defined Code
;------------------------------------------------------------------------------
-; Potential implementation of prototype objects
-;(define Proto
-; (list (make-hash-table)))
-;
-;(define (proto-clone p)
-; (list (make-hash-table) p))
-;
-;(define (proto? p))
-;(define (proto-value p))
-;(define (proto-member name))
-
oss << current;
consume();
- // Capture the sign if we have one
if(current == '-')
{
+ // Capture the sign
+ oss << current;
consume();
- oss << FloatingPoint(true);
+ }
+
+ if( isDigit() )
+ {
+ // Capture the integer part
+ do
+ {
+ oss << current;
+ consume();
+ }
+ while(isDigit());
}
else
{
- oss << FloatingPoint(false);
+ Exception ex(line,column);
+ ex << "Integer for floating point exponent";
+ throw ex;
}
}
ARRY_IDX = 37,
MACRO = 38,
IMPORT = 39,
+ MUTATE = 40,
// AST "Virtual" Node Types
- PROGRAM = 40,
- BLOCK = 41,
- FN_CALL = 42,
- PARAMS = 43,
- PATT = 44,
+ PROGRAM = 50,
+ BLOCK = 51,
+ FN_CALL = 52,
+ PARAMS = 53,
+ PATT = 54,
} eTokenTypes;
typedef struct {
AST* DLParser::AssignExpr(void)
{
AST* ret = LogicalExpr();
+ AST* child = NULL;
if(lookaheadType(1) == DEFN)
{
match(DEFN);
else if(lookaheadType(1) == ASSIGN)
{
match(ASSIGN);
- ret = new AST(ASSIGN, 2, ret, LogicalExpr());
+ child = LogicalExpr();
+ if( (ret->type() != ID) && (ret->type() != ARRY_IDX) && (ret->type() != MEMB))
+ {
+ Exception ex;
+ ex << "Expected ID or object reference on left hand side of assignment.";
+ throw ex;
+ }
+ else if( (ret->type() == ARRY_IDX) || (ret->type() == MEMB) )
+ {
+ AST* obj = NULL;
+ AST* idx = NULL;
+ list<AST*>::iterator it = ret->children()->begin();
+ obj = *it;
+ it++;
+ idx = *it;
+ idx->type( (ret->type() == MEMB) ? SYMBOL : idx->type() );
+ ret = new AST(MUTATE, 3, obj, idx, child );
+ }
+ else
+ {
+ ret = new AST(ASSIGN, 2, ret, child);
+ }
}
return ret;
}
// Setup Parser and Visitors
DLParser parser;
Scheme printer(output);
- //Scheme debug_printer(std::cout);
+ Scheme debug_printer(std::cout);
parser.input(new DLLexer(input));
// Parse the input stream
parser.parse();
// Post process the AST (converts to scheme and prints to output file)
- //parser.process( debug_printer );
+ parser.process( debug_printer );
parser.process( printer );
// Close the output file
ret << "define "; break;
case ASSIGN:
ret << "set! "; break;
+ case MUTATE:
+ ret << "obj-set! "; break;
case PROGRAM:
ret << "begin "; break;
case VECTOR:
void Scheme::assignSymbol(AST* cur)
{
- string text = cur->children()->front()->text();
- if( scope_stack.lookup( text ) == NULL )
+ if( cur->type() == ID )
{
- Exception ex;
- ex << "Symbol '" << text << "' has not been defined in this scope.";
- throw ex;
+ string text = cur->children()->front()->text();
+ if( scope_stack.lookup( text ) == NULL )
+ {
+ Exception ex;
+ ex << "Symbol '" << text << "' has not been defined in this scope.";
+ throw ex;
+ }
}
}