2008-06-04 15:37:38 -06:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
/*
|
|
|
|
* Go language grammar.
|
|
|
|
*
|
|
|
|
* The grammar has 6 reduce/reduce conflicts, caused by
|
|
|
|
* input that can be parsed as either a type or an expression
|
|
|
|
* depending on context, like the t in t(1). The expressions
|
|
|
|
* have the more general syntax, so the grammar arranges
|
|
|
|
* that such input gets parsed as expressions and then is
|
|
|
|
* fixed up as a type later. In return for this extra work,
|
|
|
|
* the lexer need not distinguish type names from variable names.
|
|
|
|
*
|
|
|
|
* The Go semicolon rules are:
|
|
|
|
*
|
|
|
|
* 1. all statements and declarations are terminated by semicolons
|
|
|
|
* 2. semicolons can be omitted at top level.
|
|
|
|
* 3. semicolons can be omitted before and after the closing ) or }
|
|
|
|
* on a list of statements or declarations.
|
|
|
|
*
|
2009-06-06 20:27:48 -06:00
|
|
|
* This is accomplished by calling yyoptsemi() to mark the places
|
|
|
|
* where semicolons are optional. That tells the lexer that if a
|
|
|
|
* semicolon isn't the next token, it should insert one for us.
|
2009-06-06 13:46:38 -06:00
|
|
|
*/
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
%{
|
|
|
|
#include "go.h"
|
|
|
|
%}
|
|
|
|
%union {
|
|
|
|
Node* node;
|
2009-07-17 02:00:44 -06:00
|
|
|
NodeList* list;
|
2008-06-04 15:37:38 -06:00
|
|
|
Type* type;
|
|
|
|
Sym* sym;
|
|
|
|
struct Val val;
|
|
|
|
int lint;
|
|
|
|
}
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
// |sed 's/.* //' |9 fmt -l1 |sort |9 fmt -l50 | sed 's/^/%xxx /'
|
|
|
|
|
|
|
|
%token <val> LLITERAL
|
|
|
|
%token <lint> LASOP
|
|
|
|
%token <sym> LBREAK LCASE LCHAN LCOLAS LCONST LCONTINUE LDDD
|
|
|
|
%token <sym> LDEFAULT LDEFER LELSE LFALL LFOR LFUNC LGO LGOTO
|
|
|
|
%token <sym> LIF LIMPORT LINTERFACE LMAKE LMAP LNAME LNEW
|
|
|
|
%token <sym> LPACKAGE LRANGE LRETURN LSELECT LSTRUCT LSWITCH
|
|
|
|
%token <sym> LTYPE LVAR
|
|
|
|
|
|
|
|
%token LANDAND LANDNOT LBODY LCOMM LDEC LEQ LGE LGT
|
|
|
|
%token LIGNORE LINC LLE LLSH LLT LNE LOROR LRSH
|
2009-06-06 20:27:48 -06:00
|
|
|
%token LSEMIBRACE
|
2009-06-06 13:46:38 -06:00
|
|
|
|
|
|
|
%type <lint> lbrace
|
|
|
|
%type <sym> sym packname
|
|
|
|
%type <val> oliteral
|
|
|
|
|
2009-07-14 00:38:39 -06:00
|
|
|
%type <node> stmt ntype
|
2009-07-17 02:00:44 -06:00
|
|
|
%type <node> arg_type
|
|
|
|
%type <node> case caseblock
|
|
|
|
%type <node> compound_stmt dotname embed expr
|
|
|
|
%type <node> expr_or_type
|
|
|
|
%type <node> fndcl fnliteral
|
2009-06-06 13:46:38 -06:00
|
|
|
%type <node> for_body for_header for_stmt if_header if_stmt
|
2009-07-17 02:00:44 -06:00
|
|
|
%type <node> keyval labelname name
|
|
|
|
%type <node> name_or_type
|
|
|
|
%type <node> new_name oexpr
|
|
|
|
%type <node> onew_name
|
|
|
|
%type <node> osimple_stmt pexpr
|
2009-06-06 20:27:48 -06:00
|
|
|
%type <node> pseudocall range_stmt select_stmt
|
2009-07-17 02:00:44 -06:00
|
|
|
%type <node> simple_stmt
|
|
|
|
%type <node> switch_stmt uexpr
|
|
|
|
%type <node> xfndcl
|
|
|
|
|
|
|
|
%type <list> xdcl fnbody common_dcl fnres switch_body loop_body
|
|
|
|
%type <list> name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list
|
|
|
|
%type <list> oexpr_list oexpr_or_type_list caseblock_list stmt_list oarg_type_list arg_type_list
|
|
|
|
%type <list> interfacedcl_list interfacedcl vardcl vardcl_list structdcl structdcl_list
|
2009-06-06 13:46:38 -06:00
|
|
|
|
2009-07-14 00:38:39 -06:00
|
|
|
%type <type> type
|
|
|
|
%type <node> convtype dotdotdot
|
|
|
|
%type <node> indcl interfacetype structtype
|
|
|
|
%type <type> new_type typedclname fnlitdcl fntype
|
|
|
|
%type <node> chantype non_chan_type othertype non_fn_type
|
2009-06-06 13:46:38 -06:00
|
|
|
|
|
|
|
%type <sym> hidden_importsym hidden_pkg_importsym
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
%type <node> hidden_constant hidden_dcl hidden_interfacedcl hidden_structdcl
|
|
|
|
|
|
|
|
%type <list> hidden_funres
|
|
|
|
%type <list> ohidden_funres
|
|
|
|
%type <list> hidden_funarg_list ohidden_funarg_list
|
|
|
|
%type <list> hidden_interfacedcl_list ohidden_interfacedcl_list
|
|
|
|
%type <list> hidden_structdcl_list ohidden_structdcl_list
|
2009-06-06 13:46:38 -06:00
|
|
|
|
|
|
|
%type <type> hidden_type hidden_type1 hidden_type2
|
|
|
|
|
|
|
|
%left LOROR
|
|
|
|
%left LANDAND
|
|
|
|
%left LCOMM
|
|
|
|
%left LEQ LNE LLE LGE LLT LGT
|
|
|
|
%left '+' '-' '|' '^'
|
|
|
|
%left '*' '/' '%' '&' LLSH LRSH LANDNOT
|
2008-10-03 17:15:55 -06:00
|
|
|
|
2009-03-03 09:41:02 -07:00
|
|
|
/*
|
2009-06-06 13:46:38 -06:00
|
|
|
* manual override of shift/reduce conflicts.
|
|
|
|
* the general form is that we assign a precedence
|
|
|
|
* to the token being shifted and then introduce
|
|
|
|
* NotToken with lower precedence or PreferToToken with higher
|
|
|
|
* and annotate the reducing rule accordingly.
|
2009-03-03 09:41:02 -07:00
|
|
|
*/
|
2009-06-06 13:46:38 -06:00
|
|
|
%left NotPackage
|
|
|
|
%left LPACKAGE
|
2009-03-03 09:41:02 -07:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
%left NotParen
|
|
|
|
%left '('
|
2009-03-05 16:57:03 -07:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
%left ')'
|
|
|
|
%left PreferToRightParen
|
2009-03-05 16:57:03 -07:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
%left NotDot
|
|
|
|
%left '.'
|
|
|
|
|
|
|
|
%left NotBrace
|
|
|
|
%left '{'
|
2009-03-03 09:41:02 -07:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
%%
|
|
|
|
file:
|
2009-05-08 16:40:31 -06:00
|
|
|
loadsys
|
|
|
|
package
|
|
|
|
imports
|
2009-07-17 02:00:44 -06:00
|
|
|
xdcl_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
if(debug['f'])
|
|
|
|
frame(1);
|
2008-07-19 14:38:29 -06:00
|
|
|
fninit($4);
|
2009-06-23 16:30:59 -06:00
|
|
|
if(nsyntaxerrors == 0)
|
|
|
|
testdclstack();
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
package:
|
2009-03-05 16:57:03 -07:00
|
|
|
%prec NotPackage
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
yyerror("package statement must be first");
|
|
|
|
mkpackage("main");
|
|
|
|
}
|
|
|
|
| LPACKAGE sym
|
|
|
|
{
|
|
|
|
mkpackage($2->name);
|
2009-05-08 16:40:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* this loads the definitions for the sys functions,
|
|
|
|
* so that the compiler can generate calls to them,
|
|
|
|
* but does not make the name "sys" visible as a package.
|
|
|
|
*/
|
|
|
|
loadsys:
|
|
|
|
{
|
2008-12-08 20:46:39 -07:00
|
|
|
cannedimports("sys.6", sysimport);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-05-08 16:40:31 -06:00
|
|
|
import_package
|
|
|
|
import_there
|
|
|
|
{
|
|
|
|
pkgimportname = S;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
imports:
|
|
|
|
| imports import
|
|
|
|
|
|
|
|
import:
|
|
|
|
LIMPORT import_stmt
|
2009-07-17 02:00:44 -06:00
|
|
|
| LIMPORT '(' import_stmt_list osemi ')'
|
2008-10-08 16:33:09 -06:00
|
|
|
| LIMPORT '(' ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
import_stmt:
|
2009-05-08 16:40:31 -06:00
|
|
|
import_here import_package import_there import_done
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
import_stmt_list:
|
|
|
|
import_stmt
|
|
|
|
| import_stmt_list ';' import_stmt
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
import_here:
|
|
|
|
LLITERAL
|
|
|
|
{
|
|
|
|
// import with original name
|
2009-05-08 16:40:31 -06:00
|
|
|
pkgimportname = S;
|
2008-06-04 15:37:38 -06:00
|
|
|
pkgmyname = S;
|
|
|
|
importfile(&$1);
|
|
|
|
}
|
|
|
|
| sym LLITERAL
|
|
|
|
{
|
|
|
|
// import with given name
|
2009-05-08 16:40:31 -06:00
|
|
|
pkgimportname = S;
|
2008-06-04 15:37:38 -06:00
|
|
|
pkgmyname = $1;
|
|
|
|
importfile(&$2);
|
|
|
|
}
|
|
|
|
| '.' LLITERAL
|
|
|
|
{
|
2009-05-08 16:40:31 -06:00
|
|
|
// import into my name space
|
|
|
|
pkgmyname = lookup(".");
|
2008-06-04 15:37:38 -06:00
|
|
|
importfile(&$2);
|
|
|
|
}
|
|
|
|
|
2008-06-12 22:48:56 -06:00
|
|
|
import_package:
|
|
|
|
LPACKAGE sym
|
|
|
|
{
|
|
|
|
pkgimportname = $2;
|
2009-04-02 22:46:19 -06:00
|
|
|
if(strcmp($2->name, "main") == 0)
|
|
|
|
yyerror("cannot import package main");
|
2008-06-12 22:48:56 -06:00
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
import_there:
|
2009-07-17 02:00:44 -06:00
|
|
|
{
|
|
|
|
defercheckwidth();
|
|
|
|
}
|
2008-10-06 17:44:17 -06:00
|
|
|
hidden_import_list '$' '$'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
resumecheckwidth();
|
2008-09-24 15:12:21 -06:00
|
|
|
checkimports();
|
2008-06-04 15:37:38 -06:00
|
|
|
unimportfile();
|
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| LIMPORT '$' '$'
|
2008-09-24 15:12:21 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
defercheckwidth();
|
|
|
|
}
|
|
|
|
hidden_import_list '$' '$'
|
|
|
|
{
|
|
|
|
resumecheckwidth();
|
2008-09-24 15:12:21 -06:00
|
|
|
checkimports();
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-05-08 16:40:31 -06:00
|
|
|
import_done:
|
|
|
|
{
|
|
|
|
Sym *import, *my;
|
|
|
|
|
|
|
|
import = pkgimportname;
|
|
|
|
my = pkgmyname;
|
|
|
|
pkgmyname = S;
|
|
|
|
pkgimportname = S;
|
|
|
|
|
|
|
|
if(import == S)
|
|
|
|
break;
|
|
|
|
if(my == S)
|
|
|
|
my = import;
|
|
|
|
if(my->name[0] == '.') {
|
|
|
|
importdot(import);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// In order to allow multifile packages to use type names
|
|
|
|
// that are the same as the package name (i.e. go/parser
|
|
|
|
// is package parser and has a type called parser), we have
|
|
|
|
// to not bother trying to declare the package if it is our package.
|
|
|
|
// TODO(rsc): Is there a better way to tell if the package is ours?
|
|
|
|
if(my == import && strcmp(import->name, package) == 0)
|
|
|
|
break;
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
if(my->def != N) {
|
2009-05-08 16:40:31 -06:00
|
|
|
// TODO(rsc): this line is only needed because of the
|
|
|
|
// package net
|
|
|
|
// import "net"
|
|
|
|
// convention; if we get rid of it, the check can go away
|
|
|
|
// and we can just always print the error
|
2009-06-06 13:46:38 -06:00
|
|
|
if(my->def->op != OPACK || strcmp(my->name, import->name) != 0)
|
2009-05-08 16:40:31 -06:00
|
|
|
yyerror("redeclaration of %S by import", my);
|
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
my->def = nod(OPACK, N, N);
|
|
|
|
my->def->sym = import;
|
2009-05-08 16:40:31 -06:00
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
/*
|
|
|
|
* declarations
|
|
|
|
*/
|
|
|
|
xdcl:
|
2008-10-13 21:14:09 -06:00
|
|
|
{ stksize = initstksize; } common_dcl
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
initstksize = stksize;
|
|
|
|
}
|
2008-08-04 14:18:59 -06:00
|
|
|
| xfndcl
|
2008-08-03 19:47:02 -06:00
|
|
|
{
|
2009-01-15 17:43:51 -07:00
|
|
|
if($1 != N && $1->nname != N && $1->type->thistuple == 0)
|
|
|
|
autoexport($1->nname->sym);
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-08-03 19:47:02 -06:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| ';'
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-07-05 13:49:25 -06:00
|
|
|
| error xdcl
|
2008-07-03 19:05:20 -06:00
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
$$ = $2;
|
2008-07-03 19:05:20 -06:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
common_dcl:
|
2009-06-06 20:27:48 -06:00
|
|
|
LVAR vardcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = $2;
|
2009-06-06 20:27:48 -06:00
|
|
|
if(yylast == LSEMIBRACE)
|
|
|
|
yyoptsemi(0);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| LVAR '(' vardcl_list osemi ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = $3;
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-08 16:33:09 -06:00
|
|
|
| LVAR '(' ')'
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
|
|
|
}
|
|
|
|
| LCONST constdcl
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2009-06-06 20:27:48 -06:00
|
|
|
iota = 0;
|
2009-07-17 02:00:44 -06:00
|
|
|
lastconst = nil;
|
2008-10-08 16:33:09 -06:00
|
|
|
}
|
2008-09-04 13:21:10 -06:00
|
|
|
| LCONST '(' constdcl osemi ')'
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-09-04 13:21:10 -06:00
|
|
|
iota = 0;
|
2009-07-17 02:00:44 -06:00
|
|
|
lastconst = nil;
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-09-04 13:21:10 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| LCONST '(' constdcl ';' constdcl_list osemi ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-06-04 15:37:38 -06:00
|
|
|
iota = 0;
|
2009-07-17 02:00:44 -06:00
|
|
|
lastconst = nil;
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-08 16:33:09 -06:00
|
|
|
| LCONST '(' ')'
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-10-08 16:33:09 -06:00
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| LTYPE typedcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2009-06-06 20:27:48 -06:00
|
|
|
if(yylast == LSEMIBRACE)
|
|
|
|
yyoptsemi(0);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| LTYPE '(' typedcl_list osemi ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-08 16:33:09 -06:00
|
|
|
| LTYPE '(' ')'
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-10-08 16:33:09 -06:00
|
|
|
}
|
2008-06-21 16:11:29 -06:00
|
|
|
|
2009-06-06 20:27:48 -06:00
|
|
|
varoptsemi:
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
2009-06-29 18:46:22 -06:00
|
|
|
if(yylast == LSEMIBRACE)
|
|
|
|
yyoptsemi('=');
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
vardcl:
|
2009-06-06 20:27:48 -06:00
|
|
|
name_list type varoptsemi
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = variter($1, $2, nil);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| name_list type varoptsemi '=' expr_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 20:27:48 -06:00
|
|
|
$$ = variter($1, $2, $5);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| name_list '=' expr_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-12-04 16:33:40 -07:00
|
|
|
$$ = variter($1, T, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
constdcl:
|
2009-06-06 13:46:38 -06:00
|
|
|
name_list type '=' expr_list
|
2008-07-03 17:41:32 -06:00
|
|
|
{
|
2008-12-04 16:33:40 -07:00
|
|
|
constiter($1, $2, $4);
|
2008-07-03 17:41:32 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| name_list '=' expr_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-12-04 16:33:40 -07:00
|
|
|
constiter($1, T, $3);
|
2008-07-03 17:41:32 -06:00
|
|
|
}
|
|
|
|
|
2008-09-04 13:21:10 -06:00
|
|
|
constdcl1:
|
|
|
|
constdcl
|
2009-06-06 13:46:38 -06:00
|
|
|
| name_list type
|
2008-07-03 17:41:32 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
constiter($1, $2, nil);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| name_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
constiter($1, T, nil);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2008-10-06 17:44:17 -06:00
|
|
|
typedclname:
|
|
|
|
new_type
|
|
|
|
{
|
|
|
|
$$ = dodcltype($1);
|
|
|
|
defercheckwidth();
|
|
|
|
}
|
|
|
|
|
2008-10-07 13:36:30 -06:00
|
|
|
typedcl:
|
2009-06-06 20:27:48 -06:00
|
|
|
typedclname type
|
2008-10-06 17:44:17 -06:00
|
|
|
{
|
|
|
|
updatetype($1, $2);
|
|
|
|
resumecheckwidth();
|
|
|
|
}
|
|
|
|
| typedclname LSTRUCT
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
2008-10-06 17:44:17 -06:00
|
|
|
updatetype($1, typ(TFORWSTRUCT));
|
|
|
|
resumecheckwidth();
|
2008-06-21 16:11:29 -06:00
|
|
|
}
|
2008-10-06 17:44:17 -06:00
|
|
|
| typedclname LINTERFACE
|
|
|
|
{
|
|
|
|
updatetype($1, typ(TFORWINTER));
|
|
|
|
resumecheckwidth();
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
simple_stmt:
|
|
|
|
expr
|
|
|
|
{
|
|
|
|
$$ = $1;
|
|
|
|
}
|
|
|
|
| expr LASOP expr
|
|
|
|
{
|
|
|
|
$$ = nod(OASOP, $1, $3);
|
2008-08-08 18:13:31 -06:00
|
|
|
$$->etype = $2; // rathole to pass opcode
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| expr_list '=' expr_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
if($1->next == nil && $3->next == nil) {
|
|
|
|
// simple
|
|
|
|
$$ = nod(OAS, $1->n, $3->n);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// multiple
|
|
|
|
$$ = nod(OAS2, N, N);
|
|
|
|
$$->list = $1;
|
|
|
|
$$->rlist = $3;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| expr_list LCOLAS expr_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
if($3->n->op == OTYPESW) {
|
|
|
|
if($3->next != nil)
|
|
|
|
yyerror("expr.(type) must be alone in list");
|
|
|
|
else if($1->next != nil)
|
|
|
|
yyerror("argument count mismatch: %d = %d", count($1), 1);
|
|
|
|
$$ = nod(OTYPESW, $1->n, $3->n->left);
|
2009-03-06 18:50:43 -07:00
|
|
|
break;
|
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = colas($1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-07 13:36:30 -06:00
|
|
|
| expr LINC
|
2008-06-17 23:33:32 -06:00
|
|
|
{
|
2009-03-12 20:04:38 -06:00
|
|
|
$$ = nod(OASOP, $1, nodintconst(1));
|
2008-06-17 23:33:32 -06:00
|
|
|
$$->etype = OADD;
|
|
|
|
}
|
|
|
|
| expr LDEC
|
|
|
|
{
|
2009-03-12 20:04:38 -06:00
|
|
|
$$ = nod(OASOP, $1, nodintconst(1));
|
2008-06-17 23:33:32 -06:00
|
|
|
$$->etype = OSUB;
|
|
|
|
}
|
|
|
|
|
2009-05-30 22:18:15 -06:00
|
|
|
case:
|
|
|
|
LCASE expr_list ':'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
int e;
|
|
|
|
Node *n;
|
2009-07-10 17:29:26 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
// will be converted to OCASE
|
|
|
|
// right will point to next case
|
|
|
|
// done in casebody()
|
|
|
|
poptodcl();
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OXCASE, N, N);
|
2009-06-06 13:46:38 -06:00
|
|
|
if(typeswvar != N && typeswvar->right != N) {
|
2009-07-17 02:00:44 -06:00
|
|
|
// type switch
|
|
|
|
n = $2->n;
|
|
|
|
if($2->next != nil)
|
|
|
|
yyerror("type switch case cannot be list");
|
|
|
|
if(n->op == OLITERAL && n->val.ctype == CTNIL) {
|
|
|
|
// case nil
|
|
|
|
$$->list = list1(nod(OTYPESW, N, N));
|
2009-06-06 13:46:38 -06:00
|
|
|
break;
|
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
|
|
|
|
// TODO: move
|
2009-07-14 00:38:39 -06:00
|
|
|
e = nerrors;
|
2009-07-17 02:00:44 -06:00
|
|
|
walkexpr(n, Etype | Erv, &$$->ninit);
|
|
|
|
if(n->op == OTYPE) {
|
|
|
|
n = old2new(typeswvar->right, n->type, &$$->ninit);
|
|
|
|
$$->list = list1(nod(OTYPESW, n, N));
|
2009-06-06 13:46:38 -06:00
|
|
|
break;
|
|
|
|
}
|
2009-07-14 00:38:39 -06:00
|
|
|
// maybe walkexpr found problems that keep
|
2009-07-06 17:29:28 -06:00
|
|
|
// e from being valid even outside a type switch.
|
2009-07-14 00:38:39 -06:00
|
|
|
// only complain if walkexpr didn't print new errors.
|
2009-07-06 17:29:28 -06:00
|
|
|
if(nerrors == e)
|
|
|
|
yyerror("non-type case in type switch");
|
|
|
|
$$->diag = 1;
|
2009-07-17 02:00:44 -06:00
|
|
|
} else {
|
|
|
|
// expr switch
|
|
|
|
$$->list = $2;
|
2009-03-17 14:58:38 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
break;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| LCASE type ':'
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
Node *n;
|
2009-07-10 17:29:26 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OXCASE, N, N);
|
2009-06-06 13:46:38 -06:00
|
|
|
poptodcl();
|
|
|
|
if(typeswvar == N || typeswvar->right == N) {
|
|
|
|
yyerror("type case not in a type switch");
|
2009-07-17 02:00:44 -06:00
|
|
|
n = N;
|
2009-06-06 13:46:38 -06:00
|
|
|
} else
|
2009-07-17 02:00:44 -06:00
|
|
|
n = old2new(typeswvar->right, $2, &$$->ninit);
|
|
|
|
$$->list = list1(nod(OTYPESW, n, N));
|
2009-06-06 13:46:38 -06:00
|
|
|
}
|
2008-09-16 20:14:33 -06:00
|
|
|
| LCASE name '=' expr ':'
|
|
|
|
{
|
|
|
|
// will be converted to OCASE
|
|
|
|
// right will point to next case
|
|
|
|
// done in casebody()
|
|
|
|
poptodcl();
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OXCASE, N, N);
|
|
|
|
$$->list = list1(nod(OAS, $2, $4));
|
2008-09-16 20:14:33 -06:00
|
|
|
}
|
|
|
|
| LCASE name LCOLAS expr ':'
|
|
|
|
{
|
|
|
|
// will be converted to OCASE
|
|
|
|
// right will point to next case
|
|
|
|
// done in casebody()
|
|
|
|
poptodcl();
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OXCASE, N, N);
|
|
|
|
$$->list = list1(nod(OAS, selectas($2, $4, &$$->ninit), $4));
|
2008-09-16 20:14:33 -06:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| LDEFAULT ':'
|
|
|
|
{
|
|
|
|
poptodcl();
|
|
|
|
$$ = nod(OXCASE, N, N);
|
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
compound_stmt:
|
|
|
|
'{'
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
markdcl();
|
2009-06-06 13:46:38 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
stmt_list '}'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = liststmt($3);
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2009-05-30 22:18:15 -06:00
|
|
|
switch_body:
|
2009-06-06 13:46:38 -06:00
|
|
|
LBODY
|
2009-05-30 22:18:15 -06:00
|
|
|
{
|
|
|
|
markdcl();
|
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
caseblock_list '}'
|
2009-05-30 22:18:15 -06:00
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
popdcl();
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2009-05-30 22:18:15 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
caseblock:
|
2009-07-17 02:00:44 -06:00
|
|
|
case stmt_list
|
2009-05-30 22:18:15 -06:00
|
|
|
{
|
|
|
|
$$ = $1;
|
|
|
|
$$->nbody = $2;
|
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
caseblock_list:
|
2009-05-30 22:18:15 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
|
|
|
}
|
|
|
|
| caseblock_list caseblock
|
|
|
|
{
|
|
|
|
$$ = list($1, $2);
|
2009-05-30 22:18:15 -06:00
|
|
|
}
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
loop_body:
|
|
|
|
LBODY
|
|
|
|
{
|
|
|
|
markdcl();
|
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
stmt_list '}'
|
2009-06-06 13:46:38 -06:00
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
popdcl();
|
|
|
|
}
|
|
|
|
|
2009-01-28 16:41:50 -07:00
|
|
|
range_stmt:
|
2009-06-06 13:46:38 -06:00
|
|
|
expr_list '=' LRANGE expr
|
2008-12-06 14:40:30 -07:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(ORANGE, N, $4);
|
|
|
|
$$->list = $1;
|
2008-12-06 14:40:30 -07:00
|
|
|
$$->etype = 0; // := flag
|
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| expr_list LCOLAS LRANGE expr
|
2008-12-06 14:40:30 -07:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(ORANGE, N, $4);
|
|
|
|
$$->list = $1;
|
2008-12-06 14:40:30 -07:00
|
|
|
$$->etype = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for_header:
|
2009-01-28 16:41:50 -07:00
|
|
|
osimple_stmt ';' osimple_stmt ';' osimple_stmt
|
|
|
|
{
|
2008-06-04 15:37:38 -06:00
|
|
|
// init ; test ; incr
|
2008-12-15 14:44:27 -07:00
|
|
|
if($5 != N && $5->colas != 0)
|
|
|
|
yyerror("cannot declare in the for-increment");
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = nod(OFOR, N, N);
|
2009-07-17 02:00:44 -06:00
|
|
|
if($1 != N)
|
|
|
|
$$->ninit = list1($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
$$->ntest = $3;
|
|
|
|
$$->nincr = $5;
|
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| osimple_stmt
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-12-06 14:40:30 -07:00
|
|
|
// normal test
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = nod(OFOR, N, N);
|
|
|
|
$$->ntest = $1;
|
|
|
|
}
|
2009-01-28 16:41:50 -07:00
|
|
|
| range_stmt
|
|
|
|
{
|
|
|
|
$$ = dorange($1);
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
for_body:
|
2009-06-06 13:46:38 -06:00
|
|
|
for_header loop_body
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = $1;
|
2009-07-17 02:00:44 -06:00
|
|
|
$$->nbody = concat($$->nbody, $2);
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
for_stmt:
|
2009-05-30 22:18:15 -06:00
|
|
|
LFOR
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
markdcl();
|
2009-05-30 22:18:15 -06:00
|
|
|
}
|
|
|
|
for_body
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-05-30 22:18:15 -06:00
|
|
|
$$ = $3;
|
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if_header:
|
2009-06-06 13:46:38 -06:00
|
|
|
osimple_stmt
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
// test
|
|
|
|
$$ = nod(OIF, N, N);
|
|
|
|
$$->ntest = $1;
|
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| osimple_stmt ';' osimple_stmt
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
// init ; test
|
|
|
|
$$ = nod(OIF, N, N);
|
2009-07-17 02:00:44 -06:00
|
|
|
if($1 != N)
|
|
|
|
$$->ninit = list1($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
$$->ntest = $3;
|
|
|
|
}
|
|
|
|
|
2009-05-30 22:18:15 -06:00
|
|
|
if_stmt:
|
|
|
|
LIF
|
|
|
|
{
|
|
|
|
markdcl();
|
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
if_header loop_body
|
2009-05-30 22:18:15 -06:00
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
$$->nbody = $4;
|
|
|
|
// no popdcl; maybe there's an LELSE
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(LELSE);
|
2009-05-30 22:18:15 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
switch_stmt:
|
|
|
|
LSWITCH
|
|
|
|
{
|
|
|
|
markdcl();
|
|
|
|
}
|
2009-03-06 18:50:43 -07:00
|
|
|
if_header
|
|
|
|
{
|
|
|
|
Node *n;
|
2009-05-30 22:18:15 -06:00
|
|
|
n = $3->ntest;
|
2009-03-06 18:50:43 -07:00
|
|
|
if(n != N && n->op == OTYPESW)
|
|
|
|
n = n->left;
|
|
|
|
else
|
|
|
|
n = N;
|
2009-07-17 02:00:44 -06:00
|
|
|
typeswvar = nod(OXXX, typeswvar, n);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-05-30 22:18:15 -06:00
|
|
|
switch_body
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-05-30 22:18:15 -06:00
|
|
|
$$ = $3;
|
|
|
|
$$->op = OSWITCH;
|
2009-07-17 02:00:44 -06:00
|
|
|
$$->list = $5;
|
2009-05-30 22:18:15 -06:00
|
|
|
typeswvar = typeswvar->left;
|
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2008-07-20 21:13:07 -06:00
|
|
|
select_stmt:
|
2009-05-30 22:18:15 -06:00
|
|
|
LSELECT
|
2008-07-20 21:13:07 -06:00
|
|
|
{
|
|
|
|
markdcl();
|
|
|
|
}
|
2009-05-30 22:18:15 -06:00
|
|
|
switch_body
|
2008-07-20 21:13:07 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OSELECT, N, N);
|
|
|
|
$$->list = $3;
|
2009-05-30 22:18:15 -06:00
|
|
|
popdcl();
|
2008-07-20 21:13:07 -06:00
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
/*
|
|
|
|
* expressions
|
|
|
|
*/
|
|
|
|
expr:
|
|
|
|
uexpr
|
|
|
|
| expr LOROR expr
|
|
|
|
{
|
|
|
|
$$ = nod(OOROR, $1, $3);
|
|
|
|
}
|
|
|
|
| expr LANDAND expr
|
|
|
|
{
|
|
|
|
$$ = nod(OANDAND, $1, $3);
|
|
|
|
}
|
|
|
|
| expr LEQ expr
|
|
|
|
{
|
|
|
|
$$ = nod(OEQ, $1, $3);
|
|
|
|
}
|
|
|
|
| expr LNE expr
|
|
|
|
{
|
|
|
|
$$ = nod(ONE, $1, $3);
|
|
|
|
}
|
|
|
|
| expr LLT expr
|
|
|
|
{
|
|
|
|
$$ = nod(OLT, $1, $3);
|
|
|
|
}
|
|
|
|
| expr LLE expr
|
|
|
|
{
|
|
|
|
$$ = nod(OLE, $1, $3);
|
|
|
|
}
|
|
|
|
| expr LGE expr
|
|
|
|
{
|
|
|
|
$$ = nod(OGE, $1, $3);
|
|
|
|
}
|
|
|
|
| expr LGT expr
|
|
|
|
{
|
|
|
|
$$ = nod(OGT, $1, $3);
|
|
|
|
}
|
|
|
|
| expr '+' expr
|
|
|
|
{
|
|
|
|
$$ = nod(OADD, $1, $3);
|
|
|
|
}
|
|
|
|
| expr '-' expr
|
|
|
|
{
|
|
|
|
$$ = nod(OSUB, $1, $3);
|
|
|
|
}
|
|
|
|
| expr '|' expr
|
|
|
|
{
|
|
|
|
$$ = nod(OOR, $1, $3);
|
|
|
|
}
|
|
|
|
| expr '^' expr
|
|
|
|
{
|
|
|
|
$$ = nod(OXOR, $1, $3);
|
|
|
|
}
|
|
|
|
| expr '*' expr
|
|
|
|
{
|
|
|
|
$$ = nod(OMUL, $1, $3);
|
|
|
|
}
|
|
|
|
| expr '/' expr
|
|
|
|
{
|
|
|
|
$$ = nod(ODIV, $1, $3);
|
|
|
|
}
|
|
|
|
| expr '%' expr
|
|
|
|
{
|
|
|
|
$$ = nod(OMOD, $1, $3);
|
|
|
|
}
|
|
|
|
| expr '&' expr
|
|
|
|
{
|
|
|
|
$$ = nod(OAND, $1, $3);
|
|
|
|
}
|
2009-03-11 20:59:35 -06:00
|
|
|
| expr LANDNOT expr
|
|
|
|
{
|
|
|
|
$$ = nod(OANDNOT, $1, $3);
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| expr LLSH expr
|
|
|
|
{
|
|
|
|
$$ = nod(OLSH, $1, $3);
|
|
|
|
}
|
|
|
|
| expr LRSH expr
|
|
|
|
{
|
|
|
|
$$ = nod(ORSH, $1, $3);
|
|
|
|
}
|
2008-09-16 20:14:33 -06:00
|
|
|
| expr LCOMM expr
|
2008-07-15 22:07:59 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OSEND, $1, $3);
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
uexpr:
|
|
|
|
pexpr
|
|
|
|
| '*' uexpr
|
|
|
|
{
|
|
|
|
$$ = nod(OIND, $2, N);
|
|
|
|
}
|
|
|
|
| '&' uexpr
|
|
|
|
{
|
|
|
|
$$ = nod(OADDR, $2, N);
|
|
|
|
}
|
|
|
|
| '+' uexpr
|
|
|
|
{
|
|
|
|
$$ = nod(OPLUS, $2, N);
|
|
|
|
}
|
|
|
|
| '-' uexpr
|
|
|
|
{
|
|
|
|
$$ = nod(OMINUS, $2, N);
|
|
|
|
}
|
|
|
|
| '!' uexpr
|
|
|
|
{
|
|
|
|
$$ = nod(ONOT, $2, N);
|
|
|
|
}
|
|
|
|
| '~' uexpr
|
|
|
|
{
|
|
|
|
yyerror("the OCOM operator is ^");
|
|
|
|
$$ = nod(OCOM, $2, N);
|
|
|
|
}
|
|
|
|
| '^' uexpr
|
|
|
|
{
|
|
|
|
$$ = nod(OCOM, $2, N);
|
|
|
|
}
|
2008-09-16 20:14:33 -06:00
|
|
|
| LCOMM uexpr
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(ORECV, $2, N);
|
|
|
|
}
|
|
|
|
|
2009-04-28 18:20:18 -06:00
|
|
|
/*
|
|
|
|
* call-like statements that
|
2009-07-17 02:00:44 -06:00
|
|
|
* can be preceded by 'defer' and 'go'
|
2009-04-28 18:20:18 -06:00
|
|
|
*/
|
|
|
|
pseudocall:
|
2009-06-06 13:46:38 -06:00
|
|
|
pexpr '(' oexpr_or_type_list ')'
|
2009-04-28 18:20:18 -06:00
|
|
|
{
|
|
|
|
$$ = unsafenmagic($1, $3);
|
2009-06-06 13:46:38 -06:00
|
|
|
if($$)
|
|
|
|
break;
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OCALL, $1, N);
|
|
|
|
$$->list = $3;
|
2009-04-28 18:20:18 -06:00
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
pexpr:
|
|
|
|
LLITERAL
|
|
|
|
{
|
2009-03-12 20:04:38 -06:00
|
|
|
$$ = nodlit($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| name %prec NotBrace
|
|
|
|
| pexpr '.' sym
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
if($1->op == OPACK) {
|
|
|
|
Sym *s;
|
2009-07-14 00:38:39 -06:00
|
|
|
s = restrictlookup($3->name, $1->sym->name);
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = oldname(s);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$$ = nod(ODOT, $1, newname($3));
|
|
|
|
$$ = adddot($$);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| '(' expr_or_type ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| pexpr '.' '(' expr_or_type ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(ODOTTYPE, $1, $4);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-03-06 18:50:43 -07:00
|
|
|
| pexpr '.' '(' LTYPE ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OTYPESW, $1, N);
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| pexpr '[' expr ']'
|
|
|
|
{
|
|
|
|
$$ = nod(OINDEX, $1, $3);
|
|
|
|
}
|
|
|
|
| pexpr '[' keyval ']'
|
|
|
|
{
|
|
|
|
$$ = nod(OSLICE, $1, $3);
|
|
|
|
}
|
2009-04-28 18:20:18 -06:00
|
|
|
| pseudocall
|
2009-03-03 09:41:02 -07:00
|
|
|
| convtype '(' expr ')'
|
2008-09-05 20:50:34 -06:00
|
|
|
{
|
2009-03-03 09:41:02 -07:00
|
|
|
// conversion
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OCALL, $1, N);
|
|
|
|
$$->list = list1($3);
|
2009-06-06 13:46:38 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| convtype lbrace braced_keyval_list '}'
|
2009-06-06 13:46:38 -06:00
|
|
|
{
|
|
|
|
// composite expression
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OCOMPOS, N, $1);
|
|
|
|
$$->list = $3;
|
2009-06-06 13:46:38 -06:00
|
|
|
|
|
|
|
// If the opening brace was an LBODY,
|
|
|
|
// set up for another one now that we're done.
|
|
|
|
// See comment in lex.c about loophack.
|
|
|
|
if($2 == LBODY)
|
|
|
|
loophack = 1;
|
2008-09-05 20:50:34 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| pexpr '{' braced_keyval_list '}'
|
2008-09-05 20:50:34 -06:00
|
|
|
{
|
2009-03-03 09:41:02 -07:00
|
|
|
// composite expression
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OCOMPOS, N, $1);
|
|
|
|
$$->list = $3;
|
2008-09-05 20:50:34 -06:00
|
|
|
}
|
|
|
|
| fnliteral
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
expr_or_type:
|
|
|
|
expr
|
2009-07-14 00:38:39 -06:00
|
|
|
| ntype %prec PreferToRightParen
|
2009-06-06 13:46:38 -06:00
|
|
|
|
|
|
|
name_or_type:
|
|
|
|
dotname
|
|
|
|
| type
|
2009-05-08 16:40:31 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = typenod($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
lbrace:
|
|
|
|
LBODY
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = LBODY;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| '{'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = '{';
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* names and types
|
|
|
|
* newname is used before declared
|
|
|
|
* oldname is used after declared
|
|
|
|
*/
|
|
|
|
new_name:
|
2009-06-06 13:46:38 -06:00
|
|
|
sym
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = newname($1);
|
|
|
|
}
|
|
|
|
|
|
|
|
new_type:
|
2009-06-06 13:46:38 -06:00
|
|
|
sym
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = newtype($1);
|
|
|
|
}
|
|
|
|
|
2008-08-29 21:30:19 -06:00
|
|
|
onew_name:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| new_name
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
sym:
|
2009-06-06 13:46:38 -06:00
|
|
|
LNAME
|
2008-10-26 15:04:09 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
name:
|
2009-06-06 13:46:38 -06:00
|
|
|
sym %prec NotDot
|
2009-03-05 16:57:03 -07:00
|
|
|
{
|
|
|
|
$$ = oldname($1);
|
|
|
|
}
|
|
|
|
|
|
|
|
labelname:
|
|
|
|
name
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
convtype:
|
2009-07-14 00:38:39 -06:00
|
|
|
'[' oexpr ']' ntype
|
2008-06-08 13:48:37 -06:00
|
|
|
{
|
2008-09-03 15:09:29 -06:00
|
|
|
// array literal
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTARRAY, $2, $4);
|
2008-06-08 13:48:37 -06:00
|
|
|
}
|
2009-07-14 00:38:39 -06:00
|
|
|
| '[' dotdotdot ']' ntype
|
2009-01-06 18:31:24 -07:00
|
|
|
{
|
|
|
|
// array literal of nelem
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTARRAY, $2, $4);
|
2009-01-06 18:31:24 -07:00
|
|
|
}
|
2009-07-14 00:38:39 -06:00
|
|
|
| LMAP '[' ntype ']' ntype
|
2008-06-08 13:48:37 -06:00
|
|
|
{
|
2008-09-03 15:09:29 -06:00
|
|
|
// map literal
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTMAP, $3, $5);
|
2008-06-08 13:48:37 -06:00
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| structtype
|
2008-06-08 13:48:37 -06:00
|
|
|
|
2008-10-07 13:36:30 -06:00
|
|
|
/*
|
|
|
|
* to avoid parsing conflicts, type is split into
|
|
|
|
* channel types
|
|
|
|
* function types
|
2009-06-06 20:27:48 -06:00
|
|
|
* parenthesized types
|
2008-10-07 13:36:30 -06:00
|
|
|
* any other type
|
|
|
|
* the type system makes additional restrictions,
|
|
|
|
* but those are not implemented in the grammar.
|
|
|
|
*/
|
2008-10-29 13:46:44 -06:00
|
|
|
dotdotdot:
|
|
|
|
LDDD
|
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = typenod(typ(TDDD));
|
2008-10-29 13:46:44 -06:00
|
|
|
}
|
2008-10-07 13:36:30 -06:00
|
|
|
|
2009-06-06 20:27:48 -06:00
|
|
|
type:
|
2009-07-14 00:38:39 -06:00
|
|
|
ntype
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
NodeList *init;
|
2009-07-14 00:38:39 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
init = nil;
|
2009-07-14 00:38:39 -06:00
|
|
|
walkexpr($1, Etype, &init);
|
|
|
|
// init can only be set if this was not a type; ignore
|
|
|
|
|
|
|
|
$$ = $1->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
ntype:
|
2009-06-06 20:27:48 -06:00
|
|
|
chantype
|
2009-07-14 00:38:39 -06:00
|
|
|
| fntype { $$ = typenod($1); }
|
2009-06-06 20:27:48 -06:00
|
|
|
| othertype
|
2009-07-14 00:38:39 -06:00
|
|
|
| '(' ntype ')'
|
2009-02-18 11:07:46 -07:00
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
2008-10-07 13:36:30 -06:00
|
|
|
|
2009-06-06 20:27:48 -06:00
|
|
|
non_chan_type:
|
2009-07-14 00:38:39 -06:00
|
|
|
fntype { $$ = typenod($1); }
|
2009-06-06 20:27:48 -06:00
|
|
|
| othertype
|
2009-07-14 00:38:39 -06:00
|
|
|
| '(' ntype ')'
|
fix up arg list parsing to handle any names:
type t1 int;
type t2 int;
type t3 int;
func f1(t1, t2, t3);
func f2(t1, t2, t3 bool);
func f3(t1, t2, x t3);
func f4(*t2, x t3); // error: cannot mix
func f5(t1, *t3);
func (x *t1) f6(y *[]t2) (t1, *t3);
func f7() (int, *string);
func f8(t1, *t2, x t3); // error: cannot mix
func f9() (x int, *string);
func f10(*t2, t3);
R=ken
OCL=16202
CL=16210
2008-09-30 13:53:11 -06:00
|
|
|
{
|
2009-06-06 20:27:48 -06:00
|
|
|
$$ = $2;
|
fix up arg list parsing to handle any names:
type t1 int;
type t2 int;
type t3 int;
func f1(t1, t2, t3);
func f2(t1, t2, t3 bool);
func f3(t1, t2, x t3);
func f4(*t2, x t3); // error: cannot mix
func f5(t1, *t3);
func (x *t1) f6(y *[]t2) (t1, *t3);
func f7() (int, *string);
func f8(t1, *t2, x t3); // error: cannot mix
func f9() (x int, *string);
func f10(*t2, t3);
R=ken
OCL=16202
CL=16210
2008-09-30 13:53:11 -06:00
|
|
|
}
|
|
|
|
|
2009-06-06 20:27:48 -06:00
|
|
|
non_fn_type:
|
|
|
|
chantype
|
|
|
|
| othertype
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
dotname:
|
|
|
|
name %prec NotDot
|
|
|
|
| name '.' sym
|
|
|
|
{
|
|
|
|
if($1->op == OPACK) {
|
|
|
|
Sym *s;
|
2009-07-14 00:38:39 -06:00
|
|
|
s = restrictlookup($3->name, $1->sym->name);
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = oldname(s);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$$ = nod(ODOT, $1, newname($3));
|
|
|
|
$$ = adddot($$);
|
|
|
|
}
|
2008-10-07 13:36:30 -06:00
|
|
|
|
2009-06-06 20:27:48 -06:00
|
|
|
othertype:
|
|
|
|
'[' oexpr ']' type
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = typenod(aindex($2, $4));
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-07-14 00:38:39 -06:00
|
|
|
| LCOMM LCHAN ntype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTCHAN, $3, N);
|
|
|
|
$$->etype = Crecv;
|
2008-09-16 20:14:33 -06:00
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| LCHAN LCOMM non_chan_type
|
2008-09-16 20:14:33 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTCHAN, $3, N);
|
|
|
|
$$->etype = Csend;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-07-14 00:38:39 -06:00
|
|
|
| LMAP '[' ntype ']' ntype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTMAP, $3, $5);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-07-14 00:38:39 -06:00
|
|
|
| '*' ntype
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OIND, $2, N);
|
2008-06-21 16:11:29 -06:00
|
|
|
}
|
2008-10-07 13:36:30 -06:00
|
|
|
| structtype
|
|
|
|
| interfacetype
|
2009-06-06 20:27:48 -06:00
|
|
|
| dotname
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-06-06 20:27:48 -06:00
|
|
|
chantype:
|
2009-07-14 00:38:39 -06:00
|
|
|
LCHAN ntype
|
2008-09-16 20:14:33 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTCHAN, $2, N);
|
|
|
|
$$->etype = Cboth;
|
2008-09-16 20:14:33 -06:00
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
structtype:
|
2009-07-17 02:00:44 -06:00
|
|
|
LSTRUCT '{' structdcl_list osemi '}'
|
2008-09-05 20:50:34 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OTSTRUCT, N, N);
|
|
|
|
$$->list = $3;
|
2009-06-06 20:27:48 -06:00
|
|
|
// Distinguish closing brace in struct from
|
|
|
|
// other closing braces by explicitly marking it.
|
|
|
|
// Used above (yylast == LSEMIBRACE).
|
|
|
|
yylast = LSEMIBRACE;
|
2008-09-05 20:50:34 -06:00
|
|
|
}
|
|
|
|
| LSTRUCT '{' '}'
|
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTSTRUCT, N, N);
|
2009-06-06 20:27:48 -06:00
|
|
|
yylast = LSEMIBRACE;
|
2008-09-05 20:50:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
interfacetype:
|
2009-07-17 02:00:44 -06:00
|
|
|
LINTERFACE '{' interfacedcl_list osemi '}'
|
2008-09-05 20:50:34 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(OTINTER, N, N);
|
|
|
|
$$->list = $3;
|
2009-06-06 20:27:48 -06:00
|
|
|
yylast = LSEMIBRACE;
|
2008-09-05 20:50:34 -06:00
|
|
|
}
|
|
|
|
| LINTERFACE '{' '}'
|
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OTINTER, N, N);
|
2009-06-06 20:27:48 -06:00
|
|
|
yylast = LSEMIBRACE;
|
2008-09-05 20:50:34 -06:00
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
keyval:
|
|
|
|
expr ':' expr
|
|
|
|
{
|
2008-09-03 15:40:22 -06:00
|
|
|
$$ = nod(OKEY, $1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-05-21 17:31:10 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* function stuff
|
|
|
|
* all in one place to show how crappy it all is
|
|
|
|
*/
|
|
|
|
xfndcl:
|
2008-06-11 22:06:26 -06:00
|
|
|
LFUNC
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-06-11 22:06:26 -06:00
|
|
|
maxarg = 0;
|
|
|
|
stksize = 0;
|
|
|
|
} fndcl fnbody
|
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
$$->nbody = $4;
|
2008-06-04 15:37:38 -06:00
|
|
|
funcbody($$);
|
|
|
|
}
|
|
|
|
|
|
|
|
fndcl:
|
|
|
|
new_name '(' oarg_type_list ')' fnres
|
|
|
|
{
|
|
|
|
b0stack = dclstack; // mark base for fn literals
|
|
|
|
$$ = nod(ODCLFUNC, N, N);
|
|
|
|
$$->nname = $1;
|
2009-07-17 02:00:44 -06:00
|
|
|
if($3 == nil && $5 == nil)
|
2008-07-19 19:39:12 -06:00
|
|
|
$$->nname = renameinit($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
$$->type = functype(N, $3, $5);
|
|
|
|
funchdr($$);
|
|
|
|
}
|
|
|
|
| '(' oarg_type_list ')' new_name '(' oarg_type_list ')' fnres
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
Node *rcvr;
|
|
|
|
|
|
|
|
rcvr = $2->n;
|
|
|
|
if($2->next != nil || $2->n->op != ODCLFIELD) {
|
|
|
|
yyerror("bad receiver in method");
|
|
|
|
rcvr = N;
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
b0stack = dclstack; // mark base for fn literals
|
|
|
|
$$ = nod(ODCLFUNC, N, N);
|
2009-07-17 02:00:44 -06:00
|
|
|
$$->nname = $4;
|
|
|
|
$$->nname = methodname($4, rcvr->type);
|
|
|
|
$$->type = functype(rcvr, $6, $8);
|
|
|
|
funchdr($$);
|
|
|
|
if(rcvr != N)
|
2008-10-16 14:29:03 -06:00
|
|
|
addmethod($4, $$->type, 1);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
fntype:
|
2009-06-06 20:27:48 -06:00
|
|
|
LFUNC '(' oarg_type_list ')' fnres
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-01-30 15:39:42 -07:00
|
|
|
$$ = functype(N, $3, $5);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fnlitdcl:
|
|
|
|
fntype
|
|
|
|
{
|
2009-02-06 14:47:10 -07:00
|
|
|
markdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = $1;
|
2009-02-06 14:47:10 -07:00
|
|
|
funclit0($$);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fnliteral:
|
2009-07-17 02:00:44 -06:00
|
|
|
fnlitdcl '{' stmt_list '}'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-02-06 14:47:10 -07:00
|
|
|
$$ = funclit1($1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fnbody:
|
2009-07-17 02:00:44 -06:00
|
|
|
{
|
|
|
|
$$ = nil;
|
|
|
|
}
|
|
|
|
| '{' stmt_list '}'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
$$ = $2;
|
2009-07-17 02:00:44 -06:00
|
|
|
if($$ == nil)
|
|
|
|
$$ = list1(nod(ORETURN, N, N));
|
2009-06-06 20:27:48 -06:00
|
|
|
yyoptsemi(0);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-07-05 13:49:25 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
fnres:
|
2009-03-05 16:57:03 -07:00
|
|
|
%prec NotParen
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-06-21 16:11:29 -06:00
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| non_fn_type
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list1(nod(ODCLFIELD, N, $1));
|
2008-06-21 16:11:29 -06:00
|
|
|
}
|
2008-10-07 13:36:30 -06:00
|
|
|
| '(' oarg_type_list ')'
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
2008-06-21 16:11:29 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
/*
|
|
|
|
* lists of things
|
|
|
|
* note that they are left recursive
|
|
|
|
* to conserve yacc stack. they need to
|
|
|
|
* be reversed to interpret correctly
|
|
|
|
*/
|
2009-07-17 02:00:44 -06:00
|
|
|
xdcl_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
|
|
|
}
|
|
|
|
| xdcl_list xdcl
|
|
|
|
{
|
|
|
|
$$ = concat($1, $2);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
vardcl_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
vardcl
|
2009-07-17 02:00:44 -06:00
|
|
|
| vardcl_list ';' vardcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = concat($1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
constdcl_list:
|
2008-09-04 13:21:10 -06:00
|
|
|
constdcl1
|
2009-07-17 02:00:44 -06:00
|
|
|
| constdcl_list ';' constdcl1
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
typedcl_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
typedcl
|
2009-07-17 02:00:44 -06:00
|
|
|
| typedcl_list ';' typedcl
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
structdcl_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
structdcl
|
2009-07-17 02:00:44 -06:00
|
|
|
| structdcl_list ';' structdcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = concat($1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
interfacedcl_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
interfacedcl
|
2009-07-17 02:00:44 -06:00
|
|
|
| interfacedcl_list ';' interfacedcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = concat($1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
structdcl:
|
2009-07-17 02:00:44 -06:00
|
|
|
name_list ntype oliteral
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
NodeList *l;
|
|
|
|
|
|
|
|
for(l=$1; l; l=l->next) {
|
|
|
|
l->n = nod(ODCLFIELD, l->n, $2);
|
|
|
|
l->n->val = $3;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-30 16:29:55 -06:00
|
|
|
| embed oliteral
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$1->val = $2;
|
|
|
|
$$ = list1($1);
|
2008-10-30 16:29:55 -06:00
|
|
|
}
|
|
|
|
| '*' embed oliteral
|
2008-09-26 22:27:26 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$2->right = nod(OIND, $2->right, N);
|
|
|
|
$2->val = $3;
|
|
|
|
$$ = list1($2);
|
2008-10-21 16:04:10 -06:00
|
|
|
}
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
packname:
|
|
|
|
LNAME
|
|
|
|
| LNAME '.' sym
|
2008-10-21 16:04:10 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
char *pkg;
|
|
|
|
|
|
|
|
if($1->def == N || $1->def->op != OPACK) {
|
|
|
|
yyerror("%S is not a package", $1);
|
|
|
|
pkg = $1->name;
|
|
|
|
} else
|
|
|
|
pkg = $1->def->sym->name;
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = restrictlookup($3->name, pkg);
|
2008-10-19 21:13:37 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
|
|
|
|
embed:
|
|
|
|
packname
|
2008-10-19 21:13:37 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = embedded($1);
|
2008-09-26 22:27:26 -06:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
interfacedcl:
|
|
|
|
name_list indcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
NodeList *l;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
for(l=$1; l; l=l->next)
|
|
|
|
l->n = nod(ODCLFIELD, l->n, $2);
|
|
|
|
$$ = $1;
|
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| packname
|
2009-02-16 17:36:18 -07:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list1(nod(ODCLFIELD, N, typenod(oldtype($1))));
|
2009-02-16 17:36:18 -07:00
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
indcl:
|
2008-06-04 15:37:38 -06:00
|
|
|
'(' oarg_type_list ')' fnres
|
|
|
|
{
|
|
|
|
// without func keyword
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = typenod(functype(fakethis(), $2, $4));
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
fix up arg list parsing to handle any names:
type t1 int;
type t2 int;
type t3 int;
func f1(t1, t2, t3);
func f2(t1, t2, t3 bool);
func f3(t1, t2, x t3);
func f4(*t2, x t3); // error: cannot mix
func f5(t1, *t3);
func (x *t1) f6(y *[]t2) (t1, *t3);
func f7() (int, *string);
func f8(t1, *t2, x t3); // error: cannot mix
func f9() (x int, *string);
func f10(*t2, t3);
R=ken
OCL=16202
CL=16210
2008-09-30 13:53:11 -06:00
|
|
|
/*
|
|
|
|
* function arguments.
|
|
|
|
*/
|
2009-06-06 13:46:38 -06:00
|
|
|
arg_type:
|
|
|
|
name_or_type
|
|
|
|
| sym name_or_type
|
|
|
|
{
|
|
|
|
$$ = $1->def;
|
|
|
|
if($$ == N) {
|
|
|
|
$$ = nod(ONONAME, N, N);
|
|
|
|
$$->sym = $1;
|
|
|
|
}
|
|
|
|
$$ = nod(OKEY, $$, $2);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| sym dotdotdot
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = $1->def;
|
|
|
|
if($$ == N) {
|
|
|
|
$$ = nod(ONONAME, N, N);
|
|
|
|
$$->sym = $1;
|
|
|
|
}
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(OKEY, $$, $2);
|
fix up arg list parsing to handle any names:
type t1 int;
type t2 int;
type t3 int;
func f1(t1, t2, t3);
func f2(t1, t2, t3 bool);
func f3(t1, t2, x t3);
func f4(*t2, x t3); // error: cannot mix
func f5(t1, *t3);
func (x *t1) f6(y *[]t2) (t1, *t3);
func f7() (int, *string);
func f8(t1, *t2, x t3); // error: cannot mix
func f9() (x int, *string);
func f10(*t2, t3);
R=ken
OCL=16202
CL=16210
2008-09-30 13:53:11 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| dotdotdot
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
arg_type_list:
|
2009-06-06 13:46:38 -06:00
|
|
|
arg_type
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list1($1);
|
|
|
|
}
|
|
|
|
| arg_type_list ',' arg_type
|
|
|
|
{
|
|
|
|
$$ = list($1, $3);
|
fix up arg list parsing to handle any names:
type t1 int;
type t2 int;
type t3 int;
func f1(t1, t2, t3);
func f2(t1, t2, t3 bool);
func f3(t1, t2, x t3);
func f4(*t2, x t3); // error: cannot mix
func f5(t1, *t3);
func (x *t1) f6(y *[]t2) (t1, *t3);
func f7() (int, *string);
func f8(t1, *t2, x t3); // error: cannot mix
func f9() (x int, *string);
func f10(*t2, t3);
R=ken
OCL=16202
CL=16210
2008-09-30 13:53:11 -06:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
oarg_type_list:
|
|
|
|
{
|
|
|
|
$$ = nil;
|
|
|
|
}
|
|
|
|
| arg_type_list
|
fix up arg list parsing to handle any names:
type t1 int;
type t2 int;
type t3 int;
func f1(t1, t2, t3);
func f2(t1, t2, t3 bool);
func f3(t1, t2, x t3);
func f4(*t2, x t3); // error: cannot mix
func f5(t1, *t3);
func (x *t1) f6(y *[]t2) (t1, *t3);
func f7() (int, *string);
func f8(t1, *t2, x t3); // error: cannot mix
func f9() (x int, *string);
func f10(*t2, t3);
R=ken
OCL=16202
CL=16210
2008-09-30 13:53:11 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = checkarglist($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2008-06-08 17:11:14 -06:00
|
|
|
/*
|
2009-06-06 20:27:48 -06:00
|
|
|
* statement
|
2008-06-08 17:11:14 -06:00
|
|
|
*/
|
2009-06-06 20:27:48 -06:00
|
|
|
stmt:
|
2008-06-08 18:21:46 -06:00
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| simple_stmt
|
|
|
|
| compound_stmt
|
|
|
|
| common_dcl
|
2009-07-17 02:00:44 -06:00
|
|
|
{
|
|
|
|
$$ = liststmt($1);
|
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| for_stmt
|
|
|
|
| switch_stmt
|
|
|
|
| select_stmt
|
|
|
|
| if_stmt
|
|
|
|
{
|
|
|
|
popdcl();
|
|
|
|
$$ = $1;
|
|
|
|
}
|
|
|
|
| if_stmt LELSE stmt
|
|
|
|
{
|
|
|
|
popdcl();
|
|
|
|
$$ = $1;
|
2009-07-17 02:00:44 -06:00
|
|
|
$$->nelse = list1($3);
|
2009-06-06 20:27:48 -06:00
|
|
|
}
|
|
|
|
| error
|
2008-07-03 19:05:20 -06:00
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| labelname ':' stmt
|
2008-10-07 13:36:30 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
NodeList *l;
|
|
|
|
|
|
|
|
l = list1(nod(OLABEL, $1, N));
|
|
|
|
if($3)
|
|
|
|
l = list(l, $3);
|
|
|
|
$$ = liststmt(l);
|
2008-10-07 13:36:30 -06:00
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| LFALL
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 20:27:48 -06:00
|
|
|
// will be converted to OFALL
|
|
|
|
$$ = nod(OXFALL, N, N);
|
2008-06-08 13:48:37 -06:00
|
|
|
}
|
2009-06-06 20:27:48 -06:00
|
|
|
| LBREAK onew_name
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 20:27:48 -06:00
|
|
|
$$ = nod(OBREAK, $2, N);
|
|
|
|
}
|
|
|
|
| LCONTINUE onew_name
|
|
|
|
{
|
|
|
|
$$ = nod(OCONTINUE, $2, N);
|
|
|
|
}
|
|
|
|
| LGO pseudocall
|
|
|
|
{
|
|
|
|
$$ = nod(OPROC, $2, N);
|
|
|
|
}
|
|
|
|
| LDEFER pseudocall
|
|
|
|
{
|
|
|
|
$$ = nod(ODEFER, $2, N);
|
|
|
|
}
|
|
|
|
| LGOTO new_name
|
|
|
|
{
|
|
|
|
$$ = nod(OGOTO, $2, N);
|
|
|
|
}
|
|
|
|
| LRETURN oexpr_list
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nod(ORETURN, N, N);
|
|
|
|
$$->list = $2;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
stmt_list:
|
2009-06-06 20:27:48 -06:00
|
|
|
stmt
|
2009-04-28 13:28:31 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
|
|
|
if($1 != N)
|
|
|
|
$$ = list1($1);
|
2009-04-28 13:28:31 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| stmt_list ';' stmt
|
2008-10-26 15:04:09 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = $1;
|
|
|
|
if($3 != N)
|
|
|
|
$$ = list($$, $3);
|
2008-10-26 15:04:09 -06:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
name_list:
|
|
|
|
name
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list1(newname($1->sym));
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| name_list ',' name
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list($1, newname($3->sym));
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
expr_list:
|
|
|
|
expr
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list1($1);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| expr_list ',' expr
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list($1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
expr_or_type_list:
|
|
|
|
expr_or_type
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list1($1);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| expr_or_type_list ',' expr_or_type
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list($1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2009-05-21 14:46:07 -06:00
|
|
|
/*
|
|
|
|
* list of combo of keyval and val
|
|
|
|
*/
|
2009-07-17 02:00:44 -06:00
|
|
|
keyval_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
keyval
|
2009-05-21 14:46:07 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list1($1);
|
2009-05-21 14:46:07 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| expr
|
2008-10-14 18:10:39 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list1($1);
|
2008-10-14 18:10:39 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| keyval_list ',' keyval
|
2008-10-14 18:10:39 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list($1, $3);
|
2008-10-14 18:10:39 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| keyval_list ',' expr
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = list($1, $3);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
braced_keyval_list:
|
2009-06-06 13:46:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2009-06-06 13:46:38 -06:00
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
| keyval_list ocomma
|
2009-06-06 13:46:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = $1;
|
2009-06-06 13:46:38 -06:00
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
/*
|
|
|
|
* optional things
|
|
|
|
*/
|
|
|
|
osemi:
|
|
|
|
| ';'
|
|
|
|
|
|
|
|
ocomma:
|
|
|
|
| ','
|
|
|
|
|
|
|
|
oexpr:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| expr
|
|
|
|
|
|
|
|
oexpr_list:
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
| expr_list
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
oexpr_or_type_list:
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2009-06-06 13:46:38 -06:00
|
|
|
}
|
|
|
|
| expr_or_type_list
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
osimple_stmt:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| simple_stmt
|
|
|
|
|
2008-10-03 17:15:55 -06:00
|
|
|
ohidden_funarg_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| hidden_funarg_list
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-10-03 17:15:55 -06:00
|
|
|
ohidden_structdcl_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| hidden_structdcl_list
|
|
|
|
|
|
|
|
ohidden_interfacedcl_list:
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| hidden_interfacedcl_list
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-10-30 16:13:09 -06:00
|
|
|
oliteral:
|
|
|
|
{
|
|
|
|
$$.ctype = CTxxx;
|
|
|
|
}
|
|
|
|
| LLITERAL
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
/*
|
|
|
|
* import syntax from header of
|
|
|
|
* an output package
|
|
|
|
*/
|
|
|
|
hidden_import:
|
2009-06-06 13:46:38 -06:00
|
|
|
LPACKAGE sym
|
2008-06-04 15:37:38 -06:00
|
|
|
/* variables */
|
2009-01-26 17:57:24 -07:00
|
|
|
| LVAR hidden_pkg_importsym hidden_type
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-01-30 15:39:42 -07:00
|
|
|
importvar($2, $3, PEXTERN);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
2009-01-26 17:57:24 -07:00
|
|
|
| LCONST hidden_pkg_importsym '=' hidden_constant
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-03-12 20:04:38 -06:00
|
|
|
importconst($2, types[TIDEAL], $4);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
2009-01-26 17:57:24 -07:00
|
|
|
| LCONST hidden_pkg_importsym hidden_type '=' hidden_constant
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-03-12 20:04:38 -06:00
|
|
|
importconst($2, $3, $5);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
2009-01-26 17:57:24 -07:00
|
|
|
| LTYPE hidden_pkg_importsym hidden_type
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-01-20 15:40:00 -07:00
|
|
|
importtype($2, $3);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
2009-06-29 16:13:37 -06:00
|
|
|
| LTYPE hidden_pkg_importsym LSTRUCT
|
|
|
|
{
|
|
|
|
importtype($2, typ(TFORWSTRUCT));
|
|
|
|
}
|
|
|
|
| LTYPE hidden_pkg_importsym LINTERFACE
|
|
|
|
{
|
|
|
|
importtype($2, typ(TFORWINTER));
|
|
|
|
}
|
2009-01-26 17:57:24 -07:00
|
|
|
| LFUNC hidden_pkg_importsym '(' ohidden_funarg_list ')' ohidden_funres
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-01-30 15:39:42 -07:00
|
|
|
importvar($2, functype(N, $4, $6), PFUNC);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| LFUNC '(' hidden_funarg_list ')' sym '(' ohidden_funarg_list ')' ohidden_funres
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
if($3->next != nil || $3->n->op != ODCLFIELD) {
|
2008-10-03 17:15:55 -06:00
|
|
|
yyerror("bad receiver in method");
|
|
|
|
YYERROR;
|
|
|
|
}
|
2009-07-17 02:00:44 -06:00
|
|
|
importmethod($5, functype($3->n, $7, $9));
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
hidden_type:
|
|
|
|
hidden_type1
|
|
|
|
| hidden_type2
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-10-03 17:15:55 -06:00
|
|
|
hidden_type1:
|
|
|
|
hidden_importsym
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = pkgtype($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| LNAME
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = oldtype($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| '[' ']' hidden_type
|
|
|
|
{
|
|
|
|
$$ = aindex(N, $3);
|
|
|
|
}
|
|
|
|
| '[' LLITERAL ']' hidden_type
|
|
|
|
{
|
2009-03-12 20:04:38 -06:00
|
|
|
$$ = aindex(nodlit($2), $4);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
|
|
|
| LMAP '[' hidden_type ']' hidden_type
|
|
|
|
{
|
2009-03-04 18:38:37 -07:00
|
|
|
$$ = maptype($3, $5);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
|
|
|
| LSTRUCT '{' ohidden_structdcl_list '}'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = dostruct($3, TSTRUCT);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| LINTERFACE '{' ohidden_interfacedcl_list '}'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = dostruct($3, TINTER);
|
|
|
|
$$ = sortinter($$);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| '*' hidden_type
|
2008-08-27 18:28:30 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = ptrto($2);
|
2008-08-27 18:28:30 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| LCOMM LCHAN hidden_type
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $3;
|
|
|
|
$$->chan = Crecv;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| LCHAN LCOMM hidden_type1
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $3;
|
|
|
|
$$->chan = Csend;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-11-01 17:52:12 -06:00
|
|
|
| LDDD
|
|
|
|
{
|
|
|
|
$$ = typ(TDDD);
|
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
|
|
|
|
hidden_type2:
|
|
|
|
LCHAN hidden_type
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $2;
|
|
|
|
$$->chan = Cboth;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-01-30 15:39:42 -07:00
|
|
|
| LFUNC '(' ohidden_funarg_list ')' ohidden_funres
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = functype(nil, $3, $5);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
|
|
|
|
hidden_dcl:
|
2009-06-06 13:46:38 -06:00
|
|
|
sym hidden_type
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = nod(ODCLFIELD, newname($1), N);
|
|
|
|
$$->type = $2;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
| '?' hidden_type
|
2008-07-12 14:08:53 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
$$ = nod(ODCLFIELD, N, N);
|
|
|
|
$$->type = $2;
|
2008-07-12 14:08:53 -06:00
|
|
|
}
|
2008-10-03 17:15:55 -06:00
|
|
|
|
2008-10-22 14:22:56 -06:00
|
|
|
hidden_structdcl:
|
2009-06-06 13:46:38 -06:00
|
|
|
sym hidden_type oliteral
|
2008-10-22 14:22:56 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(ODCLFIELD, newname($1), typenod($2));
|
2008-10-30 16:25:26 -06:00
|
|
|
$$->val = $3;
|
2008-10-22 14:22:56 -06:00
|
|
|
}
|
2008-10-30 16:29:55 -06:00
|
|
|
| '?' hidden_type oliteral
|
2008-10-22 14:22:56 -06:00
|
|
|
{
|
2008-10-22 18:25:10 -06:00
|
|
|
if(isptr[$2->etype]) {
|
|
|
|
$$ = embedded($2->type->sym);
|
2009-07-14 00:38:39 -06:00
|
|
|
$$->right = nod(OIND, $$->right, N);
|
2008-10-22 18:25:10 -06:00
|
|
|
} else
|
|
|
|
$$ = embedded($2->sym);
|
2008-10-30 16:29:55 -06:00
|
|
|
$$->val = $3;
|
2008-10-22 14:22:56 -06:00
|
|
|
}
|
|
|
|
|
2008-10-03 17:15:55 -06:00
|
|
|
hidden_interfacedcl:
|
2009-06-06 13:46:38 -06:00
|
|
|
sym '(' ohidden_funarg_list ')' ohidden_funres
|
2008-09-14 17:57:55 -06:00
|
|
|
{
|
2009-07-14 00:38:39 -06:00
|
|
|
$$ = nod(ODCLFIELD, newname($1), typenod(functype(fakethis(), $3, $5)));
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
ohidden_funres:
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
$$ = nil;
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
|
|
|
| hidden_funres
|
|
|
|
|
|
|
|
hidden_funres:
|
|
|
|
'(' ohidden_funarg_list ')'
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
| hidden_type1
|
|
|
|
{
|
2009-07-17 02:00:44 -06:00
|
|
|
Node *n;
|
|
|
|
|
|
|
|
n = nod(ODCLFIELD, N, N);
|
|
|
|
n->type = $1;
|
|
|
|
$$ = list1(n);
|
2008-09-14 17:57:55 -06:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-09-26 12:44:20 -06:00
|
|
|
hidden_constant:
|
|
|
|
LLITERAL
|
2009-03-12 20:04:38 -06:00
|
|
|
{
|
|
|
|
$$ = nodlit($1);
|
|
|
|
}
|
2008-09-26 12:44:20 -06:00
|
|
|
| '-' LLITERAL
|
|
|
|
{
|
2009-03-12 20:04:38 -06:00
|
|
|
$$ = nodlit($2);
|
|
|
|
switch($$->val.ctype){
|
2008-09-26 12:44:20 -06:00
|
|
|
case CTINT:
|
2009-03-12 20:04:38 -06:00
|
|
|
mpnegfix($$->val.u.xval);
|
2008-09-26 12:44:20 -06:00
|
|
|
break;
|
|
|
|
case CTFLT:
|
2009-03-12 20:04:38 -06:00
|
|
|
mpnegflt($$->val.u.fval);
|
2008-09-26 12:44:20 -06:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
yyerror("bad negated constant");
|
|
|
|
}
|
|
|
|
}
|
2009-06-06 13:46:38 -06:00
|
|
|
| name
|
2009-01-16 11:45:28 -07:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = $1;
|
|
|
|
if($$->op != OLITERAL)
|
|
|
|
yyerror("bad constant %S", $$->sym);
|
2009-01-16 11:45:28 -07:00
|
|
|
}
|
2008-09-26 12:44:20 -06:00
|
|
|
|
2008-10-03 17:15:55 -06:00
|
|
|
hidden_importsym:
|
2009-06-06 13:46:38 -06:00
|
|
|
sym '.' sym
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-06-06 13:46:38 -06:00
|
|
|
$$ = pkglookup($3->name, $1->name);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-09-18 14:32:14 -06:00
|
|
|
|
2009-01-26 17:57:24 -07:00
|
|
|
hidden_pkg_importsym:
|
|
|
|
hidden_importsym
|
|
|
|
{
|
|
|
|
$$ = $1;
|
2009-06-06 13:46:38 -06:00
|
|
|
structpkg = $$->package;
|
2008-12-16 18:45:28 -07:00
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
hidden_import_list:
|
|
|
|
| hidden_import_list hidden_import
|
|
|
|
|
|
|
|
hidden_funarg_list:
|
|
|
|
hidden_dcl
|
|
|
|
{
|
|
|
|
$$ = list1($1);
|
|
|
|
}
|
|
|
|
| hidden_funarg_list ',' hidden_dcl
|
|
|
|
{
|
|
|
|
$$ = list($1, $3);
|
|
|
|
}
|
|
|
|
|
|
|
|
hidden_structdcl_list:
|
|
|
|
hidden_structdcl
|
|
|
|
{
|
|
|
|
$$ = list1($1);
|
|
|
|
}
|
|
|
|
| hidden_structdcl_list ';' hidden_structdcl
|
|
|
|
{
|
|
|
|
$$ = list($1, $3);
|
|
|
|
}
|
2008-09-18 14:32:14 -06:00
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
hidden_interfacedcl_list:
|
|
|
|
hidden_interfacedcl
|
|
|
|
{
|
|
|
|
$$ = list1($1);
|
|
|
|
}
|
|
|
|
| hidden_interfacedcl_list ';' hidden_interfacedcl
|
|
|
|
{
|
|
|
|
$$ = list($1, $3);
|
|
|
|
}
|