/* * Programming Language SOOPY * (Simple Object Oriented Programming sYstem) * * Copyright (C) 2002 SUZUKI Jun * * URL: http://sourceforge.jp/projects/soopy/ * License: GPL(GNU General Public License) * * * $Id: parser.y,v 1.59 2004/03/27 05:59:44 randy Exp $ */ %{ #ifdef AQUA //#include "../../soopy.h" #include "soopy.h" #else #include "soopy.h" #endif extern int yylex(); extern SpValue program; static vector PublicVector; int yyerror(char* str) { throw SpException(str); } void pushPublicVector() { PublicVector.push_back(true); } void popPublicVector() { PublicVector.pop_back(); } void setPublic(bool p){ PublicVector.back() = p; } bool getPublic(){ return PublicVector.back(); } void checkAllSymbols(SpValue& list) { if(list.isSymbol() || list.isNil()){ return; } if(!list.isList()){ throw SpException("not symbol (list). fun{var:...}"); } SpValue v = list; while(!v.isNil()){ SpList* list = v.asList(); /* if(!(list->value().isSymbol())){ */ SpValue temp; temp = list->value(); if(!(temp.isSymbol())){ throw SpException("syntax error. local var is not symbol"); } v = list->nextList(); } } %} %token INT %token REAL %token CHAR %token STRING SYMBOL %token TokTRUE TokFALSE NIL %token FUN PROPERTY CONSTANT %token MATCH LOOP EXIT NEXT RETRY LET %token PRIVATE PUBLIC LARROW %token LB RB LP RP LC RC COMMA COLON SEMI DOT BAR %token EndOfStream %token ARRAY DATATYPE DOLL %right ASSIGN %left OR %left AND %right NOT %left EQ NE %left GT GE LT LE %left PLUS MINUS %left TIMES DIV MOD %right UMINUS %right WDOT WSLASH WCOLON AT /* AT = '@' */ %% program : { pushPublicVector(); } stmt SEMI { program = $2; /* SpValueResult(program); */ popPublicVector(); return 1; } | EndOfStream { return 0; } ; stmt : expr { $$ = $1; } | assign { $$ = $1; } | constant { NSPairAdaptor* adapt = dynamic_cast($1.getObject()); SpValue v0 = getCurrentNS(); SpNameSpace* ns = dynamic_cast(v0.getObject()); SpValue val = adapt->pair->second; ns->setValue(adapt->pair->first, val, ns); $$ = val; } | function { SpUsrFunc* f = dynamic_cast($1.getObject()); // SpValue place(new NSFunc(f->getName())); SpValue temp; temp = f->getName(); SpValue place(new NSFunc(temp)); SpValue v0 = getCurrentNS(); SpNameSpace* ns = dynamic_cast(v0.getObject()); ns->setValue(place, $1, ns); $$ = $1; } | datatype { SpDataType* dt = $1.asDataType(); SpValue v0 = getCurrentNS(); SpNameSpace* ns = v0.asNameSpace(); dt->mapping2ns($1, ns); $$ = $1; } ; expr : object { $$ = $1; } | sendMessage { $$ = $1; } | LP stmt RP { $$ = $2; } | quoted { $$ = $1; } | RETRY { $$.setNewObject(new SpRetry()); } | MINUS expr %prec UMINUS { ExprUMinus* exp = new ExprUMinus($2); $$.setNewObject(exp); } | expr PLUS expr { ExprPlus* exp = new ExprPlus($1, $3); $$.setNewObject(exp); } | expr MINUS expr { ExprMinus* exp = new ExprMinus($1, $3); $$.setNewObject(exp); } | expr TIMES expr { ExprTimes* exp = new ExprTimes($1, $3); $$.setNewObject(exp); } | expr DIV expr { ExprDiv* exp = new ExprDiv($1, $3); $$.setNewObject(exp); } | expr MOD expr { ExprMod* exp = new ExprMod($1, $3); $$.setNewObject(exp); } | NOT expr { ExprNOT* exp = new ExprNOT($2); $$.setNewObject(exp); } | expr OR expr { ExprOR* exp = new ExprOR($1, $3); $$.setNewObject(exp); } | expr AND expr { ExprAND* exp = new ExprAND($1, $3); $$.setNewObject(exp); } | expr EQ expr { ExprEQ* exp = new ExprEQ($1, $3); $$.setNewObject(exp); } | expr NE expr { ExprNE* exp = new ExprNE($1, $3); $$.setNewObject(exp); } | expr GT expr { ExprGT* exp = new ExprGT($1, $3); $$.setNewObject(exp); } | expr GE expr { ExprGE* exp = new ExprGE($1, $3); $$.setNewObject(exp); } | expr LT expr { ExprLT* exp = new ExprLT($1, $3); $$.setNewObject(exp); } | expr LE expr { ExprLE* exp = new ExprLE($1, $3); $$.setNewObject(exp); } | expr WCOLON expr { ExprWColon* exp = new ExprWColon($1, $3); $$.setNewObject(exp); } | expr AT expr { ExprAT* exp = new ExprAT($1, $3); $$.setNewObject(exp); } /* | IF LP expr RP match_assoc_body { SpIf* exp = new SpIf($3, $5); $$.setNewObject(exp); } */ | MATCH LP expr RP match_assoc_body { SpIf* exp = new SpIf($3, $5); $$.setNewObject(exp); } | loop { $$ = $1; } | exit { $$ = $1; } | next { $$ = $1; } ; object : INT { $$ = $1; } | NIL { $$ = NilObject; } | REAL { $$ = $1; } | CHAR { $$ = $1; } | TokTRUE { $$ = TrueObject; } | TokFALSE { $$ = FalseObject; } | STRING { $$ = $1; } | SYMBOL { $$ = $1; } | LP RP { $$ = NilObject; } | tuple { $$ = $1; } | list { $$ = $1; } | namespace { $$.setNewObject(new MakeNameSpace($1)); } | array { $$ = $1; } ; quoted : DOLL SYMBOL { $$.setNewObject(new SpQuote($2)); } ; /* * Tuple */ tuple : LP expr list_separator exprVector RP { SpValueVector vec; vec.push_back($2); SpTuple* ptr = dynamic_cast($4.getObject()); vec.insert(vec.end(), ptr->vec.begin(), ptr->vec.end()); $$.setNewObject(new SpTuple(vec)); } ; exprVector : expr { SpValueVector vec; vec.push_back($1); $$.setNewObject(new SpTuple(vec)); /* this tuple can't print */ } | exprVector list_separator expr { SpTuple* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; /* * List, Range */ list : LB RB { $$ = NilObject; } | LB expr_or_assign_list RB { $$ = $2; } | LB expr_or_assign_list list_separator RB { $$ = $2; } | LB expr WDOT expr RB { SpMakeRange* range = new SpMakeRange($2, $4); $$.setNewObject(range); } | LB expr WDOT expr WDOT expr RB { SpMakeRange* range = new SpMakeRange($2, $6, $4); $$.setNewObject(range); } | LB expr WDOT RB { SpMakeRange* range = new SpMakeRange($2, NilObject, true); $$.setNewObject(range); } | LB expr WDOT expr WDOT RB { SpMakeRange* range = new SpMakeRange($2, NilObject, $4, true); $$.setNewObject(range); } | LB expr BAR list_creator_list RB { $$.setNewObject(new SpListCompreCreator($2, $4, NilObject)); } | LB expr BAR list_creator_list list_separator expr_list RB { $$.setNewObject(new SpListCompreCreator($2, $4, $6)); } | LB expr WSLASH list_creator_list RB { $$.setNewObject(new SpListCompreDiagCreator($2, $4, NilObject)); } | LB expr WSLASH list_creator_list list_separator expr_list RB { $$.setNewObject(new SpListCompreCreator($2, $4, $6)); } ; list_creator_list : list_creator { SpValueVector vec; vec.push_back($1); $$.setNewObject(new SpTuple(vec)); /* this tuple can't print */ } | list_creator_list list_separator list_creator { SpTuple* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; list_creator : SYMBOL LARROW expr { SpListCreator* ptr = new SpListCreator($1, $3); $$.setNewObject(ptr); } ; expr_list : /* nothing */ { $$ = NilObject; } | exprs { $$ = $1; } ; exprs : expr { SpValueVector vec; vec.push_back($1); $$.setNewObject(new SpTuple(vec)); /* this tuple can't print */ } | exprVector list_separator expr { SpTuple* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; expr_or_assign : expr { $$ = $1; } | assign { $$ = $1; } ; expr_or_assign_list : expr_or_assign { SpCons* list = new SpCons($1); $$.setNewObject(list); } | expr_or_assign_list list_separator expr_or_assign { SpCons* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; list_separator : COMMA | SEMI ; /* * NameSpace */ namespace : LC { pushPublicVector(); } assocMap RC { NSMapAdaptor* map_adapt = dynamic_cast($3.getObject()); NSMap* map = map_adapt->map; SpNameSpace* ns = new SpNameSpace(*map, getCurrentNS()); $$.setNewObject(ns); popPublicVector(); } ; assocMap: /* nothing */ { NSMap* map = new NSMap; NSMapAdaptor* map_adapt = new NSMapAdaptor(map); $$.setNewObject(map_adapt); } | assocMap assoc SEMI { NSMapAdaptor* map_adapt = dynamic_cast($1.getObject()); NSMap* map = map_adapt->map; NSPairAdaptor* adapt = dynamic_cast($2.getObject()); NSPair* pair = adapt->pair; NSMap::iterator it = map->find(pair->first); if(it != map->end()){ map->erase(it); } (*map)[pair->first] = pair->second; $$ = $1; } | assocMap PRIVATE { setPublic(false); $$ = $1; } | assocMap PUBLIC { setPublic(true); $$ = $1; } ; assoc : pattern COLON assocValue { NSPair* pair = new NSPair; pair->first.setNewObject(new NSVar($1, getPublic())); pair->second = $3; NSPairAdaptor* adapt = new NSPairAdaptor(pair); $$.setNewObject(adapt); } | constant { $$ = $1; } | property { $$ = $1; } | function { NSPair* pair = new NSPair; SpUsrFunc* f = dynamic_cast($1.getObject()); // pair->first.setNewObject(new NSFunc(f->getName(), getPublic())); SpValue temp; temp = f->getName(); pair->first.setNewObject(new NSFunc(temp, getPublic())); pair->second = $1; NSPairAdaptor* adapt = new NSPairAdaptor(pair); $$.setNewObject(adapt); } | datatype { NSPair* pair = new NSPair; SpDataType* dt = $1.asDataType(); pair->first.setNewObject(new NSDataType(dt->symbol, getPublic())); pair->second = $1; NSPairAdaptor* adapt = new NSPairAdaptor(pair); $$.setNewObject(adapt); } ; assocValue : stmt { $$ = $1; } ; match_assoc_body : LC RC { $$ = NilObject; } | LC match_assoc_vector RC { $$ = $2; } ; match_assoc_vector : match_assoc SEMI { SpValueVector vec; vec.push_back($1); $$.setNewObject(new SpTuple(vec)); /* this tuple can't print */ } | match_assoc_vector match_assoc SEMI { SpTuple* ptr = dynamic_cast($1.getObject()); ptr->append($2); $$ = $1; } ; match_assoc : pattern COLON assocValue { NSPair* pair = new NSPair; pair->first = $1; pair->second = $3; NSPairAdaptor* adapt = new NSPairAdaptor(pair); $$.setNewObject(adapt); } ; pattern : SYMBOL { $$ = $1; } | INT { $$ = $1; } | CHAR { $$ = $1; } | STRING { $$ = $1; } | TokTRUE { $$ = TrueObject; } | TokFALSE { $$ = FalseObject; } | NIL { $$ = NilObject; } | LP RP { $$ = NilObject; } | list_pattern { $$ = $1; } | tuple_pattern { $$ = $1; } | pattern WCOLON pattern { SpPatternWColon* pat = new SpPatternWColon($1, $3); $$.setNewObject(pat); } | list_pattern AT list_pattern { SpPatternAt* pat = new SpPatternAt($1,$3); $$.setNewObject(pat); } | con_pattern { $$ = $1; } ; list_patterns : pattern { SpCons* list = new SpCons($1); $$.setNewObject(list); } | list_patterns list_separator pattern { SpCons* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; list_pattern : LB RB { $$ = NilObject; } | LB list_patterns RB { $$ = $2; } ; tuple_pattern : LP pattern list_separator tuple_patterns RP { SpValueVector vec; vec.push_back($2); SpTuple* ptr = dynamic_cast($4.getObject()); vec.insert(vec.end(), ptr->vec.begin(), ptr->vec.end()); $$.setNewObject(new SpTuple(vec)); } ; tuple_patterns : pattern { SpValueVector vec; vec.push_back($1); $$.setNewObject(new SpTuple(vec)); /* this tuple can't print */ } | tuple_patterns list_separator pattern { SpTuple* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; con_pattern : SYMBOL LP pattern RP { SpValueVector vec; vec.push_back($3); SpValue v(new SpTuple(vec)); SpPatternCon* con = new SpPatternCon($1, v); $$.setNewObject(con); } | SYMBOL tuple_pattern { SpPatternCon* con = new SpPatternCon($1, $2); $$.setNewObject(con); } ; type : SYMBOL { $$ = $1; } ; typ : /* nothing */ { $$ = NilObject; } | COLON type { $$ = $2; } ; constant: CONSTANT SYMBOL ASSIGN expr { NSPair* pair = new NSPair; SpValue v = $4.eval(); pair->first.setNewObject(new NSConst($2, getPublic(), v.getType())); pair->second = v; NSPairAdaptor* adapt = new NSPairAdaptor(pair); $$.setNewObject(adapt); } ; property: PROPERTY SYMBOL typ namespace { SpValue setter, getter; SpNameSpace* ns = dynamic_cast($4.getObject()); getter = ns->lookup(SymGet); setter = ns->lookup(SymSet); NSPair* pair = new NSPair; pair->first.setNewObject(new NSProperty($2, getter, setter, getPublic())); pair->second = NilObject; /* no use */ NSPairAdaptor* adapt = new NSPairAdaptor(pair); $$.setNewObject(adapt); } ; symbols : SYMBOL COMMA SYMBOL { SpValueVector vec; vec.push_back($1); vec.push_back($3); $$.setNewObject(new SpTuple(vec)); /* this tuple can't print */ } | symbols COMMA SYMBOL { SpTuple* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; assign : SYMBOL ASSIGN expr { $$.setNewObject(new SpAssign($1, $3)); } | LET SYMBOL ASSIGN expr { $$.setNewObject(new SpAssign($2, $4)); } | LET LP symbols RP ASSIGN expr { SpTuple* ptr = dynamic_cast($3.getObject()); $$.setNewObject(new SpAssignS(ptr->vec, $6)); } | LET LB symbols RB ASSIGN expr { SpTuple* ptr = dynamic_cast($3.getObject()); $$.setNewObject(new SpAssignList(ptr->vec, $6)); } | LET SYMBOL WCOLON SYMBOL ASSIGN expr { $$.setNewObject(new SpAssignHT($2, $4, $6)); } | sendMessage ASSIGN expr { $$.setNewObject(new SpAssignSM($1, $3)); } ; receiver: object { $$ = $1; } | LP stmt RP { $$ = $2; } ; message : object { $$ = $1; } | LP stmt RP { $$ = $2; } ; sendMessage : receiver message { $$.setNewObject(new SpSendMsg($1, $2)); } | sendMessage message { $$.setNewObject(new SpSendMsg($1, $2)); } ; arg : SYMBOL typ { $$.setNewObject(new SpArg($1, $2)); } ; arg_list: arg { SpValueVector vec; vec.push_back($1); $$.setNewObject(new SpTuple(vec)); /* this tuple can't print */ } | arg_list COMMA arg { SpTuple* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; args : /* nothing */ { $$ = NilObject; } | arg_list { $$ = $1; } ; argList : /* nothing */ { $$ = NilObject; } | LP args RP { $$ = $2; } ; function: FUN SYMBOL argList namespace { SpValue vars, require, body, ensure, rescue; SpNameSpace* ns = dynamic_cast($4.getObject()); vars = ns->lookup(SymVar); checkAllSymbols(vars); require = ns->lookup(SymRequire); body = ns->lookup(SymDo); ensure = ns->lookup(SymEnsure); rescue = ns->lookup(SymRescue); $$.setNewObject(new SpUsrFunc($2, $3, vars, require, body, ensure, rescue)); } ; loop : LOOP namespace { SpValue from, step, body, wcond, ucond, variant, invariant; SpNameSpace* ns = dynamic_cast($2.getObject()); from = ns->lookup(SymFrom); step = ns->lookup(SymStep); body = ns->lookup(SymDo); wcond = ns->lookup(SymWhile); ucond = ns->lookup(SymUntil); variant = ns->lookup(SymVariant); invariant = ns->lookup(SymInvariant); $$.setNewObject(new SpLoop(NilObject, from, step, body, wcond, ucond, variant, invariant)); } | LOOP SYMBOL namespace { SpValue from, step, body, wcond, ucond, variant, invariant; SpNameSpace* ns = dynamic_cast($3.getObject()); from = ns->lookup(SymFrom); step = ns->lookup(SymStep); body = ns->lookup(SymDo); wcond = ns->lookup(SymWhile); ucond = ns->lookup(SymUntil); variant = ns->lookup(SymVariant); invariant = ns->lookup(SymInvariant); $$.setNewObject(new SpLoop($2, from, step, body, wcond, ucond, variant, invariant)); } ; exit : EXIT { $$.setNewObject(new SpExit()); } | SYMBOL DOT EXIT { $$.setNewObject(new SpExit($1)); } | EXIT LP expr RP { $$.setNewObject(new SpExit(NilObject, $3)); } | SYMBOL DOT EXIT LP expr RP { $$.setNewObject(new SpExit($1, $5)); } ; next : NEXT { $$.setNewObject(new SpNext()); } | SYMBOL DOT NEXT { $$.setNewObject(new SpNext($1)); } ; array : ARRAY typ LP exprVector RP { $$.setNewObject(new MakeArray($2, $4)); } ; datatype: DATATYPE SYMBOL ASSIGN dtype_list { SpTuple* p = dynamic_cast($4.getObject()); if(p == NULL){ throw SpSystemError(__FILE__, __LINE__); } SpDataType* dt = new SpDataType($2, p->vec); $$.setNewObject(dt); /* set datatype to constructor */ SpValueVector::iterator it; it = p->begin(); for(; it != p->end(); it++){ SpConstructor* con = it->asConstructor(); con->setDataType(dt); } } | DATATYPE SYMBOL namespace ASSIGN dtype_list { SpTuple* p = $5.asTuple(); SpDataType* dt = new SpDataType($2, p->vec); $$.setNewObject(dt); /* set datatype to constructor */ SpValueVector::iterator it; it = p->begin(); for(; it != p->end(); it++){ SpConstructor* con = it->asConstructor(); con->setDataType(dt); if(con->ns.isNil()){ con->ns = $3; }else{ SpNameSpace* ns = con->ns.asNameSpace(); ns->parentNS = $3; } } } ; dtype_list : dtype { SpValueVector vec; vec.push_back($1); $$.setNewObject(new SpTuple(vec)); /* this tuple can't print */ } | dtype_list BAR dtype { SpTuple* ptr = dynamic_cast($1.getObject()); ptr->append($3); $$ = $1; } ; dtype : SYMBOL argList { $$.setNewObject(new SpConstructor($1, $2, NilObject)); } | SYMBOL argList namespace { $$.setNewObject(new SpConstructor($1, $2, $3)); } ;