Author: kjs
Date: Sat Mar 31 02:47:12 2007
New Revision: 17875

Added:
   trunk/compilers/pirc/src/pirvtable.c   (contents, props changed)
Modified:
   trunk/compilers/pirc/src/pirlexer.c
   trunk/compilers/pirc/src/pirlexer.h
   trunk/compilers/pirc/src/pirmain.c
   trunk/compilers/pirc/src/pirout.c
   trunk/compilers/pirc/src/pirparser.c
   trunk/compilers/pirc/src/pirparser.h
   trunk/compilers/pirc/src/pirvtable.h
   trunk/config/gen/makefiles/pirc.in

Log:
compilers/pirc:
* added vtable entries
* remove no_output.{c,h} files
* clean up here and there
* better PIR output
* better PAST output
* not finished :-) but working nicely

Modified: trunk/compilers/pirc/src/pirlexer.c
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.c (original)
+++ trunk/compilers/pirc/src/pirlexer.c Sat Mar 31 02:47:12 2007
@@ -368,6 +368,34 @@
     return s->curfile->line;
 }
 
+/*
+
+=item get_current_linepos()
+
+Returns the current line position (i.o.w., how many characters
+have been read on the current line?)
+
+=cut
+
+*/
+unsigned short
+get_current_linepos(struct lexer_state *s) {
+    return s->curfile->linepos;
+}
+
+/*
+
+=item get_current_filepos()
+
+Returns the number of charactars read in the current file so far.
+
+=cut
+
+*/
+long
+get_current_filepos(struct lexer_state *s) {
+    return (s->curfile->curchar - s->curfile->buffer);
+}
 
 /*
 

Modified: trunk/compilers/pirc/src/pirlexer.h
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.h (original)
+++ trunk/compilers/pirc/src/pirlexer.h Sat Mar 31 02:47:12 2007
@@ -181,6 +181,12 @@
 /* get the current line number */
 extern long get_current_line(struct lexer_state *s);
 
+/* get the current line position */
+extern unsigned short get_current_linepos(struct lexer_state *s);
+
+/* get current file position */
+extern long get_current_filepos(struct lexer_state *s);
+
 /* get the name of the current file being scanned */
 extern char * const get_current_file(struct lexer_state *s);
 

Modified: trunk/compilers/pirc/src/pirmain.c
==============================================================================
--- trunk/compilers/pirc/src/pirmain.c  (original)
+++ trunk/compilers/pirc/src/pirmain.c  Sat Mar 31 02:47:12 2007
@@ -1,6 +1,22 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "pirparser.h"
+#include "pirout.h"    /* for PIR output    */
+#include "pastout.h"   /* for PAST output   */
+
+
+/* define output type: what kind of semantic routines
+ * should be called in the parser? 
+ */
+typedef enum outputtypes {
+               OUTPUT_NONE,    /* do nothing  */
+               OUTPUT_PIR,     /* output PIR  */
+               OUTPUT_PAST     /* output PAST */
+               
+} outputtype; 
+
+
+
 
 /* main()
  *
@@ -11,24 +27,51 @@
 main(int argc, char **argv) {
 
     struct parser_state *p = NULL;
-
+    pirvtable *vtable      = NULL;
+    
+    /* make this a commandline switch */
+    int output;
+    
+    //output = OUTPUT_PAST;    
+    output = OUTPUT_PIR;
+    
+    
     if (argc < 2) {
         fprintf(stderr, "usage: %s <file>\n", argv[0]);
         exit(1);
     }
 
-
-    /* create a new parser, specifying the file name */
-    p = new_parser(argv[1], OUTPUT_PAST);
+    
+    switch (output) {
+        case OUTPUT_NONE:
+            /* just create an empty vtable, the default implementation does 
nothing */
+            vtable = new_pirvtable();
+            break;
+        case OUTPUT_PIR:
+            vtable = init_pir_vtable();
+            break;
+        case OUTPUT_PAST:
+            vtable = init_past_vtable();
+            break;
+        default:
+            fprintf(stderr, "Unknown output type specified\n");
+            exit(1);
+    }
+    
+    
+    /* create a new parser, specifying the file name and the vtable */
+    p = new_parser(argv[1], vtable);
 
     /* start parsing */
     TOP(p);
 
     /* check for errors */
-    if (get_parse_errors(p))
+    if (get_parse_errors(p)) {
         fprintf(stderr, "\nThere were %d errors.\n", get_parse_errors(p));
-    else
+    }
+    else {
         fprintf(stderr, "\nparsed successfully.\n");
+    }
 
     /* clean up and exit */
     exit_parser(p);

Modified: trunk/compilers/pirc/src/pirout.c
==============================================================================
--- trunk/compilers/pirc/src/pirout.c   (original)
+++ trunk/compilers/pirc/src/pirout.c   Sat Mar 31 02:47:12 2007
@@ -4,6 +4,9 @@
 #include <stdio.h>
 #include <malloc.h>
 
+
+#define OUT stderr
+
 /*
 
 =head1 API
@@ -57,9 +60,24 @@
 
 static void
 pir_name(struct parser_state *p, char *name) {
-    fprintf(stderr, " %s ", name);
+    fprintf(OUT, " %s ", name);
+}
+
+static void
+pir_sub(struct parser_state *p, char *source, int pos) {
+    fprintf(OUT, "#character position %d\n", pos);
+    fprintf(OUT, ".sub");
 }
 
+static void
+pir_end(struct parser_state *p) {
+    fprintf(OUT, ".end\n");
+}
+
+static void
+pir_newline(struct parser_state *p, ...) {
+    fprintf(OUT, "\n");
+}
 
 /*
 
@@ -73,11 +91,13 @@
 */
 pirvtable *
 init_pir_vtable(void) {
-    pirvtable *vtable = (pirvtable *)malloc(sizeof(pirvtable));
+    pirvtable *vtable = new_pirvtable();
 
-    vtable->sub_start = pirout;
-    vtable->sub_end   = pirout;
-    vtable->name      = pir_name;
+    /* override the methods that are needed for PIR output */
+    vtable->sub_start   = pir_sub;
+    vtable->sub_end     = pir_end;
+    vtable->name        = pir_name;
+    vtable->stmts_start = pir_newline;
 
     return vtable;
 }

Modified: trunk/compilers/pirc/src/pirparser.c
==============================================================================
--- trunk/compilers/pirc/src/pirparser.c        (original)
+++ trunk/compilers/pirc/src/pirparser.c        Sat Mar 31 02:47:12 2007
@@ -57,10 +57,7 @@
 #include "pirparser.h"
 
 /* output stuff */
-#include "pirvtable.h"
-#include "pirout.h"    /* for PIR output  */
-#include "pastout.h"   /* for PAST output */
-#include "no_output.h" /* guess what...   */
+#include "pirvtable.h" /* vtable definition */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -80,7 +77,7 @@
     char      *heredoc_ids[10];        -- array for holding heredoc arguments. 
XXX Limited to 10 currently XXX
     unsigned   heredoc_index;          -- index to keep track of heredoc ids 
in the array
     unsigned   parse_errors;           -- counter for parse_errors
-    pirvtable *vtable;                 -- vtable holding pointers for output
+    pirvtable *vtable;                 -- vtable holding pointers for output 
routines
  }
 
 =cut
@@ -102,13 +99,9 @@
 #define MAX_ERRORS  10
 
 
-/* call next() to get the next token from the lexer */ /* NOTE: it's calling 
pirout() */
-
+/* call next() to get the next token from the lexer */
 #define next(P) P->curtoken = next_token(P->lexer)
 
-/*
-#define next(P) do { pirout(P); P->curtoken = next_token(P->lexer); } while(0)
-*/
 
 
 /*
@@ -153,13 +146,17 @@
 
 =item new_parser()
 
-constructor for a parser_state object.
+constructor for a parser_state object. The specified filename
+is parsed. The semantic actions in vtable are called at certain
+points in the code. The vtable is constructed in the parser's
+client code.
 
 =cut
 
 */
 parser_state *
-new_parser(char const * filename, outputtype output) {
+new_parser(char const * filename, pirvtable *vtable) {
+
     parser_state *p = (parser_state *)malloc(sizeof(parser_state));
 
     if (p == NULL) {
@@ -170,22 +167,7 @@
     p->curtoken      = next_token(p->lexer);
     p->parse_errors  = 0;
     p->heredoc_index = 0;
-
-    /* based on the output type, create the appropiate vtable */
-    switch (output) {
-        case OUTPUT_NONE:
-            p->vtable = init_none_vtable();
-            break;
-        case OUTPUT_PIR:
-            p->vtable = init_pir_vtable();
-            break;
-        case OUTPUT_PAST:
-            p->vtable = init_past_vtable();
-            break;
-        default:
-            fprintf(stderr, "Unknown output type specified\n");
-            exit(1);
-    }
+    p->vtable        = vtable;
 
     return p;
 }
@@ -1807,31 +1789,32 @@
 */
 static void
 sub_definition(parser_state *p) {
-    /* either '.sub' or '.pcc_sub'. This kind of optimization (just skipping)
-     * can be done more often, if we're sure the token has already been 
checked for.
-     */
-
     /* call emit method */
-    emit_sub_start(p);
-
-    next(p);
+    emit_sub_start(p, "", get_current_filepos(p->lexer));
+    next(p); /* skip '.sub' or '.pcc_sub' */
 
-    if (p->curtoken == T_IDENTIFIER) {
-        emit_name(p, get_current_token(p->lexer));
-        match(p, T_IDENTIFIER);
-    }
-    else {
-        emit_name(p, get_current_token(p->lexer));
-        stringconstant(p);
+    switch (p->curtoken) {
+        case T_IDENTIFIER:
+        case T_DOUBLE_QUOTED_STRING:
+        case T_SINGLE_QUOTED_STRING:
+            emit_name(p, get_current_token(p->lexer)); /* emit the name */
+            next(p); /* and get next token */
+            break;
+        default:
+            syntax_error(p, 1, "sub identifier expected");
+            break;
     }
 
     sub_flags(p);
     match(p, T_NEWLINE);
+
     parameters(p);
+    emit_stmts_start(p); /* open stmts block */
     instructions(p);
+    emit_stmts_end(p);  /* close stmts block */
     match(p, T_END);
 
-    /* call emit method */
+    /* call emit method to close sub*/
     emit_sub_end(p);
 
 }
@@ -2114,12 +2097,16 @@
     /* the file may have some initial newlines; eat them */
     if (p->curtoken == T_NEWLINE) next(p);
 
+    emit_init(p); /* initialize emitter */
+
     compilation_unit(p);
 
     while (p->curtoken != T_EOF ) {
         match(p, T_NEWLINE);
         compilation_unit(p);
     }
+
+    emit_end(p); /* close down emitter */
 }
 
 /*

Modified: trunk/compilers/pirc/src/pirparser.h
==============================================================================
--- trunk/compilers/pirc/src/pirparser.h        (original)
+++ trunk/compilers/pirc/src/pirparser.h        Sat Mar 31 02:47:12 2007
@@ -7,17 +7,9 @@
 /* hide internals; definition in pirparser.c */
 struct parser_state;
 
-/* define output type: what kind of semantic routines
- * should be called in the parser?
- */
-typedef enum outputtypes {
-    OUTPUT_NONE,    /* do nothing  */
-    OUTPUT_PIR,     /* output PIR  */
-    OUTPUT_PAST     /* output PAST */
-} outputtype;
 
 /* parser constructor */
-extern struct parser_state *new_parser(char const * filename, outputtype type);
+extern struct parser_state *new_parser(char const * filename, pirvtable 
*vtable);
 
 /* entry function for the parser */
 extern void TOP(struct parser_state *p);

Added: trunk/compilers/pirc/src/pirvtable.c
==============================================================================
--- (empty file)
+++ trunk/compilers/pirc/src/pirvtable.c        Sat Mar 31 02:47:12 2007
@@ -0,0 +1,96 @@
+/*
+
+=head1 NAME
+
+pirvtable.c - implementation of a vtable, that is used by the parser for its 
semantic actions.
+
+=head1 DESCRIPTION
+
+Using a vtable makes changing the behaviour of the parser easy. The parser 
calls vtable methods
+at certain points, for instance at the start of a subroutine and at the end. 
Depending on the
+type of output that is expected, the appropiate function is invoked. Any 
output type should
+implement all vtable methods for correct behaviour.
+
+=cut
+
+*/
+#include "pirvtable.h"
+#include "pirparser.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+
+
+/*
+
+=head1 HELPER METHODS
+
+=over 4
+
+=item not_implemented()
+
+Default entry that is set to all vtable entries. If a particular vtable entry 
is invoked,
+but was never implemented, this method is called. This is usefule, because not 
all output
+type need all vtable methods. The variable arguments are necessary, you never 
know how
+many args a method has.
+
+=cut
+
+*/
+static void
+not_implemented(struct parser_state *p, ...) {
+    /* do nothing */
+}
+
+/*
+
+=back
+
+=head1 PIRVTABLE API
+
+=over 4
+
+=item new_pirvtable()
+
+Constructor for a pir vtable. All entries are set to "not_implemented" 
function.
+
+=cut
+
+*/
+pirvtable *
+new_pirvtable(void) {
+    pirvtable *vtable = (pirvtable *)malloc(sizeof(pirvtable));
+
+    if (vtable == NULL) {
+        fprintf(stderr, "Failed to allocate memory for vtable!\n");
+        exit(1);
+    }
+
+    /* set all entries to 'default' by default */
+    vtable->initialize  = not_implemented;
+    vtable->name        = not_implemented;
+    vtable->sub_start   = not_implemented;
+    vtable->sub_end     = not_implemented;
+    vtable->stmts_start = not_implemented;
+    vtable->stmts_end   = not_implemented;
+    vtable->end         = not_implemented;
+
+    return vtable;
+}
+
+/*
+
+=back
+
+=cut
+
+*/
+
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
+

Modified: trunk/compilers/pirc/src/pirvtable.h
==============================================================================
--- trunk/compilers/pirc/src/pirvtable.h        (original)
+++ trunk/compilers/pirc/src/pirvtable.h        Sat Mar 31 02:47:12 2007
@@ -8,20 +8,28 @@
  */
 typedef struct pirvtable {
 
-       void (* sub_start)(struct parser_state *p);
-       void (* sub_end)  (struct parser_state *p);
-       void (* name)     (struct parser_state *p, char *name);
+       void (* initialize)  (struct parser_state *p);
+       void (* sub_start)   (struct parser_state *p, char *source, int pos);
+       void (* sub_end)     (struct parser_state *p);
+       void (* name)        (struct parser_state *p, char *name);
+       void (* stmts_start) (struct parser_state *p);
+       void (* stmts_end)   (struct parser_state *p);
+       void (* end)         (struct parser_state *p);
 
 } pirvtable;
 
 
 
 /* #defines for cleaner invocation syntax */
-#  define emit_sub_start(P)    (*P->vtable->sub_start)(P)
-#  define emit_sub_end(P)      (*P->vtable->sub_end)  (P)
-#  define emit_name(P,N)       (*P->vtable->name)   (P,N)
-
+#  define emit_init(P)              (*P->vtable->initialize) (P)
+#  define emit_sub_start(P,S,L)     (*P->vtable->sub_start)  (P,S,L)
+#  define emit_sub_end(P)                      (*P->vtable->sub_end)    (P)
+#  define emit_name(P,N)                       (*P->vtable->name)       (P,N)
+#  define emit_stmts_start(P)       (*P->vtable->stmts_start)(P)
+#  define emit_stmts_end(P)         (*P->vtable->stmts_end)  (P)
+#  define emit_end(P)               (*P->vtable->end)        (P)
 
+extern pirvtable *new_pirvtable(void);
 
 
 #endif

Modified: trunk/config/gen/makefiles/pirc.in
==============================================================================
--- trunk/config/gen/makefiles/pirc.in  (original)
+++ trunk/config/gen/makefiles/pirc.in  Sat Mar 31 02:47:12 2007
@@ -1,26 +1,26 @@
 
 
-# Setup some commands
-LN_S     = @lns@
-PERL     = @perl@
-RM_RF    = @rm_rf@
-PARROT   = ../../[EMAIL PROTECTED]@
+# Setup        some commands
+LN_S    = @lns@
+PERL    = @perl@
+RM_RF   = @rm_rf@
+PARROT  = ../../[EMAIL PROTECTED]@
 TOOL_DIR = ../..
-CC       = @cc@
-CP       = @cp@
-BUILD    = $(PERL) @build_dir@/tools/build/dynpmc.pl
-O        = @o@
-EXE      = @exe@
+CC              = @cc@
+CP              = @cp@
+BUILD   = $(PERL) @build_dir@/tools/build/dynpmc.pl
+O               = @o@
+EXE             = @exe@
 
-CC_INC     = @cc_inc@
-C_LIBS     = @libs@
+CC_INC    = @cc_inc@
+C_LIBS    = @libs@
 CC_SHARED  = @cc_shared@
-CFLAGS     = $(CC_INC) @ccflags@ @cc_debug@ @ccwarn@ @cc_hasjit@ @cg_flag@ 
@gc_flag@ $(CC_SHARED)
-LINK_DYNAMIC  = @link_dynamic@
-LINK       = @link@
+CFLAGS    = $(CC_INC) @ccflags@ @cc_debug@     @ccwarn@ @cc_hasjit@ @cg_flag@ 
@gc_flag@ $(CC_SHARED)
+LINK_DYNAMIC  =        @link_dynamic@
+LINK      = @link@
 LINKFLAGS  = @linkflags@ @link_debug@ @ld_debug@
-LD         = @ld@
-LDFLAGS    = @ldflags@ @ld_debug@
+LD                = @ld@
+LDFLAGS           = @ldflags@ @ld_debug@
 
 
 
@@ -28,71 +28,71 @@
 all: pirc
 
 
-SOURCES = src/pirmain.c \
+SOURCES        = src/pirmain.c \
   src/pirparser.c \
   src/pirparser.h \
   src/pirlexer.c \
   src/pirlexer.h \
   src/pirout.c \
   src/pirout.h \
-  src/pastout.c \
-  src/pastout.h \
-  src/no_output.c \
-  src/no_output.h \
-  src/pirvtable.h 
+  src/pastout.c        \
+  src/pastout.h        \
+  src/pirvtable.c \
+  src/pirvtable.h
 
 
-pirc: pirmain$(O) pirparser$(O) pirlexer$(O) pirout$(O) pastout$(O) 
no_output$(O)
-       $(CC) -o pirc$(EXE) pirmain$(O) pirparser$(O) pirlexer$(O) pirout$(O) 
pastout$(O) \
-        no_output$(O)
+pirc: pirmain$(O) pirparser$(O)        pirlexer$(O) pirout$(O) pastout$(O)     
pirvtable$(O)
+       $(CC) -o pirc$(EXE)     pirmain$(O)     pirparser$(O) pirlexer$(O) 
pirout$(O) pastout$(O) pirvtable$(O)
 
 pirmain$(O): src/pirmain.c src/pirparser.h
-       $(CC) $(CFLAGS) -c src/pirmain.c
+       $(CC) $(CFLAGS) -c src/pirmain.c
 
 pirparser$(O): src/pirparser.c src/pirparser.h src/pirlexer.h
-       $(CC) $(CFLAGS) -c src/pirparser.c
-       
+       $(CC) $(CFLAGS) -c src/pirparser.c
+
 pirlexer$(O): src/pirlexer.c src/pirlexer.h
-       $(CC) $(CFLAGS) -c src/pirlexer.c
-       
-pirout$(O): src/pirout.c src/pirout.h
-       $(CC) $(CFLAGS) -c src/pirout.c
+       $(CC) $(CFLAGS) -c src/pirlexer.c
+
+pirout$(O):    src/pirout.c src/pirout.h
+       $(CC) $(CFLAGS) -c src/pirout.c
 
 pastout$(O): src/pastout.c src/pastout.h
-       $(CC) $(CFLAGS) -c src/pastout.c
+       $(CC) $(CFLAGS) -c src/pastout.c
+
+pirvtable$(O): src/pirvtable.c src/pirvtable.h
+       $(CC) $(CFLAGS) -c src/pirvtable.c
 
-no_output$(O): src/no_output.c src/no_output.h
-       $(CC) $(CFLAGS) -c src/no_output.c
 
-# This is a listing of all targets, that are meant to be called by users
+
+# This is a    listing of all targets, that are meant to be called     by users
 help:
        @echo ""
        @echo "Following targets are available for the user:"
        @echo ""
-       @echo "  all:               pirc"
-       @echo "                     This is the default."
+       @echo "  all:                           pirc"
+       @echo "                                         This is the     
default."
 #      @echo "Testing:"
-#      @echo "  test:              Run the test suite."
-#      @echo "  testclean:         Clean up test results."
+#      @echo "  test:                          Run     the     test suite."
+#      @echo "  testclean:                     Clean up test results."
 #      @echo ""
        @echo "Cleaning:"
-       @echo "  clean:             Basic cleaning up."
-       @echo "  realclean:         Removes also files generated by 
'Configure.pl'"
-       @echo "  distclean:         Removes also anything built, in theory"
+       @echo "  clean:                         Basic cleaning up."
+       @echo "  realclean:                     Removes also files generated by 
'Configure.pl'"
+       @echo "  distclean:                     Removes also anything built, in 
theory"
        @echo ""
        @echo "Misc:"
-       @echo "  help:              Print this help message."
+       @echo "  help:                          Print this help message."
        @echo ""
 
 
 
-clean: 
-       $(RM_RF) *$(O) 
-    
+clean:
+       $(RM_RF) *$(O)
+
 
 realclean: clean
        $(RM_RF) \
-    $(STICKY_FILES) \
-    pirc$(EXE)
+       $(STICKY_FILES) \
+       pirc$(EXE)
 
 distclean: realclean

Reply via email to