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.
|
|
|
|
|
|
|
|
%{
|
|
|
|
#include "go.h"
|
|
|
|
%}
|
|
|
|
%union {
|
|
|
|
Node* node;
|
|
|
|
Type* type;
|
|
|
|
Sym* sym;
|
|
|
|
struct Val val;
|
|
|
|
int lint;
|
|
|
|
}
|
2008-08-08 18:13:31 -06:00
|
|
|
%token <val> LLITERAL
|
|
|
|
%token <lint> LASOP
|
2008-08-11 20:17:28 -06:00
|
|
|
%token <sym> LNAME LBASETYPE LATYPE LPACK LACONST
|
|
|
|
%token <sym> LPACKAGE LIMPORT LEXPORT
|
|
|
|
%token <sym> LMAP LCHAN LINTERFACE LFUNC LSTRUCT
|
|
|
|
%token <sym> LCOLAS LFALL LRETURN
|
2008-10-02 15:38:07 -06:00
|
|
|
%token <sym> LNEW LLEN LCAP LTYPEOF LPANIC LPANICN LPRINT LPRINTN
|
2008-08-11 20:17:28 -06:00
|
|
|
%token <sym> LVAR LTYPE LCONST LCONVERT LSELECT
|
|
|
|
%token <sym> LFOR LIF LELSE LSWITCH LCASE LDEFAULT
|
|
|
|
%token <sym> LBREAK LCONTINUE LGO LGOTO LRANGE
|
|
|
|
%token <sym> LNIL LTRUE LFALSE LIOTA
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
%token LOROR LANDAND LEQ LNE LLE LLT LGE LGT
|
2008-09-16 20:14:33 -06:00
|
|
|
%token LLSH LRSH LINC LDEC LCOMM
|
2008-08-12 17:36:18 -06:00
|
|
|
%token LIGNORE
|
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
|
|
|
%type <sym> sym sym1 sym2 keyword laconst lname latype lpackatype
|
2008-06-21 16:11:29 -06:00
|
|
|
%type <node> xdcl xdcl_list_r oxdcl_list
|
|
|
|
%type <node> common_dcl Acommon_dcl Bcommon_dcl
|
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
|
|
|
%type <node> oarg_type_list arg_type_list_r arg_chunk arg_chunk_list_r arg_type_list
|
2008-06-17 23:33:32 -06:00
|
|
|
%type <node> else_stmt1 else_stmt2 inc_stmt noninc_stmt
|
2008-06-08 13:48:37 -06:00
|
|
|
%type <node> complex_stmt compound_stmt ostmt_list
|
|
|
|
%type <node> stmt_list_r Astmt_list_r Bstmt_list_r
|
2008-06-17 18:57:31 -06:00
|
|
|
%type <node> Astmt Bstmt Cstmt Dstmt
|
2008-06-04 15:37:38 -06:00
|
|
|
%type <node> for_stmt for_body for_header
|
|
|
|
%type <node> if_stmt if_body if_header
|
2008-07-20 21:13:07 -06:00
|
|
|
%type <node> range_header range_body range_stmt select_stmt
|
2008-06-08 13:48:37 -06:00
|
|
|
%type <node> simple_stmt osimple_stmt semi_stmt
|
2008-06-04 15:37:38 -06:00
|
|
|
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
|
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
|
|
|
%type <node> name onew_name new_name new_name_list_r
|
2008-06-21 16:11:29 -06:00
|
|
|
%type <node> vardcl_list_r vardcl Avardcl Bvardcl
|
2008-06-04 15:37:38 -06:00
|
|
|
%type <node> interfacedcl_list_r interfacedcl
|
|
|
|
%type <node> structdcl_list_r structdcl
|
|
|
|
%type <node> hidden_importsym_list_r ohidden_importsym_list hidden_importsym isym
|
|
|
|
%type <node> hidden_importfield_list_r ohidden_importfield_list hidden_importfield
|
2008-07-05 13:49:25 -06:00
|
|
|
%type <node> fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody
|
2008-09-03 15:09:29 -06:00
|
|
|
%type <node> keyexpr_list keyval_list_r keyval
|
2008-06-21 16:11:29 -06:00
|
|
|
%type <node> typedcl Atypedcl Btypedcl
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
%type <type> fntype fnlitdcl Afntype Bfntype fullAtype
|
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
|
|
|
%type <type> non_name_Atype non_name_type
|
2008-09-05 20:50:34 -06:00
|
|
|
%type <type> type Atype Btype indcl new_type fullBtype
|
|
|
|
%type <type> structtype interfacetype convtype
|
2008-09-16 20:14:33 -06:00
|
|
|
%type <type> Achantype Bchantype
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-09-26 12:44:20 -06:00
|
|
|
%type <val> hidden_constant
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
%left LOROR
|
|
|
|
%left LANDAND
|
2008-09-16 20:14:33 -06:00
|
|
|
%left LCOMM
|
2008-06-04 15:37:38 -06:00
|
|
|
%left LEQ LNE LLE LGE LLT LGT
|
|
|
|
%left '+' '-' '|' '^'
|
|
|
|
%left '*' '/' '%' '&' LLSH LRSH
|
|
|
|
%%
|
|
|
|
file:
|
|
|
|
package import_there imports oxdcl_list
|
|
|
|
{
|
|
|
|
if(debug['f'])
|
|
|
|
frame(1);
|
2008-07-19 14:38:29 -06:00
|
|
|
fninit($4);
|
2008-06-04 15:37:38 -06:00
|
|
|
testdclstack();
|
|
|
|
}
|
|
|
|
|
|
|
|
package:
|
|
|
|
{
|
|
|
|
yyerror("package statement must be first");
|
|
|
|
mkpackage("main");
|
|
|
|
cannedimports();
|
|
|
|
}
|
|
|
|
| LPACKAGE sym
|
|
|
|
{
|
|
|
|
mkpackage($2->name);
|
|
|
|
cannedimports();
|
|
|
|
}
|
|
|
|
|
|
|
|
imports:
|
|
|
|
| imports import
|
|
|
|
|
|
|
|
import:
|
|
|
|
LIMPORT import_stmt
|
|
|
|
| LIMPORT '(' import_stmt_list_r osemi ')'
|
|
|
|
|
|
|
|
import_stmt:
|
2008-06-12 22:48:56 -06:00
|
|
|
import_here import_package import_there
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
import_here:
|
|
|
|
LLITERAL
|
|
|
|
{
|
|
|
|
// import with original name
|
|
|
|
pkgmyname = S;
|
|
|
|
importfile(&$1);
|
|
|
|
}
|
|
|
|
| sym LLITERAL
|
|
|
|
{
|
|
|
|
// import with given name
|
|
|
|
pkgmyname = $1;
|
|
|
|
pkgmyname->lexical = LPACK;
|
|
|
|
importfile(&$2);
|
|
|
|
}
|
|
|
|
| '.' LLITERAL
|
|
|
|
{
|
|
|
|
// import with my name
|
|
|
|
pkgmyname = lookup(package);
|
|
|
|
importfile(&$2);
|
|
|
|
}
|
|
|
|
|
2008-06-12 22:48:56 -06:00
|
|
|
import_package:
|
|
|
|
LPACKAGE sym
|
|
|
|
{
|
|
|
|
pkgimportname = $2;
|
|
|
|
|
|
|
|
// if we are not remapping the package name
|
|
|
|
// then the imported package name is LPACK
|
|
|
|
if(pkgmyname == S)
|
|
|
|
pkgimportname->lexical = LPACK;
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
import_there:
|
|
|
|
hidden_import_list_r ')' ')'
|
|
|
|
{
|
2008-09-24 15:12:21 -06:00
|
|
|
checkimports();
|
2008-06-04 15:37:38 -06:00
|
|
|
unimportfile();
|
|
|
|
}
|
|
|
|
| LIMPORT '(' '(' hidden_import_list_r ')' ')'
|
2008-09-24 15:12:21 -06:00
|
|
|
{
|
|
|
|
checkimports();
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* declarations
|
|
|
|
*/
|
|
|
|
xdcl:
|
|
|
|
common_dcl
|
2008-08-04 14:18:59 -06:00
|
|
|
| xfndcl
|
2008-08-03 19:47:02 -06:00
|
|
|
{
|
2008-08-04 14:18:59 -06:00
|
|
|
$$ = N;
|
2008-08-03 19:47:02 -06:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| LEXPORT export_list_r
|
|
|
|
{
|
2008-07-19 14:38:29 -06:00
|
|
|
$$ = N;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-08-04 14:18:59 -06:00
|
|
|
| LEXPORT { exportadj = 1; } common_dcl
|
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
exportadj = 0;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| LEXPORT '(' export_list_r ')'
|
|
|
|
{
|
2008-07-19 14:38:29 -06:00
|
|
|
$$ = N;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-08-04 14:18:59 -06:00
|
|
|
| LEXPORT xfndcl
|
2008-07-19 14:38:29 -06:00
|
|
|
{
|
2008-08-04 14:18:59 -06:00
|
|
|
if($2 != N && $2->nname != N)
|
|
|
|
exportsym($2->nname->sym);
|
2008-07-19 14:38:29 -06:00
|
|
|
$$ = N;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| ';'
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
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:
|
2008-06-21 16:11:29 -06:00
|
|
|
Acommon_dcl
|
|
|
|
| Bcommon_dcl
|
|
|
|
|
|
|
|
Acommon_dcl:
|
|
|
|
LVAR Avardcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
| LVAR '(' vardcl_list_r osemi ')'
|
|
|
|
{
|
|
|
|
$$ = rev($3);
|
|
|
|
}
|
2008-09-04 13:21:10 -06:00
|
|
|
| LCONST '(' constdcl osemi ')'
|
|
|
|
{
|
|
|
|
iota = 0;
|
|
|
|
lastconst = N;
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| LCONST '(' constdcl ';' constdcl_list_r osemi ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
iota = 0;
|
2008-07-03 17:41:32 -06:00
|
|
|
lastconst = N;
|
2008-07-19 14:38:29 -06:00
|
|
|
$$ = N;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-06-21 16:11:29 -06:00
|
|
|
| LTYPE Atypedcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
2008-06-21 16:11:29 -06:00
|
|
|
| LTYPE '(' typedcl_list_r osemi ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
2008-06-21 16:11:29 -06:00
|
|
|
|
|
|
|
Bcommon_dcl:
|
|
|
|
LVAR Bvardcl
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
| LCONST constdcl
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
iota = 0;
|
2008-07-03 17:41:32 -06:00
|
|
|
lastconst = N;
|
2008-06-21 16:11:29 -06:00
|
|
|
}
|
|
|
|
| LTYPE Btypedcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
|
|
|
|
vardcl:
|
2008-06-21 16:11:29 -06:00
|
|
|
Avardcl
|
|
|
|
| Bvardcl
|
|
|
|
|
|
|
|
Avardcl:
|
2008-09-05 20:50:34 -06:00
|
|
|
new_name_list_r fullAtype
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
dodclvar($$, $2);
|
|
|
|
|
|
|
|
$$ = nod(OAS, $$, N);
|
|
|
|
}
|
|
|
|
|
|
|
|
Bvardcl:
|
2008-09-05 20:50:34 -06:00
|
|
|
new_name_list_r fullBtype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
dodclvar($$, $2);
|
|
|
|
|
|
|
|
$$ = nod(OAS, $$, N);
|
|
|
|
}
|
2008-09-04 13:21:10 -06:00
|
|
|
| new_name_list_r type '=' expr_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
dodclvar($$, $2);
|
|
|
|
|
|
|
|
$$ = nod(OAS, $$, $4);
|
2008-09-14 18:29:50 -06:00
|
|
|
addtotop($$);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
| new_name '=' expr
|
|
|
|
{
|
2008-09-14 18:29:50 -06:00
|
|
|
$$ = nod(OAS, $1, N);
|
|
|
|
gettype($3, $$);
|
2008-06-04 15:37:38 -06:00
|
|
|
defaultlit($3);
|
|
|
|
dodclvar($1, $3->type);
|
2008-09-14 18:29:50 -06:00
|
|
|
$$->right = $3;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
constdcl:
|
2008-09-04 13:21:10 -06:00
|
|
|
new_name type '=' expr
|
2008-07-03 17:41:32 -06:00
|
|
|
{
|
2008-09-04 13:21:10 -06:00
|
|
|
Node *c = treecopy($4);
|
2008-09-14 18:29:50 -06:00
|
|
|
gettype(c, N);
|
2008-09-04 13:21:10 -06:00
|
|
|
convlit(c, $2);
|
|
|
|
dodclconst($1, c);
|
|
|
|
|
|
|
|
lastconst = $4;
|
|
|
|
iota += 1;
|
2008-07-03 17:41:32 -06:00
|
|
|
}
|
2008-09-04 13:21:10 -06:00
|
|
|
| new_name '=' expr
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-09-04 13:21:10 -06:00
|
|
|
Node *c = treecopy($3);
|
2008-09-14 18:29:50 -06:00
|
|
|
gettype(c, N);
|
2008-09-04 13:21:10 -06:00
|
|
|
dodclconst($1, c);
|
|
|
|
|
|
|
|
lastconst = $3;
|
|
|
|
iota += 1;
|
2008-07-03 17:41:32 -06:00
|
|
|
}
|
|
|
|
|
2008-09-04 13:21:10 -06:00
|
|
|
constdcl1:
|
|
|
|
constdcl
|
|
|
|
| new_name type
|
2008-07-03 17:41:32 -06:00
|
|
|
{
|
2008-09-04 13:21:10 -06:00
|
|
|
Node *c = treecopy(lastconst);
|
2008-09-14 18:29:50 -06:00
|
|
|
gettype(c, N);
|
2008-09-04 13:21:10 -06:00
|
|
|
convlit(c, $2);
|
|
|
|
dodclconst($1, c);
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
iota += 1;
|
|
|
|
}
|
2008-09-04 13:21:10 -06:00
|
|
|
| new_name
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-09-04 13:21:10 -06:00
|
|
|
Node *c = treecopy(lastconst);
|
2008-09-14 18:29:50 -06:00
|
|
|
gettype(c, N);
|
2008-09-04 13:21:10 -06:00
|
|
|
dodclconst($1, c);
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
iota += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedcl:
|
2008-06-21 16:11:29 -06:00
|
|
|
Atypedcl
|
|
|
|
| Btypedcl
|
|
|
|
|
|
|
|
Atypedcl:
|
2008-09-05 20:50:34 -06:00
|
|
|
new_type fullAtype
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
|
|
|
dodcltype($1, $2);
|
|
|
|
}
|
|
|
|
|
|
|
|
Btypedcl:
|
2008-09-05 20:50:34 -06:00
|
|
|
new_type fullBtype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
dodcltype($1, $2);
|
|
|
|
}
|
|
|
|
|
2008-06-08 13:48:37 -06:00
|
|
|
else_stmt1:
|
|
|
|
complex_stmt
|
2008-06-04 15:37:38 -06:00
|
|
|
| compound_stmt
|
|
|
|
|
2008-06-08 13:48:37 -06:00
|
|
|
else_stmt2:
|
|
|
|
simple_stmt
|
|
|
|
| semi_stmt
|
|
|
|
| ';'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-06-08 13:48:37 -06:00
|
|
|
$$ = N;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
simple_stmt:
|
2008-06-17 23:33:32 -06:00
|
|
|
inc_stmt
|
|
|
|
| noninc_stmt
|
|
|
|
|
|
|
|
noninc_stmt:
|
2008-06-04 15:37:38 -06:00
|
|
|
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
|
|
|
}
|
|
|
|
| expr_list '=' expr_list
|
|
|
|
{
|
|
|
|
$$ = nod(OAS, $1, $3);
|
|
|
|
}
|
2008-06-21 16:11:29 -06:00
|
|
|
| expr_list LCOLAS expr_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-06-21 16:11:29 -06:00
|
|
|
$$ = nod(OAS, colas($1, $3), $3);
|
2008-09-09 16:47:31 -06:00
|
|
|
addtotop($$);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-08-29 21:30:19 -06:00
|
|
|
| LPRINT '(' oexpr_list ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OPRINT, $3, N);
|
|
|
|
}
|
2008-10-02 15:38:07 -06:00
|
|
|
| LPRINTN '(' oexpr_list ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OPRINTN, $3, N);
|
|
|
|
}
|
2008-08-29 21:30:19 -06:00
|
|
|
| LPANIC '(' oexpr_list ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OPANIC, $3, N);
|
|
|
|
}
|
2008-10-02 15:38:07 -06:00
|
|
|
| LPANICN '(' oexpr_list ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OPANICN, $3, N);
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-06-17 23:33:32 -06:00
|
|
|
inc_stmt:
|
|
|
|
expr LINC
|
|
|
|
{
|
|
|
|
$$ = nod(OASOP, $1, literal(1));
|
|
|
|
$$->etype = OADD;
|
|
|
|
}
|
|
|
|
| expr LDEC
|
|
|
|
{
|
|
|
|
$$ = nod(OASOP, $1, literal(1));
|
|
|
|
$$->etype = OSUB;
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
complex_stmt:
|
|
|
|
LFOR for_stmt
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
| LSWITCH if_stmt
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = $2;
|
|
|
|
$$->op = OSWITCH;
|
|
|
|
}
|
|
|
|
| LIF if_stmt
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = $2;
|
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
| LIF if_stmt LELSE else_stmt1
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = $2;
|
|
|
|
$$->nelse = $4;
|
|
|
|
}
|
2008-07-20 21:13:07 -06:00
|
|
|
| LSELECT select_stmt
|
|
|
|
{
|
|
|
|
popdcl();
|
|
|
|
$$ = $2;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| LRANGE range_stmt
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
| LCASE expr_list ':'
|
|
|
|
{
|
|
|
|
// will be converted to OCASE
|
|
|
|
// right will point to next case
|
|
|
|
// done in casebody()
|
|
|
|
poptodcl();
|
|
|
|
$$ = nod(OXCASE, $2, N);
|
|
|
|
}
|
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();
|
|
|
|
$$ = nod(OAS, $2, $4);
|
|
|
|
$$ = nod(OXCASE, $$, N);
|
|
|
|
}
|
|
|
|
| LCASE name LCOLAS expr ':'
|
|
|
|
{
|
|
|
|
// will be converted to OCASE
|
|
|
|
// right will point to next case
|
|
|
|
// done in casebody()
|
|
|
|
poptodcl();
|
2008-09-16 21:51:50 -06:00
|
|
|
$$ = nod(OAS, selectas($2,$4), $4);
|
2008-09-16 20:14:33 -06:00
|
|
|
$$ = nod(OXCASE, $$, N);
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| LDEFAULT ':'
|
|
|
|
{
|
|
|
|
poptodcl();
|
|
|
|
$$ = nod(OXCASE, N, N);
|
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
|
|
|
|
semi_stmt:
|
|
|
|
LFALL
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
// will be converted to OFALL
|
|
|
|
$$ = nod(OXFALL, N, N);
|
|
|
|
}
|
2008-08-29 21:30:19 -06:00
|
|
|
| LBREAK onew_name
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OBREAK, $2, N);
|
|
|
|
}
|
2008-08-29 21:30:19 -06:00
|
|
|
| LCONTINUE onew_name
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OCONTINUE, $2, N);
|
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
| LGO pexpr '(' oexpr_list ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-07-07 13:29:26 -06:00
|
|
|
$$ = nod(OCALL, $2, $4);
|
|
|
|
$$ = nod(OPROC, $$, N);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
| LGOTO new_name
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OGOTO, $2, N);
|
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
| LRETURN oexpr_list
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-06-08 13:48:37 -06:00
|
|
|
$$ = nod(ORETURN, $2, N);
|
|
|
|
}
|
|
|
|
| LIF if_stmt LELSE else_stmt2
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2008-06-08 13:48:37 -06:00
|
|
|
$$ = $2;
|
|
|
|
$$->nelse = $4;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
compound_stmt:
|
|
|
|
'{'
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
markdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
} ostmt_list '}'
|
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
if($$ == N)
|
|
|
|
$$ = nod(OEMPTY, N, N);
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
for_header:
|
|
|
|
osimple_stmt ';' osimple_stmt ';' osimple_stmt
|
|
|
|
{
|
|
|
|
// init ; test ; incr
|
|
|
|
$$ = nod(OFOR, N, N);
|
|
|
|
$$->ninit = $1;
|
|
|
|
$$->ntest = $3;
|
|
|
|
$$->nincr = $5;
|
|
|
|
}
|
|
|
|
| osimple_stmt
|
|
|
|
{
|
|
|
|
// test
|
|
|
|
$$ = nod(OFOR, N, N);
|
|
|
|
$$->ninit = N;
|
|
|
|
$$->ntest = $1;
|
|
|
|
$$->nincr = N;
|
|
|
|
}
|
|
|
|
|
|
|
|
for_body:
|
|
|
|
for_header compound_stmt
|
|
|
|
{
|
|
|
|
$$ = $1;
|
|
|
|
$$->nbody = $2;
|
|
|
|
}
|
|
|
|
|
|
|
|
for_stmt:
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
markdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
} for_body
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if_header:
|
|
|
|
osimple_stmt
|
|
|
|
{
|
|
|
|
// test
|
|
|
|
$$ = nod(OIF, N, N);
|
|
|
|
$$->ninit = N;
|
|
|
|
$$->ntest = $1;
|
|
|
|
}
|
|
|
|
| osimple_stmt ';' osimple_stmt
|
|
|
|
{
|
|
|
|
// init ; test
|
|
|
|
$$ = nod(OIF, N, N);
|
|
|
|
$$->ninit = $1;
|
|
|
|
$$->ntest = $3;
|
|
|
|
}
|
|
|
|
|
|
|
|
if_body:
|
|
|
|
if_header compound_stmt
|
|
|
|
{
|
|
|
|
$$ = $1;
|
|
|
|
$$->nbody = $2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if_stmt:
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
markdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
} if_body
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
|
|
|
|
range_header:
|
|
|
|
new_name LCOLAS expr
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| new_name ',' new_name LCOLAS expr
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| new_name ',' new_name '=' expr
|
|
|
|
{
|
|
|
|
yyerror("range statement only allows := assignment");
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
|
|
|
|
range_body:
|
|
|
|
range_header compound_stmt
|
|
|
|
{
|
|
|
|
$$ = $1;
|
|
|
|
$$->nbody = $2;
|
|
|
|
}
|
|
|
|
|
|
|
|
range_stmt:
|
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
markdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
} range_body
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
|
2008-07-20 21:13:07 -06:00
|
|
|
select_stmt:
|
|
|
|
{
|
|
|
|
markdcl();
|
|
|
|
}
|
|
|
|
compound_stmt
|
|
|
|
{
|
|
|
|
$$ = nod(OSELECT, $2, N);
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
| 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
pexpr:
|
|
|
|
LLITERAL
|
|
|
|
{
|
|
|
|
$$ = nod(OLITERAL, N, N);
|
|
|
|
$$->val = $1;
|
|
|
|
}
|
|
|
|
| laconst
|
|
|
|
{
|
|
|
|
$$ = nod(OLITERAL, N, N);
|
|
|
|
$$->val = $1->oconst->val;
|
|
|
|
$$->type = $1->oconst->type;
|
|
|
|
}
|
|
|
|
| LNIL
|
|
|
|
{
|
|
|
|
$$ = nod(OLITERAL, N, N);
|
|
|
|
$$->val.ctype = CTNIL;
|
|
|
|
}
|
|
|
|
| LTRUE
|
|
|
|
{
|
|
|
|
$$ = booltrue;
|
|
|
|
}
|
|
|
|
| LFALSE
|
|
|
|
{
|
|
|
|
$$ = boolfalse;
|
|
|
|
}
|
|
|
|
| LIOTA
|
|
|
|
{
|
|
|
|
$$ = literal(iota);
|
2008-07-03 17:41:32 -06:00
|
|
|
$$->iota = 1; // flag to reevaluate on copy
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
| name
|
|
|
|
| '(' expr ')'
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
2008-08-12 15:04:03 -06:00
|
|
|
| pexpr '.' sym2
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(ODOT, $1, newname($3));
|
|
|
|
}
|
|
|
|
| pexpr '.' '(' type ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OCONV, $1, N);
|
|
|
|
$$->type = $4;
|
|
|
|
}
|
|
|
|
| pexpr '[' expr ']'
|
|
|
|
{
|
|
|
|
$$ = nod(OINDEX, $1, $3);
|
|
|
|
}
|
|
|
|
| pexpr '[' keyval ']'
|
|
|
|
{
|
|
|
|
$$ = nod(OSLICE, $1, $3);
|
|
|
|
}
|
|
|
|
| pexpr '(' oexpr_list ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OCALL, $1, $3);
|
|
|
|
}
|
2008-07-28 14:54:58 -06:00
|
|
|
| LLEN '(' expr ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OLEN, $3, N);
|
|
|
|
}
|
2008-08-27 18:28:30 -06:00
|
|
|
| LCAP '(' expr ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OCAP, $3, N);
|
|
|
|
}
|
2008-08-12 17:36:18 -06:00
|
|
|
| LTYPEOF '(' type ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OTYPEOF, N, N);
|
|
|
|
$$->type = $3;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| LNEW '(' type ')'
|
|
|
|
{
|
|
|
|
$$ = nod(ONEW, N, N);
|
|
|
|
$$->type = ptrto($3);
|
|
|
|
}
|
2008-07-14 18:41:38 -06:00
|
|
|
| LNEW '(' type ',' expr_list ')'
|
|
|
|
{
|
|
|
|
$$ = nod(ONEW, $5, N);
|
|
|
|
$$->type = ptrto($3);
|
|
|
|
}
|
2008-09-03 15:09:29 -06:00
|
|
|
| LCONVERT '(' type ',' keyexpr_list ')'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OCONV, $5, N);
|
|
|
|
$$->type = $3;
|
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| latype '(' expr ')'
|
|
|
|
{
|
|
|
|
$$ = nod(OCONV, $3, N);
|
|
|
|
$$->type = oldtype($1);
|
|
|
|
}
|
|
|
|
| convtype '{' keyexpr_list '}'
|
|
|
|
{
|
2008-09-29 21:33:51 -06:00
|
|
|
// composite literal
|
|
|
|
$$ = rev($3);
|
|
|
|
if($$ == N)
|
|
|
|
$$ = nod(OEMPTY, N, N);
|
|
|
|
$$ = nod(OCONV, $$, N);
|
2008-09-05 20:50:34 -06:00
|
|
|
$$->type = $1;
|
|
|
|
}
|
|
|
|
| fnliteral
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* lexical symbols that can be
|
|
|
|
* from other packages
|
|
|
|
*/
|
|
|
|
lpack:
|
2008-07-27 14:09:15 -06:00
|
|
|
LPACK
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
context = $1->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
laconst:
|
|
|
|
LACONST
|
|
|
|
| lpack '.' LACONST
|
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
context = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
lname:
|
|
|
|
LNAME
|
|
|
|
| lpack '.' LNAME
|
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
context = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
latype:
|
|
|
|
LATYPE
|
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
|
|
|
| lpackatype
|
|
|
|
|
|
|
|
lpackatype:
|
|
|
|
lpack '.' LATYPE
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = $3;
|
|
|
|
context = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* names and types
|
|
|
|
* newname is used before declared
|
|
|
|
* oldname is used after declared
|
|
|
|
*/
|
|
|
|
new_name:
|
2008-08-12 15:04:03 -06:00
|
|
|
sym1
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = newname($1);
|
|
|
|
}
|
|
|
|
|
|
|
|
new_type:
|
2008-08-12 15:04:03 -06:00
|
|
|
sym1
|
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:
|
|
|
|
LATYPE
|
|
|
|
| LNAME
|
|
|
|
| LACONST
|
|
|
|
| LPACK
|
|
|
|
|
2008-08-11 20:17:28 -06:00
|
|
|
sym1:
|
|
|
|
sym
|
2008-09-03 15:09:29 -06:00
|
|
|
| keyword
|
2008-08-11 20:17:28 -06:00
|
|
|
|
|
|
|
sym2:
|
|
|
|
sym
|
2008-09-03 15:09:29 -06:00
|
|
|
| keyword
|
2008-08-11 20:17:28 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* keywords that we can
|
2008-08-12 15:28:58 -06:00
|
|
|
* use as variable/type names
|
2008-08-11 20:17:28 -06:00
|
|
|
*/
|
2008-09-03 15:09:29 -06:00
|
|
|
keyword:
|
2008-08-12 15:04:03 -06:00
|
|
|
LNIL
|
|
|
|
| LTRUE
|
|
|
|
| LFALSE
|
|
|
|
| LIOTA
|
|
|
|
| LLEN
|
2008-08-27 18:28:30 -06:00
|
|
|
| LCAP
|
2008-08-12 15:04:03 -06:00
|
|
|
| LPANIC
|
2008-10-02 15:38:07 -06:00
|
|
|
| LPANICN
|
2008-08-12 15:04:03 -06:00
|
|
|
| LPRINT
|
2008-10-02 15:38:07 -06:00
|
|
|
| LPRINTN
|
2008-08-12 15:04:03 -06:00
|
|
|
| LNEW
|
|
|
|
| LBASETYPE
|
2008-08-12 17:36:18 -06:00
|
|
|
| LTYPEOF
|
2008-08-11 20:17:28 -06:00
|
|
|
| LCONVERT
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
name:
|
|
|
|
lname
|
|
|
|
{
|
|
|
|
$$ = oldname($1);
|
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
convtype:
|
2008-06-08 13:48:37 -06:00
|
|
|
latype
|
|
|
|
{
|
|
|
|
$$ = oldtype($1);
|
|
|
|
}
|
2008-09-03 15:09:29 -06:00
|
|
|
| '[' oexpr ']' type
|
2008-06-08 13:48:37 -06:00
|
|
|
{
|
2008-09-03 15:09:29 -06:00
|
|
|
// array literal
|
|
|
|
$$ = aindex($2, $4);
|
2008-06-08 13:48:37 -06:00
|
|
|
}
|
2008-09-03 15:09:29 -06:00
|
|
|
| LMAP '[' type ']' type
|
2008-06-08 13:48:37 -06:00
|
|
|
{
|
2008-09-03 15:09:29 -06:00
|
|
|
// map literal
|
2008-06-08 13:48:37 -06:00
|
|
|
$$ = typ(TMAP);
|
|
|
|
$$->down = $3;
|
|
|
|
$$->type = $5;
|
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| structtype
|
2008-06-08 13:48:37 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
type:
|
2008-09-05 20:50:34 -06:00
|
|
|
fullAtype
|
|
|
|
| fullBtype
|
2008-06-21 16:11:29 -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
|
|
|
non_name_type:
|
|
|
|
non_name_Atype
|
|
|
|
| Afntype
|
|
|
|
| Achantype
|
|
|
|
| fullBtype
|
|
|
|
|
2008-06-21 16:11:29 -06:00
|
|
|
Atype:
|
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
|
|
|
LATYPE
|
|
|
|
{
|
|
|
|
$$ = oldtype($1);
|
|
|
|
}
|
|
|
|
| non_name_Atype
|
|
|
|
|
|
|
|
non_name_Atype:
|
|
|
|
lpackatype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = oldtype($1);
|
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| '[' oexpr ']' fullAtype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = aindex($2, $4);
|
|
|
|
}
|
2008-09-16 20:14:33 -06:00
|
|
|
| LCOMM LCHAN fullAtype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $3;
|
2008-09-16 20:14:33 -06:00
|
|
|
$$->chan = Crecv;
|
|
|
|
}
|
2008-09-17 15:09:44 -06:00
|
|
|
| LCHAN LCOMM Atype /* not full Atype */
|
2008-09-16 20:14:33 -06:00
|
|
|
{
|
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $3;
|
|
|
|
$$->chan = Csend;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| LMAP '[' type ']' fullAtype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = typ(TMAP);
|
|
|
|
$$->down = $3;
|
|
|
|
$$->type = $5;
|
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| structtype
|
|
|
|
| interfacetype
|
|
|
|
| '*' fullAtype
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
2008-09-01 15:37:32 -06:00
|
|
|
dowidth($2);
|
2008-06-21 16:11:29 -06:00
|
|
|
$$ = ptrto($2);
|
|
|
|
}
|
|
|
|
|
2008-09-16 20:14:33 -06:00
|
|
|
Achantype:
|
|
|
|
LCHAN fullAtype
|
|
|
|
{
|
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $2;
|
|
|
|
$$->chan = Cboth;
|
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
fullAtype:
|
|
|
|
Atype
|
|
|
|
| Afntype
|
2008-09-16 20:14:33 -06:00
|
|
|
| Achantype
|
2008-09-05 20:50:34 -06:00
|
|
|
|
2008-06-21 16:11:29 -06:00
|
|
|
Btype:
|
2008-09-05 20:50:34 -06:00
|
|
|
'[' oexpr ']' fullBtype
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
|
|
|
$$ = aindex($2, $4);
|
|
|
|
}
|
2008-09-16 20:14:33 -06:00
|
|
|
| LCOMM LCHAN fullBtype
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $3;
|
2008-09-16 20:14:33 -06:00
|
|
|
$$->chan = Crecv;
|
|
|
|
}
|
|
|
|
| LCHAN LCOMM Btype // not full Btype
|
|
|
|
{
|
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $3;
|
|
|
|
$$->chan = Csend;
|
2008-06-21 16:11:29 -06:00
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| LMAP '[' type ']' fullBtype
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
|
|
|
$$ = typ(TMAP);
|
|
|
|
$$->down = $3;
|
|
|
|
$$->type = $5;
|
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| '*' fullBtype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-09-01 15:37:32 -06:00
|
|
|
dowidth($2);
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = ptrto($2);
|
|
|
|
}
|
|
|
|
| '*' lname
|
|
|
|
{
|
|
|
|
// dont know if this is an error or not
|
|
|
|
if(dclcontext != PEXTERN)
|
2008-06-27 11:29:02 -06:00
|
|
|
yyerror("forward type in function body %s", $2->name);
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = forwdcl($2);
|
|
|
|
}
|
|
|
|
|
2008-09-16 20:14:33 -06:00
|
|
|
Bchantype:
|
|
|
|
LCHAN fullBtype
|
|
|
|
{
|
|
|
|
$$ = typ(TCHAN);
|
|
|
|
$$->type = $2;
|
|
|
|
$$->chan = Cboth;
|
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
fullBtype:
|
|
|
|
Btype
|
|
|
|
| Bfntype
|
2008-09-16 20:14:33 -06:00
|
|
|
| Bchantype
|
2008-09-05 20:50:34 -06:00
|
|
|
|
|
|
|
structtype:
|
|
|
|
LSTRUCT '{' structdcl_list_r osemi '}'
|
|
|
|
{
|
|
|
|
$$ = dostruct(rev($3), TSTRUCT);
|
|
|
|
}
|
|
|
|
| LSTRUCT '{' '}'
|
|
|
|
{
|
|
|
|
$$ = dostruct(N, TSTRUCT);
|
|
|
|
}
|
|
|
|
|
|
|
|
interfacetype:
|
|
|
|
LINTERFACE '{' interfacedcl_list_r osemi '}'
|
|
|
|
{
|
|
|
|
$$ = dostruct(rev($3), TINTER);
|
|
|
|
$$ = sortinter($$);
|
|
|
|
}
|
|
|
|
| LINTERFACE '{' '}'
|
|
|
|
{
|
|
|
|
$$ = dostruct(N, TINTER);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
2008-07-19 19:39:12 -06:00
|
|
|
if($3 == N && $5 == N)
|
|
|
|
$$->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
|
|
|
|
{
|
|
|
|
b0stack = dclstack; // mark base for fn literals
|
|
|
|
$$ = nod(ODCLFUNC, N, N);
|
|
|
|
$$->nname = methodname($4, $2->type);
|
|
|
|
$$->type = functype($2, $6, $8);
|
|
|
|
funchdr($$);
|
2008-09-14 17:57:55 -06:00
|
|
|
|
|
|
|
addmethod($4, $$->type, 1);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
fntype:
|
|
|
|
Afntype
|
|
|
|
| Bfntype
|
2008-06-21 16:11:29 -06:00
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
Afntype:
|
|
|
|
'(' oarg_type_list ')' Afnres
|
2008-06-21 16:11:29 -06:00
|
|
|
{
|
2008-09-05 20:50:34 -06:00
|
|
|
$$ = functype(N, $2, $4);
|
2008-06-21 16:11:29 -06:00
|
|
|
funcnam($$, nil);
|
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
Bfntype:
|
|
|
|
'(' oarg_type_list ')' Bfnres
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-09-05 20:50:34 -06:00
|
|
|
$$ = functype(N, $2, $4);
|
2008-06-04 15:37:38 -06:00
|
|
|
funcnam($$, nil);
|
|
|
|
}
|
|
|
|
|
|
|
|
fnlitdcl:
|
|
|
|
fntype
|
|
|
|
{
|
|
|
|
markdclstack(); // save dcl stack and revert to block0
|
|
|
|
$$ = $1;
|
|
|
|
funcargs($$);
|
|
|
|
}
|
|
|
|
|
|
|
|
fnliteral:
|
2008-09-05 20:50:34 -06:00
|
|
|
LFUNC fnlitdcl '{' ostmt_list '}'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
popdcl();
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
vargen++;
|
|
|
|
snprint(namebuf, sizeof(namebuf), "_f%.3ld", vargen);
|
|
|
|
|
|
|
|
$$ = newname(lookup(namebuf));
|
2008-09-05 20:50:34 -06:00
|
|
|
addvar($$, $2, PEXTERN);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
{
|
|
|
|
Node *n;
|
|
|
|
|
|
|
|
n = nod(ODCLFUNC, N, N);
|
|
|
|
n->nname = $$;
|
2008-09-05 20:50:34 -06:00
|
|
|
n->type = $2;
|
|
|
|
n->nbody = $4;
|
2008-06-04 15:37:38 -06:00
|
|
|
if(n->nbody == N)
|
|
|
|
n->nbody = nod(ORETURN, N, N);
|
|
|
|
compile(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
$$ = nod(OADDR, $$, N);
|
|
|
|
}
|
|
|
|
|
|
|
|
fnbody:
|
2008-07-05 13:49:25 -06:00
|
|
|
'{' ostmt_list '}'
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-07-05 13:49:25 -06:00
|
|
|
$$ = $2;
|
|
|
|
if($$ == N)
|
2008-06-04 15:37:38 -06:00
|
|
|
$$ = nod(ORETURN, N, N);
|
|
|
|
}
|
|
|
|
| ';'
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
2008-07-05 13:49:25 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
fnres:
|
2008-06-21 16:11:29 -06:00
|
|
|
Afnres
|
|
|
|
| Bfnres
|
|
|
|
|
|
|
|
Afnres:
|
|
|
|
Atype
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(ODCLFIELD, N, N);
|
|
|
|
$$->type = $1;
|
|
|
|
$$ = cleanidlist($$);
|
|
|
|
}
|
|
|
|
| '(' oarg_type_list ')'
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
}
|
|
|
|
|
2008-06-21 16:11:29 -06:00
|
|
|
Bfnres:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| Btype
|
|
|
|
{
|
|
|
|
$$ = nod(ODCLFIELD, N, N);
|
|
|
|
$$->type = $1;
|
|
|
|
$$ = cleanidlist($$);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
xdcl_list_r:
|
|
|
|
xdcl
|
|
|
|
| xdcl_list_r xdcl
|
|
|
|
{
|
2008-07-19 14:38:29 -06:00
|
|
|
$$ = list($1, $2);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
vardcl_list_r:
|
|
|
|
vardcl
|
|
|
|
| vardcl_list_r ';' vardcl
|
|
|
|
{
|
|
|
|
$$ = nod(OLIST, $1, $3);
|
|
|
|
}
|
|
|
|
|
|
|
|
constdcl_list_r:
|
2008-09-04 13:21:10 -06:00
|
|
|
constdcl1
|
|
|
|
| constdcl_list_r ';' constdcl1
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
typedcl_list_r:
|
|
|
|
typedcl
|
|
|
|
| typedcl_list_r ';' typedcl
|
|
|
|
|
|
|
|
structdcl_list_r:
|
|
|
|
structdcl
|
|
|
|
{
|
|
|
|
$$ = cleanidlist($1);
|
|
|
|
}
|
|
|
|
| structdcl_list_r ';' structdcl
|
|
|
|
{
|
|
|
|
$$ = cleanidlist($3);
|
|
|
|
$$ = nod(OLIST, $1, $$);
|
|
|
|
}
|
|
|
|
|
|
|
|
interfacedcl_list_r:
|
|
|
|
interfacedcl
|
|
|
|
{
|
|
|
|
$$ = cleanidlist($1);
|
|
|
|
}
|
|
|
|
| interfacedcl_list_r ';' interfacedcl
|
|
|
|
{
|
|
|
|
$$ = cleanidlist($3);
|
|
|
|
$$ = nod(OLIST, $1, $$);
|
|
|
|
}
|
|
|
|
|
|
|
|
structdcl:
|
|
|
|
new_name ',' structdcl
|
|
|
|
{
|
|
|
|
$$ = nod(ODCLFIELD, $1, N);
|
|
|
|
$$ = nod(OLIST, $$, $3);
|
|
|
|
}
|
|
|
|
| new_name type
|
|
|
|
{
|
|
|
|
$$ = nod(ODCLFIELD, $1, N);
|
|
|
|
$$->type = $2;
|
|
|
|
}
|
2008-09-26 22:27:26 -06:00
|
|
|
| new_name
|
|
|
|
{
|
2008-09-28 21:22:31 -06:00
|
|
|
// must be latype
|
2008-09-26 22:27:26 -06:00
|
|
|
$$ = nod(ODCLFIELD, N, N);
|
2008-09-28 21:22:31 -06:00
|
|
|
$$->type = $1->sym->otype;
|
|
|
|
if($1->sym->lexical != LATYPE) {
|
|
|
|
yyerror("unnamed structure field must be a type");
|
|
|
|
$$->type = types[TINT32];
|
|
|
|
};
|
2008-09-26 22:27:26 -06:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
interfacedcl:
|
|
|
|
new_name ',' interfacedcl
|
|
|
|
{
|
|
|
|
$$ = nod(ODCLFIELD, $1, N);
|
|
|
|
$$ = nod(OLIST, $$, $3);
|
|
|
|
}
|
2008-09-05 20:50:34 -06:00
|
|
|
| new_name indcl
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(ODCLFIELD, $1, N);
|
|
|
|
$$->type = $2;
|
|
|
|
}
|
|
|
|
|
2008-09-05 20:50:34 -06:00
|
|
|
indcl:
|
2008-06-04 15:37:38 -06:00
|
|
|
'(' oarg_type_list ')' fnres
|
|
|
|
{
|
|
|
|
// without func keyword
|
|
|
|
$$ = functype(fakethis(), $2, $4);
|
|
|
|
funcnam($$, nil);
|
|
|
|
}
|
|
|
|
| latype
|
|
|
|
{
|
|
|
|
$$ = oldtype($1);
|
|
|
|
if($$ == T || $$->etype != TFUNC)
|
|
|
|
yyerror("illegal type for function literal");
|
|
|
|
}
|
|
|
|
|
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.
|
|
|
|
*
|
|
|
|
* the hard part is that when we're reading a list of names,
|
|
|
|
* we don't know if they are going to be the names of
|
|
|
|
* parameters (like "a,b,c int") or the types of anonymous
|
|
|
|
* parameters (like "int, string, bool").
|
|
|
|
*
|
|
|
|
* an arg_chunk is a comma-separated list of arguments
|
|
|
|
* that ends in an obvious type, either "a, b, c x" or "a, b, c, *x".
|
|
|
|
* in the first case, a, b, c are parameters of type x.
|
|
|
|
* in the second case, a, b, c, and *x are types of anonymous parameters.
|
|
|
|
*/
|
|
|
|
arg_chunk:
|
|
|
|
new_name_list_r type
|
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
|
|
|
$$ = nametodcl($1, $2);
|
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
|
|
|
| non_name_type
|
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
|
|
|
$$ = anondcl($1);
|
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
|
|
|
| new_name_list_r ',' non_name_type
|
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
|
|
|
$1 = nametoanondcl($1);
|
|
|
|
$$ = appendr($1, anondcl($3));
|
|
|
|
}
|
|
|
|
|
|
|
|
arg_chunk_list_r:
|
|
|
|
arg_chunk
|
|
|
|
| arg_chunk_list_r ',' arg_chunk
|
|
|
|
{
|
|
|
|
$$ = appendr($1, $3);
|
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
|
|
|
/*
|
|
|
|
* an arg type list is a sequence of arg chunks,
|
|
|
|
* possibly ending in a list of names (plain "a,b,c"),
|
|
|
|
* which must be the types of anonymous parameters.
|
|
|
|
*/
|
2008-06-04 15:37:38 -06:00
|
|
|
arg_type_list_r:
|
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
|
|
|
arg_chunk_list_r
|
|
|
|
| arg_chunk_list_r ',' new_name_list_r
|
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
|
|
|
$3 = nametoanondcl($3);
|
|
|
|
$$ = appendr($1, $3);
|
|
|
|
}
|
|
|
|
| new_name_list_r
|
|
|
|
{
|
|
|
|
$$ = nametoanondcl($1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* arg type is just list of arg_chunks, except for the
|
|
|
|
* special case of a simple comma-separated list of names.
|
|
|
|
*/
|
|
|
|
arg_type_list:
|
|
|
|
arg_type_list_r
|
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
checkarglist($$);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2008-06-08 17:11:14 -06:00
|
|
|
/*
|
|
|
|
* need semi in front NO
|
|
|
|
* need semi in back NO
|
|
|
|
*/
|
2008-06-08 13:48:37 -06:00
|
|
|
Astmt:
|
|
|
|
complex_stmt
|
2008-06-08 17:11:14 -06:00
|
|
|
| compound_stmt
|
2008-06-21 16:11:29 -06:00
|
|
|
| Acommon_dcl
|
2008-06-08 18:21:46 -06:00
|
|
|
| ';'
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
2008-07-05 13:49:25 -06:00
|
|
|
| error Astmt
|
2008-07-03 19:05:20 -06:00
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
|
2008-06-08 17:11:14 -06:00
|
|
|
/*
|
|
|
|
* need semi in front NO
|
|
|
|
* need semi in back YES
|
|
|
|
*/
|
2008-06-08 13:48:37 -06:00
|
|
|
Bstmt:
|
|
|
|
semi_stmt
|
2008-06-21 16:11:29 -06:00
|
|
|
| Bcommon_dcl
|
2008-07-05 13:49:25 -06:00
|
|
|
| error Bstmt
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
|
2008-06-08 17:11:14 -06:00
|
|
|
/*
|
|
|
|
* need semi in front YES
|
|
|
|
* need semi in back YES
|
|
|
|
*/
|
2008-06-08 13:48:37 -06:00
|
|
|
Cstmt:
|
2008-06-17 23:33:32 -06:00
|
|
|
noninc_stmt
|
2008-06-08 13:48:37 -06:00
|
|
|
|
2008-06-08 17:11:14 -06:00
|
|
|
/*
|
2008-06-17 18:57:31 -06:00
|
|
|
* need semi in front YES
|
|
|
|
* need semi in back NO
|
|
|
|
*/
|
|
|
|
Dstmt:
|
2008-06-17 23:33:32 -06:00
|
|
|
inc_stmt
|
|
|
|
| new_name ':'
|
2008-06-17 18:57:31 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OLABEL, $1, N);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* statement list that ends AorD
|
2008-06-08 17:11:14 -06:00
|
|
|
*/
|
2008-06-08 13:48:37 -06:00
|
|
|
Astmt_list_r:
|
|
|
|
Astmt
|
2008-06-17 18:57:31 -06:00
|
|
|
| Dstmt
|
2008-06-08 13:48:37 -06:00
|
|
|
| Astmt_list_r Astmt
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-06-17 23:33:32 -06:00
|
|
|
$$ = list($1, $2);
|
2008-06-08 13:48:37 -06:00
|
|
|
}
|
2008-06-17 18:57:31 -06:00
|
|
|
| Astmt_list_r Dstmt
|
|
|
|
{
|
2008-06-17 23:33:32 -06:00
|
|
|
$$ = list($1, $2);
|
2008-06-17 18:57:31 -06:00
|
|
|
}
|
|
|
|
| Bstmt_list_r Astmt
|
|
|
|
{
|
2008-06-17 23:33:32 -06:00
|
|
|
$$ = list($1, $2);
|
2008-06-17 18:57:31 -06:00
|
|
|
}
|
2008-06-08 13:48:37 -06:00
|
|
|
|
2008-06-08 17:11:14 -06:00
|
|
|
/*
|
2008-06-17 18:57:31 -06:00
|
|
|
* statement list that ends BorC
|
2008-06-08 17:11:14 -06:00
|
|
|
*/
|
2008-06-08 13:48:37 -06:00
|
|
|
Bstmt_list_r:
|
|
|
|
Bstmt
|
|
|
|
| Cstmt
|
2008-06-17 18:57:31 -06:00
|
|
|
| Astmt_list_r Bstmt
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-06-17 23:33:32 -06:00
|
|
|
$$ = list($1, $2);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-06-17 18:57:31 -06:00
|
|
|
| Astmt_list_r Cstmt
|
2008-06-08 13:48:37 -06:00
|
|
|
{
|
2008-06-17 23:33:32 -06:00
|
|
|
$$ = list($1, $2);
|
2008-06-08 13:48:37 -06:00
|
|
|
}
|
2008-06-17 18:57:31 -06:00
|
|
|
| Bstmt_list_r Bstmt
|
2008-06-08 13:48:37 -06:00
|
|
|
{
|
2008-06-17 23:33:32 -06:00
|
|
|
$$ = list($1, $2);
|
2008-06-08 13:48:37 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
stmt_list_r:
|
|
|
|
Astmt_list_r
|
|
|
|
| Bstmt_list_r
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
expr_list_r:
|
|
|
|
expr
|
|
|
|
| expr_list_r ',' expr
|
|
|
|
{
|
|
|
|
$$ = nod(OLIST, $1, $3);
|
|
|
|
}
|
|
|
|
|
|
|
|
new_name_list_r:
|
|
|
|
new_name
|
|
|
|
| new_name_list_r ',' new_name
|
|
|
|
{
|
|
|
|
$$ = nod(OLIST, $1, $3);
|
|
|
|
}
|
|
|
|
|
|
|
|
export_list_r:
|
|
|
|
export
|
|
|
|
| export_list_r ocomma export
|
|
|
|
|
|
|
|
export:
|
|
|
|
sym
|
|
|
|
{
|
2008-08-03 19:47:02 -06:00
|
|
|
exportsym($1);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-08-12 15:04:03 -06:00
|
|
|
| sym '.' sym2
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-08-03 19:47:02 -06:00
|
|
|
exportsym(pkglookup($3->name, $1->name));
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
import_stmt_list_r:
|
|
|
|
import_stmt
|
|
|
|
| import_stmt_list_r osemi import_stmt
|
|
|
|
|
|
|
|
hidden_import_list_r:
|
|
|
|
hidden_import
|
|
|
|
| hidden_import_list_r hidden_import
|
|
|
|
|
|
|
|
hidden_importsym_list_r:
|
|
|
|
hidden_importsym
|
|
|
|
| hidden_importsym_list_r hidden_importsym
|
|
|
|
{
|
|
|
|
$$ = nod(OLIST, $1, $2);
|
|
|
|
}
|
|
|
|
|
|
|
|
hidden_importfield_list_r:
|
|
|
|
hidden_importfield
|
|
|
|
| hidden_importfield_list_r hidden_importfield
|
|
|
|
{
|
|
|
|
$$ = nod(OLIST, $1, $2);
|
|
|
|
}
|
|
|
|
|
|
|
|
keyval_list_r:
|
|
|
|
keyval
|
|
|
|
| keyval_list_r ',' keyval
|
|
|
|
{
|
|
|
|
$$ = nod(OLIST, $1, $3);
|
|
|
|
}
|
|
|
|
|
2008-09-03 15:09:29 -06:00
|
|
|
keyexpr_list:
|
|
|
|
keyval_list_r
|
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
}
|
2008-09-04 13:21:10 -06:00
|
|
|
| oexpr_list
|
2008-09-03 15:09:29 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
/*
|
|
|
|
* the one compromise of a
|
|
|
|
* non-reversed list
|
|
|
|
*/
|
|
|
|
expr_list:
|
|
|
|
expr_list_r
|
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
}
|
|
|
|
|
2008-06-21 16:11:29 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
/*
|
|
|
|
* optional things
|
|
|
|
*/
|
|
|
|
osemi:
|
|
|
|
| ';'
|
|
|
|
|
|
|
|
ocomma:
|
|
|
|
| ','
|
|
|
|
|
|
|
|
oexpr:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| expr
|
|
|
|
|
|
|
|
oexpr_list:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| expr_list
|
|
|
|
|
|
|
|
osimple_stmt:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| simple_stmt
|
|
|
|
|
|
|
|
ostmt_list:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| stmt_list_r
|
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
}
|
|
|
|
|
|
|
|
oxdcl_list:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| xdcl_list_r
|
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
}
|
|
|
|
|
|
|
|
ohidden_importsym_list:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| hidden_importsym_list_r
|
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
}
|
|
|
|
|
|
|
|
ohidden_importfield_list:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
|
|
|
| hidden_importfield_list_r
|
|
|
|
{
|
|
|
|
$$ = rev($1);
|
|
|
|
}
|
|
|
|
|
|
|
|
oarg_type_list:
|
|
|
|
{
|
|
|
|
$$ = N;
|
|
|
|
}
|
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
|
|
|
| arg_type_list
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* import syntax from header of
|
|
|
|
* an output package
|
|
|
|
*/
|
|
|
|
hidden_import:
|
2008-06-15 21:24:30 -06:00
|
|
|
/* leftover import ignored */
|
|
|
|
LPACKAGE sym
|
2008-06-04 15:37:38 -06:00
|
|
|
/* variables */
|
2008-06-15 21:24:30 -06:00
|
|
|
| LVAR hidden_importsym hidden_importsym
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
// var
|
|
|
|
doimportv1($2, $3);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* constants */
|
2008-09-26 12:44:20 -06:00
|
|
|
| LCONST hidden_importsym hidden_constant
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
doimportc1($2, &$3);
|
|
|
|
}
|
2008-09-26 12:44:20 -06:00
|
|
|
| LCONST hidden_importsym hidden_importsym hidden_constant
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
doimportc2($2, $3, &$4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* types */
|
|
|
|
| LTYPE hidden_importsym '[' hidden_importsym ']' hidden_importsym
|
|
|
|
{
|
|
|
|
// type map
|
|
|
|
doimport1($2, $4, $6);
|
|
|
|
}
|
|
|
|
| LTYPE hidden_importsym '[' LLITERAL ']' hidden_importsym
|
|
|
|
{
|
|
|
|
// type array
|
|
|
|
doimport2($2, &$4, $6);
|
|
|
|
}
|
2008-08-27 18:28:30 -06:00
|
|
|
| LTYPE hidden_importsym '[' ']' hidden_importsym
|
|
|
|
{
|
|
|
|
// type array
|
|
|
|
doimport2($2, nil, $5);
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
| LTYPE hidden_importsym '(' ohidden_importsym_list ')'
|
|
|
|
{
|
|
|
|
// type function
|
|
|
|
doimport3($2, $4);
|
|
|
|
}
|
|
|
|
| LTYPE hidden_importsym '{' ohidden_importfield_list '}'
|
|
|
|
{
|
|
|
|
// type structure
|
|
|
|
doimport4($2, $4);
|
|
|
|
}
|
|
|
|
| LTYPE hidden_importsym LLITERAL
|
|
|
|
{
|
|
|
|
// type basic
|
|
|
|
doimport5($2, &$3);
|
|
|
|
}
|
|
|
|
| LTYPE hidden_importsym '*' hidden_importsym
|
|
|
|
{
|
|
|
|
// type pointer
|
|
|
|
doimport6($2, $4);
|
|
|
|
}
|
|
|
|
| LTYPE hidden_importsym LLT ohidden_importfield_list LGT
|
|
|
|
{
|
|
|
|
// type interface
|
|
|
|
doimport7($2, $4);
|
|
|
|
}
|
2008-07-12 14:08:53 -06:00
|
|
|
| LTYPE hidden_importsym LLITERAL hidden_importsym
|
|
|
|
{
|
|
|
|
// type interface
|
|
|
|
doimport8($2, &$3, $4);
|
|
|
|
}
|
2008-09-14 17:57:55 -06:00
|
|
|
| LFUNC sym1 hidden_importsym
|
|
|
|
{
|
|
|
|
// method
|
|
|
|
doimport9($2, $3);
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-09-26 12:44:20 -06:00
|
|
|
hidden_constant:
|
|
|
|
LLITERAL
|
|
|
|
| '-' LLITERAL
|
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
switch($$.ctype){
|
|
|
|
case CTINT:
|
|
|
|
mpnegfix($$.u.xval);
|
|
|
|
break;
|
|
|
|
case CTFLT:
|
|
|
|
mpnegflt($$.u.fval);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
yyerror("bad negated constant");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
isym:
|
2008-08-13 16:24:55 -06:00
|
|
|
sym1 '.' sym2
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OIMPORT, N, N);
|
|
|
|
$$->osym = $1;
|
|
|
|
$$->psym = $1;
|
|
|
|
$$->sym = $3;
|
2008-06-12 22:48:56 -06:00
|
|
|
renamepkg($$);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2008-08-13 16:24:55 -06:00
|
|
|
| '(' sym1 ')' sym1 '.' sym2
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = nod(OIMPORT, N, N);
|
|
|
|
$$->osym = $2;
|
|
|
|
$$->psym = $4;
|
|
|
|
$$->sym = $6;
|
2008-06-12 22:48:56 -06:00
|
|
|
renamepkg($$);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
hidden_importsym:
|
|
|
|
isym
|
|
|
|
| '!' isym
|
|
|
|
{
|
|
|
|
$$ = $2;
|
2008-06-12 22:48:56 -06:00
|
|
|
$$->etype = 1;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
hidden_importfield:
|
2008-08-13 16:24:55 -06:00
|
|
|
sym1 isym
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
$$ = $2;
|
|
|
|
$$->fsym = $1;
|
|
|
|
}
|
2008-09-18 14:32:14 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* helpful error messages.
|
|
|
|
* THIS SECTION MUST BE AT THE END OF THE FILE.
|
|
|
|
*
|
|
|
|
* these rules trigger reduce/reduce conflicts in the grammar.
|
|
|
|
* they are safe because reduce/reduce conflicts are resolved
|
|
|
|
* in favor of rules appearing earlier in the grammar, and these
|
|
|
|
* are at the end of the file.
|
|
|
|
*
|
|
|
|
* to check whether the rest of the grammar is free of
|
|
|
|
* reduce/reduce conflicts, comment this section out by
|
|
|
|
* removing the slash on the next line.
|
2008-09-29 21:33:51 -06:00
|
|
|
*/
|
2008-09-18 14:32:14 -06:00
|
|
|
lpack:
|
|
|
|
LATYPE
|
|
|
|
{
|
|
|
|
yyerror("%s is type, not package", $1->name);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
laconst:
|
|
|
|
LPACK
|
|
|
|
{
|
|
|
|
// for LALR(1) reasons, using laconst works here
|
|
|
|
// but lname does not. even so, the messages make
|
|
|
|
// more sense saying "var" instead of "const".
|
|
|
|
yyerror("%s is package, not var", $1->name);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
| LATYPE
|
|
|
|
{
|
|
|
|
yyerror("%s is type, not var", $1->name);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
latype:
|
|
|
|
LACONST
|
|
|
|
{
|
|
|
|
yyerror("%s is const, not type", $1->name);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
| LPACK
|
|
|
|
{
|
|
|
|
yyerror("%s is package, not type", $1->name);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
| LNAME
|
|
|
|
{
|
2008-09-22 13:45:01 -06:00
|
|
|
yyerror("no type %s", $1->name);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
| lpack '.' LNAME
|
|
|
|
{
|
|
|
|
yyerror("no type %s.%s", context, $3->name);
|
2008-09-18 14:32:14 -06:00
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**/
|
|
|
|
|