Author: kjs
Date: Wed Apr 11 11:46:56 2007
New Revision: 18142

Modified:
   trunk/compilers/pirc/src/pirlexer.c
   trunk/compilers/pirc/src/pirlexer.h
   trunk/compilers/pirc/src/pirparser.c
   trunk/compilers/pirc/src/pirutil.c
   trunk/compilers/pirc/src/pirutil.h

Log:
compilers/pirc: 
* fix lexer in some places
* fix parser in some places (need some refactoring and clean ups)
* add list of parrot ops from languages/PIR, so now we can parse ops!!

Modified: trunk/compilers/pirc/src/pirlexer.c
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.c (original)
+++ trunk/compilers/pirc/src/pirlexer.c Wed Apr 11 11:46:56 2007
@@ -106,6 +106,15 @@
   :unique_reg
 
 
+=head1 STRING ENCODINGS
+
+The following are string encoding specifiers:
+
+  ascii:
+  binary:
+  iso-8859-1:
+  unicode:
+
 =cut
 
 
@@ -257,6 +266,10 @@
     "heredoc id",               /* T_HEREDOC_ID,            */
     "heredoc string",           /* T_HEREDOC_STRING,        */
     "parrot op",                /* T_PARROT_OP              */
+    "unicode:",                 /* T_UNICODE                */
+    "ascii:",                   /* T_ASCII                  */
+    "binary:",                  /* T_BINARY                 */
+    "iso-8859-1:",              /* T_ISO_8859_1             */
     NULL                        /*                          */
 };
 
@@ -682,26 +695,6 @@
 }
 
 
-/*
-
-=item is_op()
-
-TODO: check whether 'word' is an op. How does IMCC handle this?
-Is there an API call that checks for this?
-
-Function to check if the specified id is a Parrot op.
-Dynamically loaded op libraries need to be considered as well.
-
-=cut
-
-*/
-static int
-is_op(char *word) {
-    if (strcmp(word, "add") == 0) return 1; /* hardcoded some, to give an idea 
*/
-    if (strcmp(word, "print") == 0) return 1;
-    if (strcmp(word, "new") == 0) return 1;
-    return 0;
-}
 
 
 /*
@@ -812,6 +805,35 @@
 }
 
 
+/*
+
+=item read_string()
+
+Read a quoted string.
+
+=cut
+
+*/
+static token
+read_string(lexer_state *lexer, char delimiter) {
+    char c;
+    buffer_char(lexer, delimiter); /* buffer first delimiter */
+    do {
+        c = read_char(lexer->curfile);
+        if (c == '\n') {
+            fprintf(stderr, "Possibly a run-away string on line %ld\n", 
lexer->curfile->line);
+            buffer_char(lexer, delimiter); /* try to fix it */
+            update_line(lexer);
+            return T_ERROR;
+        }
+        if (c == EOF_MARKER) return T_EOF;
+        buffer_char(lexer, c);
+    }
+    while (c != delimiter);
+
+    return T_STRING_CONSTANT;
+}
+
 
 
 /*
@@ -1117,9 +1139,9 @@
             if (c == 'P' || c == 'I' || c == 'N' || c == 'S') {
                 int count;
                 char regtype = c; /* store register type for later */
-                buffer_char(lexer, c);
-                count = read_digits(lexer);
-                c = read_char(lexer->curfile);
+                buffer_char(lexer, c); /* store current char. */
+                count = read_digits(lexer); /* read digits and count how many 
*/
+                c = read_char(lexer->curfile); /* the last one was not a 
digit, re-read it */
 
                 /* only if the current char is not an alpha and we just read a 
number of digits,
                  * can this be a pasm register. */
@@ -1150,8 +1172,17 @@
 
             /* we got some kind of an identifier, maybe it's a label, 
invocant, etc */
             if (c == ':') { /* label -> IDENT':' */
+                token tmp;
                 buffer_char(lexer, c);
-                return T_LABEL;
+
+                /* it might be a string encoding specifier */
+                tmp = check_dictionary(lexer, dictionary);
+
+                if (tmp == T_NOT_FOUND) return T_LABEL;
+                else {
+                    c = read_char(lexer->curfile); /* this should be a quote 
char. */
+                    return read_string(lexer, c);
+                }
             }
             else if (c == '.') { /* invocant_id -> IDENT'.' */
                 return T_INVOCANT_IDENT;
@@ -1256,7 +1287,7 @@
                     c = read_char(lexer->curfile);
                     if (c == EOF_MARKER) return T_EOF;
 
-                    while (isalnum(c)) { /* this is all part of the label name 
*/
+                    while (isalnum(c) || c == '_') { /* this is all part of 
the label name */
                         buffer_char(lexer, c);
                         c = read_char(lexer->curfile);
                         if (c == EOF_MARKER) return T_EOF;
@@ -1266,8 +1297,9 @@
                     if (c == ':') {
                         return T_MACRO_LABEL;
                     }
-                    else { /* $ ??? */
+                    else { /* $ ??? unexpected, put it back */
                         unread_char(lexer->curfile);
+                        fprintf(stderr, "Unknown token starting with '$'\n");
                         return T_ERROR;
                     }
             }
@@ -1275,11 +1307,24 @@
             buffer_char(lexer, c);
 
             numdigits = read_digits(lexer);
+
+            /* read next char, maybe a dot? */
+            c = read_char(lexer->curfile);
+
             if (numdigits == 0) {
+                unread_char(lexer->curfile);
                 fprintf(stderr, "digits expected (line %d)\n", 
lexer->curfile->line);
                 return T_ERROR;
             }
-            return regtype; /* return register */
+
+            if (c == '.') { /* $P0. and friends */
+                buffer_char(lexer, c);
+                return T_INVOCANT_IDENT;
+            }
+            else { /* just a simple pir reg $P0 */
+                unread_char(lexer->curfile);
+                return regtype; /* return register */
+            }
         }
 
 
@@ -1398,8 +1443,26 @@
                 case '=': return T_MINUS_ASSIGN; /* -= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile);
-                    return T_MINUS;
+
+                    /* TODO: refactor this number reading code, it's also 
somewhere else */
+
+                    if (isdigit(c)) { /* handle negative numbers here */
+                        int count = read_digits(lexer);
+                        c = read_char(lexer->curfile);
+                        if (c == '.') {
+                            buffer_char(lexer, c);
+                            read_digits(lexer);
+                            return T_NUMBER_CONSTANT;
+                        }
+                        else {
+                            unread_char(lexer->curfile);
+                            return T_INTEGER_CONSTANT;
+                        }
+                    }
+                    else { /* no negative number, just a minus sign */
+                        unread_char(lexer->curfile);
+                        return T_MINUS;
+                    }
             }
         }
         else if (c == '!') {
@@ -1526,7 +1589,6 @@
                 if (c == '\n') update_line(lexer);
                 else if (c == EOF_MARKER) return T_EOF;
             }
-            /* while ( c == ' ' || c == '\t' || c == '\n' || c == '\r');  */
             while (isspace(c));
 
             /* the last read char. was not space/newline, put it back */
@@ -1535,38 +1597,10 @@
             return T_NEWLINE;
         }
         else if (c == '"') {
-            buffer_char(lexer, c);
-            do {
-                c = read_char(lexer->curfile);
-                if (c == '\n') {
-                    fprintf(stderr, "Possibly a run-away string on line 
%ld\n", lexer->curfile->line);
-                    buffer_char(lexer, '"'); /* try to fix it */
-                    update_line(lexer);
-                    return T_ERROR;
-                }
-                if (c == EOF_MARKER) return T_EOF;
-                buffer_char(lexer, c);
-            }
-            while (c != '"');
-
-            return T_STRING_CONSTANT;
+            return read_string(lexer, c);
         }
         else if (c == '\'') {
-            buffer_char(lexer, c);
-            do {
-                c = read_char(lexer->curfile);
-                if (c == '\n') {
-                    fprintf(stderr, "Possibly a run-away string on line 
%ld\n", lexer->curfile->line);
-                    buffer_char(lexer, '"'); /* try to fix it */
-                    update_line(lexer);
-                    return T_ERROR;
-                }
-                if (c == EOF_MARKER) return T_EOF;
-                buffer_char(lexer, c);
-            }
-            while (c != '\'');
-
-            return T_STRING_CONSTANT;
+            return read_string(lexer, c);
         }
         else if (c == ':') { /* read flags */
             token tmp;
@@ -1576,13 +1610,16 @@
                 c = read_char(lexer->curfile);
                 if (c == EOF_MARKER) return T_EOF;
             }
-            while ( isalnum(c) );
+            while ( isalnum(c) || c == '_' );
 
             unread_char(lexer->curfile); /* push back last character not 
needed */
             tmp = check_dictionary(lexer, dictionary);
 
             /* if not found, then no valid flag found */
-            if (tmp == T_NOT_FOUND) return T_ERROR;
+            if (tmp == T_NOT_FOUND) {
+                fprintf(stderr, "invalid flag: '%s'\n", lexer->token_chars);
+                return T_ERROR;
+            }
             else return tmp;
         }
         else if (c == 0) { /* this is necessary since svn properties on input 
files */

Modified: trunk/compilers/pirc/src/pirlexer.h
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.h (original)
+++ trunk/compilers/pirc/src/pirlexer.h Wed Apr 11 11:46:56 2007
@@ -141,8 +141,12 @@
     T_LSHIFT_ASSIGN,                    /* "<<=",                     */
     T_HEREDOC_ID,                       /* "heredoc id",              */
     T_HEREDOC_STRING,                   /* "heredoc string",          */
-    T_PARROT_OP                         /* "parrot op",               */
-                                            /* NULL                       */
+    T_PARROT_OP,                        /* "parrot op",               */
+    T_UNICODE,                          /* "unicode:",                */
+    T_ASCII,                                                   /* "ascii:",    
              */
+    T_BINARY,                                              /* "binary:",       
          */
+    T_ISO_8859_1                                               /* 
"iso-8859-1:"              */
+    /* NULL                                                           */
 } token;
 
 /* Make sure MAX_TOKEN is the last enum value from enum token {} */

Modified: trunk/compilers/pirc/src/pirparser.c
==============================================================================
--- trunk/compilers/pirc/src/pirparser.c        (original)
+++ trunk/compilers/pirc/src/pirparser.c        Wed Apr 11 11:46:56 2007
@@ -545,6 +545,64 @@
     match(p, T_RBRACKET); /* match closing ']' */
 }
 
+
+
+/*
+
+=item *
+
+  arg_flags -> { arg_flag }
+
+  arg_flag -> ':flat' | ':named' [ '(' STRINGC ')' ]
+
+=cut
+
+*/
+static void
+arg_flags(parser_state *p) {
+    while (p->curtoken != T_NEWLINE) {
+        switch (p->curtoken) {
+            case T_FLAT_FLAG:
+                next(p);
+                break;
+            case T_NAMED_FLAG:
+                next(p);
+                if (p->curtoken == T_LPAREN) {
+                    next(p);
+                    match(p, T_STRING_CONSTANT);
+                    match(p, T_RPAREN);
+                }
+                break;
+            default:
+                syntax_error(p, 1, "':flat' or ':named' flag expected");
+                break;
+        }
+    }
+}
+
+static void
+inline_arg_flags(parser_state *p) {
+    int ok = 1;
+    while (ok) {
+        switch (p->curtoken) {
+            case T_FLAT_FLAG:
+                next(p);
+                break;
+            case T_NAMED_FLAG:
+                next(p);
+                if (p->curtoken == T_LPAREN) {
+                    next(p);
+                    match(p, T_STRING_CONSTANT);
+                    match(p, T_RPAREN);
+                }
+                break;
+            default:
+                ok = 0; /* quit loop */
+                break;
+        }
+    }
+}
+
 /*
 
 =item *
@@ -575,6 +633,12 @@
                 next(p);
                 expression(p);
             }
+            else {
+                inline_arg_flags(p);
+            }
+        }
+        else {
+            inline_arg_flags(p);
         }
     }
 }
@@ -735,11 +799,20 @@
      * instruction and wait for run-time error?
      */
     while (p->curtoken != T_NEWLINE) {
+
+        /* XXX for now, just skip ANYTHING until a newline. This is so we can 
handle
+         * "delete obj[bla] etc.
+         */
+        next(p);
+
+        /*
         expression(p);
+
         if (p->curtoken == T_COMMA) {
             next(p);
         }
         else break;
+        */
     }
 
     emit_op_end(p);
@@ -1220,41 +1293,6 @@
 }
 
 
-
-
-/*
-
-=item *
-
-  arg_flags -> { arg_flag }
-
-  arg_flag -> ':flat' | ':named' [ '(' STRINGC ')' ]
-
-=cut
-
-*/
-static void
-arg_flags(parser_state *p) {
-    while (p->curtoken != T_NEWLINE) {
-        switch (p->curtoken) {
-            case T_FLAT_FLAG:
-                next(p);
-                break;
-            case T_NAMED_FLAG:
-                next(p);
-                if (p->curtoken == T_LPAREN) {
-                    next(p);
-                    match(p, T_STRING_CONSTANT);
-                    match(p, T_RPAREN);
-                }
-                break;
-            default:
-                syntax_error(p, 1, "':flat' or ':named' flag expected");
-                break;
-        }
-    }
-}
-
 /*
 
 =item *

Modified: trunk/compilers/pirc/src/pirutil.c
==============================================================================
--- trunk/compilers/pirc/src/pirutil.c  (original)
+++ trunk/compilers/pirc/src/pirutil.c  Wed Apr 11 11:46:56 2007
@@ -76,6 +76,361 @@
 }
 
 
+
+
+
+
+
+
+static char const *parrot_ops[] = {
+        "yield",
+        "xor",
+        "warningson",
+        "warningsoff",
+        "valid_type",
+        "upcase",
+        "unshift",
+        "unregister",
+        "unpin",
+        "unless_null",
+        "unless",
+        "typeof",
+        "trans_encoding",
+        "trans_charset",
+        "trace",
+        "titlecase",
+        "time",
+        "throw",
+        "thaw",
+        "tell",
+        "tanh",
+        "tan",
+        "tailcallmethod",
+        "tailcall",
+        "sysinfo",
+        "sweepon",
+        "sweepoff",
+        "sweep",
+        "substr",
+        "subclass",
+        "sub",
+        "stringinfo",
+        "store_lex",
+        "stat",
+        "sqrt",
+        "sprintf",
+        "split",
+        "spawnw",
+        "socket",
+        "sockaddr",
+        "sleep",
+        "sizeof",
+        "sinh",
+        "singleton",
+        "sin",
+        "shr",
+        "shl",
+        "shift",
+        "setstdout",
+        "setstderr",
+        "sets_ind",
+        "setref",
+        "setprop",
+        "setp_ind",
+        "setn_ind",
+        "seti_ind",
+        "setattribute",
+        "set_root_global",
+        "set_returns",
+        "set_hll_global",
+        "set_global",
+        "set_args",
+        "set_addr",
+        "set",
+        "send",
+        "seek",
+        "sech",
+        "sec",
+        "savec",
+        "saveall",
+        "save",
+        "runinterp",
+        "rotate_up",
+        "rot",
+        "returncc",
+        "rethrow",
+        "ret",
+        "result_info",
+        "restoreall",
+        "restore",
+        "reserved",
+        "repeat",
+        "removeparent",
+        "removedoes",
+        "removeattribute",
+        "register",
+        "recv",
+        "readline",
+        "read",
+        "pushmark",
+        "pushaction",
+        "push_eh",
+        "push",
+        "prophash",
+        "profile",
+        "printerr",
+        "print",
+        "pow",
+        "popmark",
+        "pop",
+        "poll",
+        "pioctl",
+        "pin",
+        "peek",
+        "ord"
+        "or",
+        "open",
+        "null",
+        "not",
+        "noop",
+        "newclosure",
+        "newclass",
+        "new_callback",
+        "new",
+        "new",
+        "neg",
+        "needs_destroy",
+        "ne_str",
+        "ne_num",
+        "ne_addr",
+        "ne",
+        "n_repeat",
+        "n_not",
+        "n_neg",
+        "n_infix",
+        "n_concat",
+        "n_bnots"
+        "n_bnot"
+        "n_abs",
+        "mul",
+        "mod",
+        "mmdvtregister",
+        "mmdvtfind",
+        "lt_str",
+        "lt_num",
+        "lt_addr",
+        "lt",
+        "lsr",
+        "lookback",
+        "log2",
+        "log10",
+        "localtime",
+        "loadlib",
+        "load_bytecode",
+        "ln",
+        "listen",
+        "length",
+        "le_str",
+        "le_num",
+        "le_addr",
+        "le",
+        "lcm",
+        "jsr",
+        "join",
+        "istrue",
+        "issame",
+        "isnull",
+        "isntsame",
+        "isne",
+        "islt",
+        "isle",
+        "isgt",
+        "isge",
+        "isfalse",
+        "iseq",
+        "isa",
+        "is_cclass",
+        "invokecc",
+        "invoke",
+        "interpinfo",
+        "infix",
+        "index",
+        "inc",
+        "if_null",
+        "if",
+        "hash",
+        "gt_str",
+        "gt_num",
+        "gt_addr",
+        "gt",
+        "gmtime",
+        "getstdout",
+        "getstdin",
+        "getstderr",
+        "getprop",
+        "getline",
+        "getinterp",
+        "getfile",
+        "getfd",
+        "getclass",
+        "getattribute",
+        "get_root_namespace",
+        "get_root_global",
+        "get_results",
+        "get_repr",
+        "get_params",
+        "get_namespace",
+        "get_mro",
+        "get_hll_namespace",
+        "get_hll_global",
+        "get_global",
+        "get_addr",
+        "ge_str",
+        "ge_num",
+        "ge_addr",
+        "ge",
+        "gcd",
+        "gc_debug",
+        "freeze",
+        "floor",
+        "find_type",
+        "find_not_cclass",
+        "find_name",
+        "find_method",
+        "find_lex",
+        "find_encoding",
+        "find_charset",
+        "find_cclass",
+        "fdopen",
+        "fdiv",
+        "fact",
+        "exp",
+        "exit",
+        "exists",
+        "exchange",
+        "escape",
+        "errorson",
+        "errorsoff",
+        "err",
+        "eq_str",
+        "eq_num",
+        "eq_addr",
+        "eq",
+        "entrytype",
+        "enternative",
+        "end",
+        "encoding",
+        "elements",
+        "downcase",
+        "does",
+        "dlvar",
+        "dlfunc",
+        "div",
+        "die",
+        "deref",
+        "depth",
+        "delprop",
+        "delete",
+        "defined",
+        "decodetime",
+        "decodelocaltime",
+        "dec",
+        "debug_print",
+        "debug_load",
+        "debug_init",
+        "debug_break",
+        "debug",
+        "cosh",
+        "cos",
+        "connect",
+        "concat",
+        "compreg",
+        "compose",
+        "collecton",
+        "collectoff",
+        "collect",
+        "cmp_str",
+        "cmp_num",
+        "cmp",
+        "cmod",
+        "close",
+        "clone",
+        "clears",
+        "clearp",
+        "clearn",
+        "cleari",
+        "clear_eh",
+        "classoffset",
+        "classname",
+        "class",
+        "chr",
+        "chopn",
+        "charsetname",
+        "charset",
+        "ceil",
+        "can",
+        "callmethodcc",
+        "callmethod",
+        "bytelength",
+        "bxors",
+        "bxor",
+        "bsr",
+        "branch_cs",
+        "branch",
+        "bounds",
+        "bors",
+        "bor",
+        "bnots",
+        "bnot",
+        "bind",
+        "bands",
+        "band",
+        "backtrace",
+        "atan",
+        "assign",
+        "asin",
+        "asec",
+        "and",
+        "addparent",
+        "addmethod",
+        "adddoes",
+        "addattribute",
+        "add",
+        "acos",
+        "accept",
+        "abs",
+        NULL
+};
+
+
+
+/*
+
+=item is_op()
+
+Return 1 if the specified id is a Parrot op, 0 otherwise.
+
+=cut
+
+*/
+int
+is_op(char *id) {
+    char const *iter = parrot_ops[0];
+    int index = 0;
+
+    assert(id != NULL);
+
+    while (iter != NULL) {
+        if (strcmp(iter, id) == 0)
+            return 1;
+
+        iter = parrot_ops[++index];
+    }
+
+    return 0;
+}
+
+
 /*
 
 =back

Modified: trunk/compilers/pirc/src/pirutil.h
==============================================================================
--- trunk/compilers/pirc/src/pirutil.h  (original)
+++ trunk/compilers/pirc/src/pirutil.h  Wed Apr 11 11:46:56 2007
@@ -18,6 +18,9 @@
 #  define debug(P,S)    if (P->flags & PIRC_DEBUG)   printdebug(S)
 */
 
+
+extern int is_op(char *id);
+
 #endif
 
 /*

Reply via email to