/* (C) Copyright International Business Machines Corporation 23 January */
/* 1990.  All Rights Reserved. */
/*  */
/* See the file USERAGREEMENT distributed with this software for full */
/* terms and conditions of use. */
/* SCCS Info: @(#)asm.y	1.4 3/13/90 */

%token OPCODE INTEGER IDENTIFIER STRING ERROR BUILTIN_EXCEPTION
%token PROCESS END TRUE FALSE PAIR OTHERS TABLE
%token TYPENAME EXCEPTION EXITID HANDLERS SELECTARMS
%token USING LINKING

%start start



%{
#include "li.h"
#include "asm.h"
%}


%union	{
	char *string;
	int integer;
	object *obj;
	env *envp;
	}

%%

/* TEXBEGIN */

start :	{ init_asm(); }
	USING '(' defmod_name_s ')'
	proc
	{ end_file($6); } ;

proc : PROCESS symbol opt_type intval
  	{ init_proc($2, $3, $4); } 
	LINKING '(' link_name_s ')'
	statement_s END
	{ $$ = end_proc(); } ;

statement : opt_statement_label operator
	{ init_stmt($2, $1); }
	operand_s
	{ stmt_operand_list(); }
	opt_statement_qualifier ;

statement_qualifier : ',' qualifier ;

statement_label : label ':'
	{ $$ = $1; } ;

operand : '*'
	{ init_operand(); } ;
operand : true_operand ;

true_operand : true_operand '.' intval
	{ add_component($3); } ;
true_operand : intval
	{ init_operand(); add_component($1); } ;

label : symbol
	{ $$ = $1; } ;

/*
 * qualifiers absent are: real and polymorph_info, since they are not used in
 * the bootstrapping process.
 */

qualifier : proc
	{ q_proc($1); } ;
qualifier : label
	{ q_label($1); } ;
qualifier : EXITID symbol
	{ q_exitid($2); } ;
qualifier : TRUE
	{ q_boolean(nil_true); } ;
qualifier : FALSE
	{ q_boolean(nil_false); } ;
qualifier : intval
	{ q_integer($1); } ;
qualifier : charstring
	{ q_charstring($1); } ;
qualifier : PAIR intval intval
	{ q_intpair($2, $3); } ;
qualifier : PAIR intval label
	{ q_labelpair($3, $2, 2); };
qualifier : PAIR label intval
	{ q_labelpair($2, $3, 1); };
qualifier : label intval
	{ q_labelpair($1, $2, 1); } ;
qualifier : TYPENAME type
	{ q_typename($2); } ;
qualifier : EXCEPTION user_exception
	{ q_exception($2); } ;
qualifier : HANDLERS 
	{ init_handlers(); }
	opt_handlers ';' ;
qualifier : SELECTARMS
	{ init_selectlist(); }
	label_s ';' ;
qualifier : TABLE opt_intval opt_lookupinfo
  	{ q_table($2, $3); } ;

lookupinfo : intval_list key_list key_list
	{ $$ = q_lookupinfo($1, $2, $3); } ;

type : symbol '!' symbol
  	{ $$ = defmod_resolve_typename($1, $3); } ;

key :	{ init_operand_list(); }
	operand_s
	{ q_add_lookup(); } ;

handlers : handler ;
handlers : handlers ',' handler ;

handler : exception label
	{ add_handler($1, $2); } ;

exception : user_exception
	{ $$ = ex_user($1); } ;
exception : OTHERS
	{ $$ = ex_others(); } ;
exception : excep
	{ $$ = ex_builtin($1); } ;
exception : EXITID symbol
	{ $$ = ex_exit($2); } ;

user_exception : type '.' symbol
	{ $$ = defmod_resolve_userex($1, $3); } ;

/* TEXEND */

empty : ;

key_list : '(' 
	{ q_init_lookupset(); } 
	key_sublist ')'
	{ $$ = q_get_lookupset(); } ;

key_sublist : key ;
key_sublist : key_sublist ',' key  ;

intval_list : '(' 
  	{ init_tblreps(); }
	intval_sublist ')'
	{ $$ = get_tblreps(); } ;

intval_sublist : intval
	{ add_tblrep($1); } ;
intval_sublist : intval_sublist ',' intval
	{ add_tblrep($3); } ;

defmod_name_s : defmod_name_s symbol
	{ defmod_import($2); } ;
defmod_name_s : empty ;

link_name_s : link_name_s symbol
	{ link_module($2); } ;
link_name_s : empty ;

statement_s : statement_s statement ;
statement_s : empty ;

opt_statement_qualifier : statement_qualifier ;
opt_statement_qualifier : empty ;

operand_s : operand_s operand
	{ add_operand(); } ;
operand_s : empty ;

opt_statement_label : statement_label
	{ $$ = $1; } ;
opt_statement_label : empty
	{ $$ = nil; } ;

opt_intval : intval 
  	{ $$ = $1; } ;
opt_intval : empty
	{ $$ = -1; } ;

opt_lookupinfo : lookupinfo
	{ $$ = $1; } ;
opt_lookupinfo : empty
	{ $$ = nil; } ;

opt_type : type
	{ $$ = $1; } ;
opt_type : empty
	{ $$ = new_object(); } ;	/* return bottom'ed object */

label_s : label_s label
	{ add_selectlabel($2); } ;
label_s : empty ;

opt_handlers : empty ;
opt_handlers : handlers ;


intval : INTEGER
	{ $$ = $1; } ;

excep : BUILTIN_EXCEPTION
	{ $$ = $1; } ;

operator : OPCODE 
	{ $$ = $1; } ;

symbol : IDENTIFIER
	{ $$ = copystring($1); } ;

charstring : STRING
	{ $$ = copystring($1); } ;

