%{
/*
 * cola.l
 *
 * $Id: /mirror/trunk/languages/cola/cola.l 21229 2007-09-12T19:24:53.985733Z paultcochrane  $
 *
 * Cola compiler for Parrot
 *
 * Copyright (C) 2002 Melvin Smith
 *
 * The lexer. Grammar for Flex.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cola.h"
#include "parser.h"

extern long line;
int yyerror(char *);
%}

%option outfile="lexer.c"

LETTER          [a-zA-Z_]
DIGIT           [0-9]
LETTERDIGIT     [a-zA-Z0-9_]
SIGN            [-+]
STRINGCONSTANT  \"[^"\n]*["\n]
CHARCONSTANT    \'[^'\n]*\'
RANKSPEC        \[[,]*\]

%%

[\n]            line++;
\/\/.*\n        line++;    /* COMMENT */

"__asm"         return ASM;
"bool"          return BOOL;
"break"         return BREAK;
"byte"          return BYTE;
"const"         return CONST;
"continue"      return CONTINUE;
"char"          return CHAR;
"class"         return CLASS;
"decimal"       return DECIMAL;
"double"        return DOUBLE;
"else"          return ELSE;
"false"         return FALSE;
"float"         return FLOAT;
"get"           return GET;
"goto"          return GOTO;
"for"           return FOR;
"if"            return IF;
"int"           return INT;
"long"          return LONG;
"namespace"     return NAMESPACE;
"new"           return NEW;
"null"          return NULLVAL;
"out"           return OUT;
"object"        return OBJECT;
"override"      return OVERRIDE;
"public"        return PUBLIC;
"private"       return PRIVATE;
"protected"     return PROTECTED;
"readonly"      return READONLY;
"ref"           return REF;
"return"        return RETURN;
"set"           return SET;
"sbyte"         return SBYTE;
"short"         return SHORT;
"static"        return STATIC;
"string"        return STRING;
"this"          return THIS;
"true"          return TRUE;
"uint"          return UINT;
"ulong"         return ULONG;
"ushort"        return USHORT;
"using"         return USING;
"virtual"       return VIRTUAL;
"void"          return VOID;
"while"         return WHILE;


{LETTER}{LETTERDIGIT}* {
        Symbol * s;
        s = new_identifier_symbol(yytext);
        s->line = line;
        yylval.sym = s;
        return IDENTIFIER;
    }

{SIGN}?{DIGIT}+"."{DIGIT}+ {
        Symbol * s = new_literal_symbol(yytext);
        s->type = t_float;
        s->typename = t_float->sym;
        yylval.sym = s;
        return LITERAL;
    }

{SIGN}?{DIGIT}+ {
        Symbol * s = new_literal_symbol(yytext);
        s->type = t_int32;
        s->typename = t_int32->sym;
        yylval.sym = s;
        return LITERAL;
    }

{STRINGCONSTANT} {
        Symbol * s = new_literal_symbol(yytext);
        s->type = t_string;
        s->typename = t_string->sym;
        yylval.sym = s;
        return LITERAL;
    }

{RANKSPEC}    {
        /*
         * This might bite me in the butt later, but its easier to offload
         * this to the lexer. [], [,], etc.
         */
        Symbol * s = new_literal_symbol(yytext);
        fprintf(stderr, "Rank spec /%s/\n", s->name);
        yylval.sym = s;
        return RANKSPEC;
    }

"++"            return INC;
"--"            return DEC;
"||"            return LOGICAL_OR;
"&&"            return LOGICAL_AND;
"=="            return LOGICAL_EQ;
"!="            return LOGICAL_NE;
"<<"            return LEFT_SHIFT;
">>"            return RIGHT_SHIFT;
"<="            return LOGICAL_LTE;
">="            return LOGICAL_GTE;
[\t\f\r ]+        ;
.               return yytext[0];
%%

#ifdef yywrap
#  undef yywrap
#endif

int yywrap() {
    /* Add code here to open next source file and start scanning
       yywrap returns 0 if scanning is to continue
    */
    return 1;
}


/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4:
 */
