Skip to content

Commit

Permalink
[pirc] many updates
Browse files Browse the repository at this point in the history
+ update README.pod
+ many POD comments added
+ many updates in parser-back-end communication
+ handle .const directive 

git-svn-id: https://svn.parrot.org/parrot/trunk@30293 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
kjs committed Aug 18, 2008
1 parent 2dce388 commit 9200ac9
Show file tree
Hide file tree
Showing 14 changed files with 3,274 additions and 2,520 deletions.
340 changes: 252 additions & 88 deletions compilers/pirc/README.pod

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions compilers/pirc/doc/design.pod
Expand Up @@ -5,6 +5,12 @@ design.pod - description PIRC's design.
=head1 DESCRIPTION

This document describes the design and implementation of PIRC, a PIR Compiler.
This document describes the hand-written, recursive-descent implementation
which can be found in F<compilers/pirc/src>. This implementation is currently
not actively maintained, but kept here for potential future use.

For a new implementation of PIR, you might want to look at F<compilers/pirc/new>,
which is an implementation using Bison and Flex.

=head1 OVERVIEW

Expand Down
42 changes: 20 additions & 22 deletions compilers/pirc/new/main.c
Expand Up @@ -8,6 +8,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "pirparser.h"
#include "pircompiler.h"

Expand All @@ -30,23 +31,6 @@ extern int yyerror(yyscan_t yyscanner, lexer_state * const lexer, char const * c
=over 4
=item C<void
syntax_error(yyscan_t yyscanner, char *message)>
wrapper function for yyerror. This is useful, so that if yyerror's
signature changes, calls to syntax_error in the lexer do not need
to be updated.
*/

void
syntax_error(yyscan_t yyscanner, char const * const message)
{
yyerror(yyscanner, yyget_extra(yyscanner), message);
}

/*
=item C<static void
print_help(char const * const program_name)>
Expand Down Expand Up @@ -92,6 +76,16 @@ open_file(char const * const filename, char const * const mode) {
return fp;
}

/*
static void
print_data_sizes(void) {
printf("size of symbol: %u\n", sizeof(symbol));
printf("size of target: %u\n", sizeof(target));
printf("size of sub: %u\n", sizeof(subroutine));
printf("size of stat: %u\n", sizeof(statement));
}
*/

/*
=item C<int main(int argc, char *argv[])>
Expand Down Expand Up @@ -185,6 +179,8 @@ main(int argc, char *argv[])
if (lexer->parse_errors == 0) {
fprintf(stderr, "Parse successful!\n");
print_subs(lexer);
check_unused_symbols(lexer);
free_subs(lexer);
}
else
fprintf(stderr, "There were %d errors\n", lexer->parse_errors);
Expand All @@ -195,6 +191,8 @@ main(int argc, char *argv[])
yylex_destroy(yyscanner);
free(lexer);

/*print_data_sizes();*/

/* go home! */
return 0;
}
Expand All @@ -211,13 +209,13 @@ parser finds a syntax error.
*/
int
yyerror(yyscan_t yyscanner, lexer_state * const lexer, char const * const message)
{
yyerror(yyscan_t yyscanner, lexer_state * const lexer, char const * const message) {
char const * const text = yyget_text(yyscanner);
++lexer->parse_errors;

fprintf(stderr, "\nError in file '%s' (line %d)\n%s ",
lexer->filename, yyget_lineno(yyscanner), message);
fprintf(stderr, "\nError in file '%s' (line %d)\n%s\n", lexer->filename, yyget_lineno(yyscanner),
message);

++lexer->parse_errors;

/* print current token if it's not a newline ("\r\n" on windows) */
/* the following should be fixed; the point is not to print the token if
Expand Down
84 changes: 69 additions & 15 deletions compilers/pirc/new/pir.l
Expand Up @@ -55,16 +55,17 @@ easier to maintain, and preferable.
#define YY_EXTRA_TYPE struct lexer_state *

/* accessor methods for setting and getting the lexer_state */
extern YY_EXTRA_TYPE yyget_extra(yyscan_t scanner);
extern void yyset_extra(YY_EXTRA_TYPE lexer , yyscan_t scanner);
extern YY_EXTRA_TYPE yyget_extra(yyscan_t scanner);
extern void yyset_extra(YY_EXTRA_TYPE lexer, yyscan_t scanner);

/* accessor method to get yytext */
extern char *yyget_text(yyscan_t yyscanner);

/* declaration of yylex */
extern int yylex(YYSTYPE *yylval, yyscan_t yyscanner);

extern void syntax_error(yyscan_t yyscanner, char *message);
/* declaration of yyerror */
extern void yyerror(yyscan_t yyscanner, lexer_state * const lexer, char *message);



Expand Down Expand Up @@ -109,6 +110,8 @@ so define our own strdup. Function names beginning with "str"
are reserved (I think), so make it dupstr, as that is what it
does: duplicate a string.
=cut
*/
static char *
dupstr(char const * const source) {
Expand All @@ -125,6 +128,8 @@ dupstr(char const * const source) {
See dupstr, except that this version takes the number of characters to be
copied. Easy for copying a string except the quotes.
=cut
*/
static char *
dupstrn(char const * const source, size_t num_chars) {
Expand All @@ -142,19 +147,27 @@ dupstrn(char const * const source, size_t num_chars) {
constructor for a lexer. It's very important to initialize all fields.
=cut
*/
lexer_state *
new_lexer(char * const filename) {
lexer_state *lexer = (lexer_state *)malloc(sizeof (lexer_state));
assert(lexer != NULL);

/* clear all fields */
memset(lexer, 0, sizeof (lexer_state));

lexer->filename = filename;
/*
lexer->parse_errors = 0;
lexer->current_ns = NULL;
lexer->subs = NULL;

lexer->curtarget = NULL;
lexer->curarg = NULL;
lexer->globals = NULL;
lexer->constants = NULL;
*/

printdebug(stderr, "Constructing new lexer\n");

Expand Down Expand Up @@ -297,6 +310,13 @@ Q_STRING {SQ_STRING}|{DQ_STRING}
"unless" { return TK_UNLESS; }
"null" { return TK_NULL; }

"set" { return TK_PARROT_SET; }
"add" { return TK_PARROT_ADD; }
"sub" { return TK_PARROT_SUB; }
"mul" { return TK_PARROT_MUL; }
"div" { return TK_PARROT_DIV; }
"fdiv" { return TK_PARROT_FDIV; }

"int" { return TK_INT; }
"num" { return TK_NUM; }
"pmc" { return TK_PMC; }
Expand Down Expand Up @@ -343,6 +363,7 @@ Q_STRING {SQ_STRING}|{DQ_STRING}
":vtable" { return TK_FLAG_VTABLE; }
":multi" { return TK_FLAG_MULTI; }
":lexid" { return TK_FLAG_LEXID; }
":instanceof" { return TK_INSTANCEOF; }

":unique_reg" { return TK_FLAG_UNIQUE_REG; }
":optional" { return TK_FLAG_OPTIONAL; }
Expand All @@ -368,27 +389,41 @@ Q_STRING {SQ_STRING}|{DQ_STRING}
return TK_LABEL;
}


"set" { return PARROT_SET; }
"add" { return PARROT_ADD; }
"sub" { return PARROT_SUB; }
"mul" { return PARROT_MUL; }
"div" { return PARROT_DIV; }
"fdiv" { return PARROT_FDIV; }

{IDENT} { /* identifier; can be a global (sub or const), local or parrot op */
lexer_state *lexer = yyget_extra(yyscanner);
symbol *sym = find_symbol(lexer, yytext);

constant *con;

/* if the id was declared as a local, return the pointer to the symbol
* node. Note that .locals can "hide" opcodes.
*/
if (sym != NULL) {
yylval->sym = sym;
yylval->symb = sym;
return TK_SYMBOL;
}

/* maybe it was a declared .const; if that's the case, then that .const's
* value is returned as if the literal constant was parsed.
*/
con = find_constant(lexer, yytext);
if (con != NULL) {
switch (con->type) {
case INT_TYPE:
yylval->ival = con->val.ival;
return TK_INTC;
case NUM_TYPE:
yylval->dval = con->val.nval;
return TK_NUMC;
case STRING_TYPE:
yylval->sval = con->val.sval;
return TK_STRINGC;
case PMC_TYPE:
case UNKNOWN_TYPE:
default:
fprintf(stderr, "invalid constant type!\n");
}
}

/* at this point we need to duplicate the string */
yylval->sval = dupstr(yytext);

Expand All @@ -413,7 +448,7 @@ Q_STRING {SQ_STRING}|{DQ_STRING}


. { /* any character not covered in the rules above is an error. */
syntax_error(yyscanner, "Unexpected character");
yyerror(yyscanner, yyget_extra(yyscanner), "Unexpected character");
}


Expand All @@ -423,7 +458,18 @@ Q_STRING {SQ_STRING}|{DQ_STRING}

%%

/*
=head1 AUX. FUNCTIONS
=over 4
=item C<static int
is_parrot_op(char const * const spelling)>
=cut
*/
static int
is_parrot_op(char const * const spelling)
{
Expand Down Expand Up @@ -456,6 +502,14 @@ is_parrot_op(char const * const spelling)
return 0;
}

/*
=back
=cut
*/




Expand Down

0 comments on commit 9200ac9

Please sign in to comment.