Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

%{
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#define Extern extern
#include "acid.h"
%}

%union
{
        Node    *node;
        Lsym    *sym;
        uvlong  ival;
        float   fval;
        String  *string;
}

%type <node> expr monexpr term stmnt name args zexpr slist
%type <node> member members mname castexpr idlist
%type <sym> zname

%left   ';'
%right  '='
%left   Tfmt
%left   Toror
%left   Tandand
%left   '|'
%left   '^'
%left   '&'
%left   Teq Tneq
%left   '<' '>' Tleq Tgeq
%left   Tlsh Trsh
%left   '+' '-'
%left   '*' '/' '%'
%right  Tdec Tinc Tindir '.' '[' '('

%token <sym>    Tid
%token <ival>   Tconst Tfmt
%token <fval>   Tfconst
%token <string> Tstring
%token Tif Tdo Tthen Telse Twhile Tloop Thead Ttail Tappend Tfn Tret Tlocal
%token Tcomplex Twhat Tdelete Teval Tbuiltin

%%

prog            : 
                | prog bigstmnt
                ;

bigstmnt        : stmnt
                {
                        /* make stmnt a root so it isn't collected! */
                        mkvar("_thiscmd")->proc = $1;
                        execute($1);
                        mkvar("_thiscmd")->proc = nil;
                        gc();
                        if(interactive)
                                Bprint(bout, "acid: ");
                }
                | Tfn Tid '(' args ')' zsemi '{' slist '}'
                {
                        $2->proc = an(OLIST, $4, $8);
                }
                | Tfn Tid
                {
                        $2->proc = nil;
                }
                | Tcomplex name '{' members '}' ';'
                {
                        defcomplex($2, $4);
                }
                ;

zsemi           :
                | ';' zsemi

members         : member
                | members member
                {
                        $$ = an(OLIST, $1, $2);
                }
                ;

mname           : Tid
                {
                        $$ = an(ONAME, ZN, ZN);
                        $$->sym = $1;
                }
                ;

member          : Tconst Tconst mname ';'
                {
                        $3->ival = $2;
                        $3->fmt = $1;
                        $$ = $3;
                }
                | Tconst mname Tconst mname ';'
                {
                        $4->ival = $3;
                        $4->fmt = $1;
                        $4->right = $2;
                        $$ = $4;
                }
                | mname Tconst mname ';'
                {
                        $3->ival = $2;
                        $3->left = $1;
                        $$ = $3;
                }
                | '{' members '}' ';'
                {
                        $$ = an(OCTRUCT, $2, ZN);
                }
                ;

zname           : 
                { $$ = 0; }
                | Tid
                ;

slist           : stmnt
                | slist stmnt
                {
                        $$ = an(OLIST, $1, $2);
                }
                ;

stmnt           : zexpr ';'
                | '{' slist '}'
                {
                        $$ = $2;
                }
                | Tif expr Tthen stmnt
                {
                        $$ = an(OIF, $2, $4);
                }
                | Tif expr Tthen stmnt Telse stmnt
                {
                        $$ = an(OIF, $2, an(OELSE, $4, $6));
                }
                | Tloop expr ',' expr Tdo stmnt
                {
                        $$ = an(ODO, an(OLIST, $2, $4), $6);
                }
                | Twhile expr Tdo stmnt
                {
                        $$ = an(OWHILE, $2, $4);
                }
                | Tret expr ';'
                {
                        $$ = an(ORET, $2, ZN);
                }
                | Tlocal idlist
                {
                        $$ = an(OLOCAL, $2, ZN);
                }
                | Tcomplex Tid name ';'
                {
                        $$ = an(OCOMPLEX, $3, ZN);
                        $$->sym = $2;
                }
                ;

idlist          : Tid
                {
                        $$ = an(ONAME, ZN, ZN);
                        $$->sym = $1;
                }
                | idlist ',' Tid
                {
                        $$ = an(ONAME, $1, ZN);
                        $$->sym = $3;
                }
                ;

zexpr           :
                { $$ = 0; }
                | expr
                ;

expr            : castexpr
                | expr '*' expr
                {
                        $$ = an(OMUL, $1, $3); 
                }
                | expr '/' expr
                {
                        $$ = an(ODIV, $1, $3);
                }
                | expr '%' expr
                {
                        $$ = an(OMOD, $1, $3);
                }
                | expr '+' expr
                {
                        $$ = an(OADD, $1, $3);
                }
                | expr '-' expr
                {
                        $$ = an(OSUB, $1, $3);
                }
                | expr Trsh expr
                {
                        $$ = an(ORSH, $1, $3);
                }
                | expr Tlsh expr
                {
                        $$ = an(OLSH, $1, $3);
                }
                | expr '<' expr
                {
                        $$ = an(OLT, $1, $3);
                }
                | expr '>' expr
                {
                        $$ = an(OGT, $1, $3);
                }
                | expr Tleq expr
                {
                        $$ = an(OLEQ, $1, $3);
                }
                | expr Tgeq expr
                {
                        $$ = an(OGEQ, $1, $3);
                }
                | expr Teq expr
                {
                        $$ = an(OEQ, $1, $3);
                }
                | expr Tneq expr
                {
                        $$ = an(ONEQ, $1, $3);
                }
                | expr '&' expr
                {
                        $$ = an(OLAND, $1, $3);
                }
                | expr '^' expr
                {
                        $$ = an(OXOR, $1, $3);
                }
                | expr '|' expr
                {
                        $$ = an(OLOR, $1, $3);
                }
                | expr Tandand expr
                {
                        $$ = an(OCAND, $1, $3);
                }
                | expr Toror expr
                {
                        $$ = an(OCOR, $1, $3);
                }
                | expr '=' expr
                {
                        $$ = an(OASGN, $1, $3);
                }
                | expr Tfmt
                {
                        $$ = an(OFMT, $1, con($2));
                }
                ;

castexpr        : monexpr
                | '(' Tid ')' monexpr
                {
                        $$ = an(OCAST, $4, ZN);
                        $$->sym = $2;
                }
                ;

monexpr         : term
                | '*' monexpr 
                {
                        $$ = an(OINDM, $2, ZN);
                }
                | '@' monexpr 
                {
                        $$ = an(OINDC, $2, ZN);
                }
                | '+' monexpr
                {
                        $$ = an(OADD, $2, ZN);
                }
                | '-' monexpr
                {
                        $$ = con(0);
                        $$ = an(OSUB, $$, $2);
                }
                | Tdec monexpr
                {
                        $$ = an(OEDEC, $2, ZN);
                }
                | Tinc monexpr
                {
                        $$ = an(OEINC, $2, ZN);
                }
                | Thead monexpr
                {
                        $$ = an(OHEAD, $2, ZN);
                }
                | Ttail monexpr
                {
                        $$ = an(OTAIL, $2, ZN);
                }
                | Tappend monexpr ',' monexpr
                {
                        $$ = an(OAPPEND, $2, $4);
                }
                | Tdelete monexpr ',' monexpr
                {
                        $$ = an(ODELETE, $2, $4);
                }
                | '!' monexpr
                {
                        $$ = an(ONOT, $2, ZN);
                }
                | '~' monexpr
                {
                        $$ = an(OXOR, $2, con(-1));
                }
                | Teval monexpr
                {
                        $$ = an(OEVAL, $2, ZN); 
                }
                ;

term            : '(' expr ')'
                {
                        $$ = $2;
                }
                | '{' args '}'
                {
                        $$ = an(OCTRUCT, $2, ZN);
                }
                | term '[' expr ']'
                {
                        $$ = an(OINDEX, $1, $3);
                }
                | term Tdec
                {
                        $$ = an(OPDEC, $1, ZN);
                }
                | term '.' Tid
                {
                        $$ = an(ODOT, $1, ZN);
                        $$->sym = $3;
                }
                | term Tindir Tid
                {
                        $$ = an(ODOT, an(OINDM, $1, ZN), ZN);
                        $$->sym = $3;
                }
                | term Tinc
                {
                        $$ = an(OPINC, $1, ZN);
                }
                | name '(' args ')'
                {
                        $$ = an(OCALL, $1, $3);
                }
                | Tbuiltin name '(' args ')'
                {
                        $$ = an(OCALL, $2, $4);
                        $$->builtin = 1;
                }
                | name
                | Tconst
                {
                        $$ = con($1);
                }
                | Tfconst
                {
                        $$ = an(OCONST, ZN, ZN);
                        $$->type = TFLOAT;
                        $$->fmt = 'f';
                        $$->fval = $1;
                }
                | Tstring
                {
                        $$ = an(OCONST, ZN, ZN);
                        $$->type = TSTRING;
                        $$->string = $1;
                        $$->fmt = 's';
                }
                | Twhat zname
                {
                        $$ = an(OWHAT, ZN, ZN);
                        $$->sym = $2;
                }
                ;

name            : Tid
                {
                        $$ = an(ONAME, ZN, ZN);
                        $$->sym = $1;
                }
                | Tid ':' name
                {
                        $$ = an(OFRAME, $3, ZN);
                        $$->sym = $1;
                }
                ;

args            : zexpr
                | args ','  zexpr
                {
                        $$ = an(OLIST, $1, $3);
                }
                ;