]> git.mdlowis.com Git - archive/dlang.git/commitdiff
Tweaked macro and map syntax to allow declaration of empty map literals
authorMike D. Lowis <mike@mdlowis.com>
Sun, 1 Apr 2012 13:00:55 +0000 (09:00 -0400)
committerMike D. Lowis <mike@mdlowis.com>
Sun, 1 Apr 2012 13:00:55 +0000 (09:00 -0400)
LANGUAGE.md
example.dl
source/dllexer/dllexer.cpp
source/dlparser/dlparser.cpp
source/dlparser/macro/pattern.cpp
source/main.cpp
source/options/options.c [new file with mode: 0644]
source/options/options.h [new file with mode: 0644]

index 58b5b91fb7f4a0b0d407f52eb1613e760d5b7d1d..584c8ff545b0a6d80fa2e37bd04af60a37f8a5a7 100644 (file)
@@ -63,14 +63,15 @@ Here are some examples for defining numbers:
 #### Lists
 
     ()          # An empty list
-    (1)         # This is NOT a list. This evaluates to 1
-    (1, 2)      # A list with two numbers
+    (1,)        # A list with one element (Note: the trailing comma
+                # distinguishes this from a grouping expression)
+    (1, 2)      # A list with two elements
     ('a', 1)    # A list with two elements of different types
 
 #### Vectors
 
     []          # An empty vector
-    [1]         # A vector with on element
+    [1]         # A vector with oni element
     [1, 2]      # A vector with two number elements
     ['a', 1]    # A vector with two elements of different types
 
@@ -119,7 +120,7 @@ Anonymous functions and immediate execution
 
 A Work In Progress
 
-### Streams
+### Ports
 
 A Work In Progress
 
index 6ae7a66d41e870242140ccf8729d9ca7c6f28506..582542be08933bf02ec064e23d86ca2ceeaceb79 100644 (file)
@@ -1,7 +1,6 @@
 #------------------------------------------------------------------------------
 # Literal Definition and Usage
 #------------------------------------------------------------------------------
-foo := Nil
 
 # Nums
 assert( 1 == 1,           "Positive integer parses correctly")
@@ -19,10 +18,9 @@ assert('\n', "Parse escape sequence for newline")
 assert('\r', "Parse escape sequence for return")
 assert('\t', "Parse escape sequence for tab")
 assert('\v', "Parse escape sequence for vertical tab")
-#foo = '\xFF'  # Hex Value
 
 # String
-foo = "some string"
+foo := "some string"
 foo = "foo \a \b \f \n \r \t \v \' \" \\ \xFF bar"
 foo = "12345"[2]
 
@@ -30,7 +28,9 @@ foo = "12345"[2]
 foo = $some_symbol
 
 # Map
-foo = {
+foo = @{}
+foo.stuff = "bar"
+foo = @{
     $foo : 1 + 1,
     "stuff" : 2 + 2,
     $stuff : 2 + 2,
@@ -41,11 +41,6 @@ foo = {
 foo["stuff"] = 3
 foo.stuff = 5
 
-# Accessing map elements
-#print( foo[$bar] )
-#print( foo["stuff"] )
-#print( foo.stuff )
-
 # Vector
 foo = []
 foo = [1]
@@ -83,7 +78,7 @@ foo = ({|a,b| a + b })(1,2)
 #------------------------------------------------------------------------------
 
 # Define a macro that represents a traditional if statement
-@ if [
+% if [
     (E B B) : exec_if($1, $2, $3),
     (E B)   : exec_if($1, $2),
 ]
@@ -125,15 +120,48 @@ assert( test_result, "Branch should not be taken when test condition is false" )
 #------------------------------------------------------------------------------
 
 # Define a macro that will delay the evaluation of the following expression
-@ delay [
+% delay [
     (E) : make_promise({ $1 })
 ]
 
 # Define a macro that will force the evaluation of the following delayed statement
-@ force [
+% force [
     (E) : $1()
 ]
 
 foo = delay 1 + 1
 foo = force foo
 
+#------------------------------------------------------------------------------
+# Prototype Classes
+#------------------------------------------------------------------------------
+
+# Define a macro for creating new classes
+#% new [
+#    (I B) : ({
+#        this := @{ $proto : $1 }
+#        $2()
+#        this
+#    })(),
+#
+#    (B) : ({
+#        this := @{}
+#        $2()
+#        this
+#    })()
+#]
+
+#Duck := new foo {
+#    sound := "Quack"
+#    this.mating_call = { sound }
+#}
+#
+#Cow := new foo {
+#    sound := "Moo"
+#    this.mating_call = { sound }
+#}
+
+#print( Duck )
+#print( Duck[$mating_call] )
+#print( (Duck[$mating_call])() )
+
index 235959ac900a9ed1cec4d67d52efc8f3b04a2cec..52587be0ca2890c6248c6f883f42e74f67edb106 100644 (file)
@@ -4,7 +4,7 @@
 
 using namespace std;
 
-#define NUM_SINGLE_CHAR_MATCHES 11
+#define NUM_SINGLE_CHAR_MATCHES 12
 SingleCharMatch_T Single_Character_Matches[ NUM_SINGLE_CHAR_MATCHES ] = {
     { '[', LBRACK },
     { ']', RBRACK },
@@ -17,6 +17,7 @@ SingleCharMatch_T Single_Character_Matches[ NUM_SINGLE_CHAR_MATCHES ] = {
     { '*', MUL },
     { '/', DIV },
     { '.', MEMB },
+    { '%', MACRO },
 };
 
 DLLexer::DLLexer(std::istream& in) : ILexer(in)
@@ -402,7 +403,7 @@ void DLLexer::MultiCharOp(Token& tok)
         }
         else
         {
-            tok = Token(MACRO, line, column);
+            tok = Token(MAP, line, column);
         }
     }
     else
index 69e2c58cf3fe292f7b3367e605c549b2ad7625cf..c7d58b751b8fdd304e4fec3012f3a0237af03c30 100644 (file)
@@ -378,64 +378,61 @@ AST* DLParser::MemberExpr(void)
 AST* DLParser::Literal(void)
 {
     AST* node = NULL;
-    if(speculate_MapLiteral())
+    switch(lookaheadType(1))
     {
-        node = MapLiteral();
-    }
-    else
-    {
-        switch(lookaheadType(1))
-        {
-            // Literal = VectorLiteral
-            case LBRACK:
-                node = VectorLiteral();
-                break;
+        // Literal = VectorLiteral
+        case LBRACK:
+            node = VectorLiteral();
+            break;
 
-            // Literal = ListLiteral
-            case LPAR:
-                node = ListLiteral();
-                break;
+        // Literal = ListLiteral
+        case LPAR:
+            node = ListLiteral();
+            break;
 
-            // Literal = FuncLiteral
-            case LBRACE:
-                node = FuncLiteral();
-                break;
+        // Literal = FuncLiteral
+        case LBRACE:
+            node = FuncLiteral();
+            break;
 
-            // Literal = ID
-            case ID:
-                node = _new AST( ID, lookaheadToken(1).text() );
-                consume();
-                break;
+        case MAP:
+            node = MapLiteral();
+            break;
 
-            // Literal = NUM
-            case NUM:
-                node = _new AST( NUM, lookaheadToken(1).text() );
-                consume();
-                break;
+        // Literal = ID
+        case ID:
+            node = _new AST( ID, lookaheadToken(1).text() );
+            consume();
+            break;
 
-            // Literal = CHAR
-            case CHAR:
-                node = _new AST( CHAR, lookaheadToken(1).text() );
-                consume();
-                break;
+        // Literal = NUM
+        case NUM:
+            node = _new AST( NUM, lookaheadToken(1).text() );
+            consume();
+            break;
 
-            // Literal = STRING
-            case STRING:
-                node = _new AST( STRING, lookaheadToken(1).text() );
-                consume();
-                break;
+        // Literal = CHAR
+        case CHAR:
+            node = _new AST( CHAR, lookaheadToken(1).text() );
+            consume();
+            break;
 
-            // Literal = SYMBOL
-            case SYMBOL:
-                node = _new AST( SYMBOL, lookaheadToken(1).text() );
-                consume();
-                break;
+        // Literal = STRING
+        case STRING:
+            node = _new AST( STRING, lookaheadToken(1).text() );
+            consume();
+            break;
 
-            default:
-                Exception ex( lookaheadToken(1) );
-                ex << "Expected literal type, recieved type " << lookaheadToken(1).type() << ".";
-                throw ex;
-        }
+        // Literal = SYMBOL
+        case SYMBOL:
+            node = _new AST( SYMBOL, lookaheadToken(1).text() );
+            consume();
+            break;
+
+        default:
+            Exception ex( lookaheadToken(1) );
+            ex << "Expected literal type, recieved type " << lookaheadToken(1).type() << ".";
+            throw ex;
     }
     return node;
 }
@@ -445,30 +442,18 @@ AST* DLParser::MapLiteral(void)
 {
     AST* ret = _new AST(MAP);
     AST* child = NULL;
-    try
-    {
-        match(LBRACE);
-        do
-        {
-            child = Literal();
-            match(SEP);
-            child = _new AST(SEP, 2, child, LogicalExpr());
-            ret->addChild(child);
-
-            if( lookaheadType(1) == COMMA ) consume();
-        }
-        while( lookaheadType(1) != RBRACE );
-        match(RBRACE);
-    }
-    catch(Exception e)
+    match(MAP);
+    match(LBRACE);
+    while( lookaheadType(1) != RBRACE )
     {
-        // Cleanup our mess so we dont leak memory
-        delete ret;
-        if(child != NULL) delete child;
+        child = Literal();
+        match(SEP);
+        child = _new AST(SEP, 2, child, LogicalExpr());
+        ret->addChild(child);
 
-        // Re throw the exception so higher-ups can handle it
-        throw e;
+        if( lookaheadType(1) == COMMA ) consume();
     }
+    match(RBRACE);
     return ret;
 }
 
index c4e555496bb7f2c7af810d730cd426bc65376e18..15dfce7eb0092787595c1dbc723549b2fbf543f7 100644 (file)
@@ -1,5 +1,6 @@
 #include "pattern.h"
 #include "dllexer.h"
+#include "exception.h"
 
 using namespace std;
 
@@ -51,7 +52,9 @@ void Pattern::apply(AST* cur,std::vector<AST*>& params)
                 }
                 else
                 {
-                    throw "Invalid parameter number";
+                    Exception ex;
+                    ex << "Invalid parameter number";
+                    throw ex;
                 }
             }
             else
index 1c362e132a618682b904e2d2462d88f8b318b1b8..15e68421089d7d61e7b69f02b99acbb7b28831cb 100644 (file)
@@ -6,6 +6,7 @@
 #include "scheme.h"
 #include "common.h"
 #include "macro.h"
+#include "options.h"
 
 using namespace std;
 
@@ -16,6 +17,8 @@ int main(int argc, char** argv)
 {
     int ret = 0;
 
+    //opts_parse(argc,argv);
+
     if( (argc == 2) && fileExists( argv[1] ) )
     {
         // Setup input and output files
diff --git a/source/options/options.c b/source/options/options.c
new file mode 100644 (file)
index 0000000..7b6c698
--- /dev/null
@@ -0,0 +1,101 @@
+#include "options.h"
+#include <getopt.h>
+#include <cstdlib>
+#include <stdio.h>
+#include <string.h>
+
+static int TempFlag;
+static const char ShortOptions[] = "abc:d:f:";
+static struct option LongOptions[] =
+{
+    /* These options set a flag. */
+    {"verbose", no_argument, &TempFlag, 1},
+    {"brief",   no_argument, &TempFlag, 0},
+
+    /* These options don't set a flag.
+       We distinguish them by their indices. */
+    {"add",     no_argument,       0, 'a'},
+    {"append",  no_argument,       0, 'b'},
+    {"delete",  required_argument, 0, 'd'},
+    {"create",  required_argument, 0, 'c'},
+    {"file",    required_argument, 0, 'f'},
+    {0, 0, 0, 0}
+};
+
+static void opts_handle_opt();
+
+void opts_parse(int argc, char** argv)
+{
+    int short_opt = 0;
+
+    while(1)
+    {
+        int idx = 0;
+        short_opt = getopt_long(argc, argv, ShortOptions, LongOptions, &idx);
+        if(short_opt == -1) break;
+        opts_handle_opt();
+        switch (short_opt)
+             {
+             case 0:
+               /* If this option set a flag, do nothing else now. */
+               if (LongOptions[idx].flag != 0)
+                 break;
+               printf ("option %s", LongOptions[idx].name);
+               if (optarg)
+                 printf (" with arg %s", optarg);
+               printf ("\n");
+               break;
+
+             case 'a':
+               puts ("option -a\n");
+               break;
+
+             case 'b':
+               puts ("option -b\n");
+               break;
+
+             case 'c':
+               printf ("option -c with value `%s'\n", optarg);
+               break;
+
+             case 'd':
+               printf ("option -d with value `%s'\n", optarg);
+               break;
+
+             case 'f':
+               printf ("option -f with value `%s'\n", optarg);
+               break;
+
+             case '?':
+               /* getopt_long already printed an error message. */
+               break;
+
+             default:
+               abort ();
+             }
+    }
+
+    opts_print_usage();
+}
+
+static void opts_handle_opt()
+{
+}
+
+void opts_print_usage()
+{
+    int idx = 0;
+    while(1)
+    {
+        const char* name = LongOptions[idx].name;
+
+        // Breakout if we've reached the end of the list
+        if( name == 0) break;
+
+        if(strlen(name) > 0)
+            printf("--%s\n", name);
+
+        idx++;
+    }
+}
+
diff --git a/source/options/options.h b/source/options/options.h
new file mode 100644 (file)
index 0000000..3331087
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef OPTIONS_H
+#define OPTIONS_H
+
+void opts_parse(int argc, char** argv);
+void opts_print_usage();
+
+#endif