%{
//
-// OPTIMIZATION:
-// This loop is pointless:
-// while (current_block != prev_block)
-// current_block = current_block.Parent;
-//
// cs-parser.jay: The Parser for the C# compiler
//
-// Author: Miguel de Icaza (miguel@gnu.org)
+// Authors: Miguel de Icaza (miguel@gnu.org)
+// Ravi Pratap (ravi@ximian.com)
//
// Licensed under the terms of the GNU GPL
//
// (C) 2001 Ximian, Inc (http://www.ximian.com)
//
// TODO:
-// (1) Get rid of the *Collections.cs, that is an idea I took from System.CodeDOM
-// And come to think of it, it is not that great, it duplicates a lot of code
-// for something which is not really needed. We still have piles of typecasts
-// anwyays (due to the nature of the stack being a collection of Objects).
-//
-// (2) Figure out why error productions dont work. `type-declaration' is a
+// (1) Figure out why error productions dont work. `type-declaration' is a
// great spot to put an `error' because you can reproduce it with this input:
// "public X { }"
//
-// (3) Move Modifier checking from each object into the parser itself, that will
-// get rid of the global "error" symbol that we use now to report errors.
-// We still need to pass a pointer to the tree.ErrorHandler, but that is a
-// separate problem
//
using System.Text;
using System;
// value parameter that is passed to the "set" and "get"accesor
// methods (properties and indexers).
// </summary>
- string implicit_value_parameter_type;
+ Expression implicit_value_parameter_type;
Parameters indexer_parameters;
// <summary>
// An out-of-band stack.
//
Stack oob_stack;
+
+ //
+ // Switch stack.
+ //
+ Stack switch_stack;
%}
%token EOF
%nonassoc HIGHPREC
%start compilation_unit
-/*%start namespace_declaration */
%%
compilation_unit
- : opt_using_directives opt_namespace_member_declarations opt_attributes opt_EOF
- {
- // Check that using comes only before namespace elements
- }
- ;
-
+ : outer_declarations opt_EOF
+ | outer_declarations attribute_sections opt_EOF
+ | attribute_sections opt_EOF
+ ;
+
opt_EOF
: /* empty */
| EOF
;
+outer_declarations
+ : outer_declaration
+ | outer_declarations outer_declaration
+ ;
+
+outer_declaration
+ : using_directive
+ | namespace_member_declaration
+ ;
+
using_directives
: using_directive
| using_directives using_directive
using_namespace_directive
: USING namespace_name SEMICOLON
{
- current_namespace.Using ((string) $2);
+ current_namespace.Using ((string) $2, lexer.Location);
}
;
-// namespace_declarations
-// : namespace_declaration
-// | namespace_declarations namespace_declaration
-
+//
+// Strictly speaking, namespaces don't have attributes but
+// we parse global attributes along with namespace declarations and then
+// detach them
+//
namespace_declaration
- : NAMESPACE qualified_identifier
- {
- current_namespace = RootContext.Tree.RecordNamespace (current_namespace, name, (string) $2);
- }
+ : opt_attributes NAMESPACE qualified_identifier
+ {
+ Attributes attrs = (Attributes) $1;
+
+ if (attrs != null) {
+ foreach (AttributeSection asec in attrs.AttributeSections)
+ if (asec.Target == "assembly")
+ RootContext.AddGlobalAttribute (
+ current_container, asec, lexer.Location);
+ }
+
+ current_namespace = RootContext.Tree.RecordNamespace (current_namespace, name, (string) $3);
+ }
namespace_body opt_semicolon
{
current_namespace = current_namespace.Parent;
"Namespace elements cant be explicitly " +
"declared private or protected in `" + name + "'");
}
+ current_namespace.DeclarationFound = true;
}
| namespace_declaration
;
//
// Attributes 17.2
//
+
opt_attributes
- : /* empty */ { $$ = null; }
- | attribute_section opt_attributes
+ : /* empty */
+ | attribute_sections { $$ = $1; }
+ ;
+
+attribute_sections
+ : attribute_section
+ {
+ AttributeSection sect = (AttributeSection) $1;
+
+ if (sect.Target == "assembly")
+ RootContext.AddGlobalAttribute (current_container, sect, lexer.Location);
+
+ $$ = new Attributes ((AttributeSection) $1, lexer.Location);
+ }
+ | attribute_sections attribute_section
{
Attributes attrs = null;
- AttributeSection sect = (AttributeSection) $1;
+ AttributeSection sect = (AttributeSection) $2;
- if (sect.Target == "assembly"){
- RootContext.AddGlobalAttributes (sect, lexer.Location);
- sect = null;
- }
+ if (sect.Target == "assembly")
+ RootContext.AddGlobalAttribute (current_container, sect, lexer.Location);
- if ($2 != null) {
- if (sect != null){
- attrs = (Attributes) $2;
- attrs.AddAttribute (sect);
- }
- } else {
- if (sect != null)
- attrs = new Attributes (sect, lexer.Location);
+ if ($1 != null) {
+ attrs = (Attributes) $1;
+ attrs.AddAttribute (sect);
}
$$ = attrs;
current_container.Namespace = current_namespace;
RootContext.Tree.RecordDecl (full_struct_name, new_struct);
}
- opt_struct_interfaces
+ opt_class_base
struct_body
opt_semicolon
{
Struct new_struct = (Struct) current_container;
+ if ($6 != null)
+ new_struct.Bases = (ArrayList) $6;
+
current_container = current_container.Parent;
CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
$$ = new_struct;
}
;
-opt_struct_interfaces
- : /* empty */
- | struct_interfaces
- ;
-
-struct_interfaces
- : struct_interface
- | struct_interfaces struct_interface
- ;
-
-struct_interface
- : COLON type_list
- ;
-
struct_body
: OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE
;
Location l = constant.Location;
Const c = new Const (
- (string) $4, (string) constant.identifier,
+ (Expression) $4, (string) constant.identifier,
(Expression) constant.expression_or_array_initializer, (int) $2,
(Attributes) $1, l);
variable_declarators
SEMICOLON
{
- string type = (string) $3;
+ Expression type = (Expression) $3;
int mod = (int) $2;
foreach (VariableDeclaration var in (ArrayList) $4){
}
| STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
{
- $$ = new StackAlloc ((string) $2, (Expression) $4, lexer.Location);
+ $$ = new StackAlloc ((Expression) $2, (Expression) $4, lexer.Location);
}
;
member_name
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
- Method method = new Method ((string) $3, (int) $2, (string) $4,
+ Method method = new Method ((Expression) $3, (int) $2, (string) $4,
(Parameters) $6, (Attributes) $1, lexer.Location);
current_local_parameters = (Parameters) $6;
member_name
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
- Method method = new Method ("System.Void", (int) $2, (string) $4,
+ Method method = new Method (TypeManager.system_void_expr, (int) $2, (string) $4,
(Parameters) $6, (Attributes) $1, lexer.Location);
current_local_parameters = (Parameters) $6;
;
opt_formal_parameter_list
- : /* empty */ { $$ = Parameters.GetEmptyReadOnlyParameters (); }
+ : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
| formal_parameter_list
;
type
IDENTIFIER
{
- $$ = new Parameter ((string) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
+ $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
}
;
;
parameter_modifier
- : REF { $$ = Parameter.Modifier.REF; }
- | OUT { $$ = Parameter.Modifier.OUT; }
+ : REF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
+ | OUT { $$ = Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF; }
;
parameter_array
: opt_attributes PARAMS type IDENTIFIER
{
- $$ = new Parameter ((string) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
+ $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
note ("type must be a single-dimension array type");
}
;
type member_name
OPEN_BRACE
{
- implicit_value_parameter_type = (string) $3;
+ implicit_value_parameter_type = (Expression) $3;
lexer.PropertyParsing = true;
{
Property prop;
Pair pair = (Pair) $7;
- Block get_block = null;
- Block set_block = null;
-
- if (pair.First != null)
- get_block = (Block) pair.First;
- if (pair.Second != null)
- set_block = (Block) pair.Second;
+ Accessor get_block = (Accessor) pair.First;
+ Accessor set_block = (Accessor) pair.Second;
Location loc = (Location) $6;
- prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block,
+ prop = new Property ((Expression) $3, (string) $4, (int) $2, get_block, set_block,
(Attributes) $1, loc);
CheckDef (current_container.AddProperty (prop), prop.Name, loc);
}
accessor_body
{
- $$ = $4;
+ $$ = new Accessor ((Block) $4, (Attributes) $1);
current_local_parameters = null;
lexer.PropertyParsing = true;
}
if (parsing_indexer == false) {
args = new Parameter [1];
args [0] = implicit_value_parameter;
+ current_local_parameters = new Parameters (args, null, lexer.Location);
} else {
- Parameter [] fp = indexer_parameters.FixedParameters;
- int count = fp.Length;
-
- args = new Parameter [count + 1];
-
- fp.CopyTo (args, 0);
- args [count] = implicit_value_parameter;
+ Parameter [] fpars = indexer_parameters.FixedParameters;
+
+ if (fpars != null){
+ int count = fpars.Length;
+
+ args = new Parameter [count + 1];
+ fpars.CopyTo (args, 0);
+ args [count] = implicit_value_parameter;
+ } else
+ args = null;
+ current_local_parameters = new Parameters (
+ args, indexer_parameters.ArrayParameter, lexer.Location);
}
- current_local_parameters = new Parameters (args, null, lexer.Location);
lexer.PropertyParsing = false;
}
accessor_body
{
- $$ = $4;
+ $$ = new Accessor ((Block) $4, (Attributes) $1);
current_local_parameters = null;
lexer.PropertyParsing = true;
}
accessor_body
: block
- | SEMICOLON { $$ = new Block (null); }
+ | SEMICOLON { $$ = null; }
;
interface_declaration
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
SEMICOLON
{
- $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2,
+ $$ = new InterfaceMethod ((Expression) $3, (string) $4, (bool) $2,
(Parameters) $6, (Attributes) $1, lexer.Location);
}
| opt_attributes opt_new VOID IDENTIFIER
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
SEMICOLON
{
- $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6,
+ $$ = new InterfaceMethod (
+ TypeManager.system_void_expr, (string) $4, (bool) $2, (Parameters) $6,
(Attributes) $1, lexer.Location);
}
;
{
int gs = (int) $7;
- $$ = new InterfaceProperty ((string) $3, (string) $4, (bool) $2,
+ $$ = new InterfaceProperty ((Expression) $3, (string) $4, (bool) $2,
(gs & 1) == 1, (gs & 2) == 2, (Attributes) $1,
lexer.Location);
}
interface_event_declaration
: opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
{
- $$ = new InterfaceEvent ((string) $4, (string) $5, (bool) $2, (Attributes) $1);
+ $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
+ lexer.Location);
}
;
bool do_get = (a_flags & 1) == 1;
bool do_set = (a_flags & 2) == 2;
- $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set,
+ $$ = new InterfaceIndexer ((Expression) $3, (Parameters) $6, do_get, do_set,
(bool) $2, (Attributes) $1, lexer.Location);
}
;
Parameter [] pars = new Parameter [1];
- pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+ pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
current_local_parameters = new Parameters (pars, null, lexer.Location);
- $$ = new OperatorDeclaration (op, (string) $1, (string) $5, (string) $6,
+ $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6,
null, null, lexer.Location);
}
| type OPERATOR overloadable_operator
Parameter [] pars = new Parameter [2];
- pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
- pars [1] = new Parameter ((string) $8, (string) $9, Parameter.Modifier.NONE, null);
+ pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
+ pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null);
current_local_parameters = new Parameters (pars, null, lexer.Location);
- $$ = new OperatorDeclaration ((Operator.OpType) $3, (string) $1, (string) $5, (string) $6,
- (string) $8, (string) $9, lexer.Location);
+ $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1,
+ (Expression) $5, (string) $6,
+ (Expression) $8, (string) $9, lexer.Location);
}
| conversion_operator_declarator
;
{
Parameter [] pars = new Parameter [1];
- pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+ pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
current_local_parameters = new Parameters (pars, null, lexer.Location);
- $$ = new OperatorDeclaration (Operator.OpType.Implicit, (string) $3, (string) $5, (string) $6,
+ $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, (Expression) $5, (string) $6,
null, null, lexer.Location);
}
| EXPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
{
Parameter [] pars = new Parameter [1];
- pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+ pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
current_local_parameters = new Parameters (pars, null, lexer.Location);
- $$ = new OperatorDeclaration (Operator.OpType.Explicit, (string) $3, (string) $5, (string) $6,
+ $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, (Expression) $5, (string) $6,
null, null, lexer.Location);
}
| IMPLICIT error
constructor_initializer
: COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
{
- $$ = new ConstructorBaseInitializer ((ArrayList) $4, lexer.Location);
+ $$ = new ConstructorBaseInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
}
| COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
{
- $$ = new ConstructorThisInitializer ((ArrayList) $4, lexer.Location);
+ $$ = new ConstructorThisInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
}
;
} else {
Location l = lexer.Location;
+ int m;
+ if (!RootContext.StdLib && current_container.Name == "System.Object")
+ m = Modifiers.PROTECTED | Modifiers.VIRTUAL;
+ else
+ m = Modifiers.PROTECTED | Modifiers.OVERRIDE;
+
Method d = new Method (
- "System.Void", 0, "Finalize",
+ TypeManager.system_void_expr, m, "Finalize",
new Parameters (null, null, l), (Attributes) $1, l);
d.Block = (Block) $6;
{
foreach (VariableDeclaration var in (ArrayList) $5) {
- Event e = new Event ((string) $4, var.identifier, var.expression_or_array_initializer,
+ Event e = new Event ((Expression) $4, var.identifier,
+ var.expression_or_array_initializer,
(int) $2, null, null, (Attributes) $1, lexer.Location);
CheckDef (current_container.AddEvent (e), e.Name, e.Location);
EVENT type member_name
OPEN_BRACE
{
- implicit_value_parameter_type = (string) $4;
+ implicit_value_parameter_type = (Expression) $4;
lexer.EventParsing = true;
oob_stack.Push (lexer.Location);
}
Location loc = (Location) oob_stack.Pop ();
Pair pair = (Pair) $8;
- Block add_block = null;
- Block rem_block = null;
+ Accessor add_accessor = null;
+ Accessor rem_accessor = null;
if (pair.First != null)
- add_block = (Block) pair.First;
+ add_accessor = (Accessor) pair.First;
if (pair.Second != null)
- rem_block = (Block) pair.Second;
+ rem_accessor = (Accessor) pair.Second;
- Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_block, rem_block,
+ Event e = new Event ((Expression) $4, (string) $5, null, (int) $2, add_accessor, rem_accessor,
(Attributes) $1, loc);
CheckDef (current_container.AddEvent (e), e.Name, loc);
}
block
{
- $$ = $4;
+ $$ = new Accessor ((Block) $4, (Attributes) $1);
lexer.EventParsing = true;
}
;
}
block
{
- $$ = $4;
+ $$ = new Accessor ((Block) $4, (Attributes) $1);
lexer.EventParsing = true;
}
;
parsing_indexer = true;
indexer_parameters = decl.param_list;
- $$ = lexer.Location;
+ oob_stack.Push (lexer.Location);
}
accessor_declarations
{
{
// The signature is computed from the signature of the indexer. Look
// at section 3.6 on the spec
-
+ Location loc = (Location) oob_stack.Pop ();
Indexer indexer;
IndexerDeclaration decl = (IndexerDeclaration) $3;
Pair pair = (Pair) $6;
- Block get_block = null;
- Block set_block = null;
-
- if (pair.First != null)
- get_block = (Block) pair.First;
- if (pair.Second != null)
- set_block = (Block) pair.Second;
+ Accessor get_block = (Accessor) pair.First;
+ Accessor set_block = (Accessor) pair.Second;
indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list,
- get_block, set_block, (Attributes) $1, (Location) $5);
+ get_block, set_block, (Attributes) $1, loc);
// Note that there is no equivalent of CheckDef for this case
// We shall handle this in semantic analysis
{
Parameters pars = (Parameters) $4;
- if (pars.FixedParameters == null){
+ if (pars.FixedParameters == null && pars.ArrayParameter == null){
Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
}
- $$ = new IndexerDeclaration ((string) $1, null, pars);
+ $$ = new IndexerDeclaration ((Expression) $1, null, pars);
}
| type qualified_identifier DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
{
Parameters pars = (Parameters) $6;
- if (pars.FixedParameters == null){
+ if (pars.FixedParameters == null && pars.ArrayParameter == null){
Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
}
- $$ = new IndexerDeclaration ((string) $1, (string) $2, pars);
+ $$ = new IndexerDeclaration ((Expression) $1, (string) $2, pars);
}
;
Location enum_location = lexer.Location;
string full_name = MakeName ((string) $4);
- Enum e = new Enum (
- current_container, (string) $5, (int) $2, full_name,
- (Attributes) $1, enum_location);
-
- foreach (VariableDeclaration ev in (ArrayList) $6){
+ Enum e = new Enum (current_container, (Expression) $5, (int) $2, full_name,
+ (Attributes) $1, enum_location);
+
+ foreach (VariableDeclaration ev in (ArrayList) $6) {
Location loc = (Location) ev.Location;
CheckDef (e.AddEnumMember (ev.identifier,
(Expression) ev.expression_or_array_initializer,
- loc),
+ loc, ev.OptAttributes),
ev.identifier, loc);
}
;
opt_enum_base
- : /* empty */ { $$ = "System.Int32"; }
+ : /* empty */ { $$ = TypeManager.system_int32_expr; }
| COLON type { $$ = $2; }
;
enum_member_declaration
: opt_attributes IDENTIFIER
{
- $$ = new VariableDeclaration ((string) $2, null, lexer.Location);
+ $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
}
| opt_attributes IDENTIFIER
{
}
ASSIGN expression
{
- $$ = new VariableDeclaration ((string) $2, $5, lexer.Location);
+ $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
}
;
SEMICOLON
{
Location l = lexer.Location;
- Delegate del = new Delegate (current_container, (string) $4, (int) $2,
+ Delegate del = new Delegate (current_container, (Expression) $4, (int) $2,
MakeName ((string) $5), (Parameters) $7,
(Attributes) $1, l);
Location l = lexer.Location;
Delegate del = new Delegate (
current_container,
- "System.Void", (int) $2, MakeName ((string) $5), (Parameters) $7,
- (Attributes) $1, l);
+ TypeManager.system_void_expr, (int) $2, MakeName ((string) $5),
+ (Parameters) $7, (Attributes) $1, l);
del.Namespace = current_namespace;
CheckDef (current_container.AddDelegate (del), del.Name, l);
This does interfaces, delegates, struct_types, class_types,
parent classes, and more! 4.2
*/
- $$ = $1;
+ $$ = DecomposeQI ((string) $1, lexer.Location);
}
| builtin_types
| array_type
// can't perform checks during this phase - we do it during
// semantic analysis.
//
- $$ = (string) $1 + "*";
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
}
| VOID STAR
{
- $$ = "System.Void*";
+ $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);
}
;
non_expression_type
: builtin_types
- {
- $$ = new SimpleName ((string) $1, lexer.Location);
- }
| non_expression_type rank_specifier
{
$$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
* simple types, but we need this to reuse it easily in local_variable_type
*/
builtin_types
- : OBJECT { $$ = "System.Object"; }
- | STRING { $$ = "System.String"; }
- | BOOL { $$ = "System.Boolean"; }
- | DECIMAL { $$ = "System.Decimal"; }
- | FLOAT { $$ = "System.Single"; }
- | DOUBLE { $$ = "System.Double"; }
+ : OBJECT { $$ = TypeManager.system_object_expr; }
+ | STRING { $$ = TypeManager.system_string_expr; }
+ | BOOL { $$ = TypeManager.system_boolean_expr; }
+ | DECIMAL { $$ = TypeManager.system_decimal_expr; }
+ | FLOAT { $$ = TypeManager.system_single_expr; }
+ | DOUBLE { $$ = TypeManager.system_double_expr; }
| integral_type
;
integral_type
- : SBYTE { $$ = "System.SByte"; }
- | BYTE { $$ = "System.Byte"; }
- | SHORT { $$ = "System.Int16"; }
- | USHORT { $$ = "System.UInt16"; }
- | INT { $$ = "System.Int32"; }
- | UINT { $$ = "System.UInt32"; }
- | LONG { $$ = "System.Int64"; }
- | ULONG { $$ = "System.UInt64"; }
- | CHAR { $$ = "System.Char"; }
- | VOID { $$ = "System.Void"; }
+ : SBYTE { $$ = TypeManager.system_sbyte_expr; }
+ | BYTE { $$ = TypeManager.system_byte_expr; }
+ | SHORT { $$ = TypeManager.system_int16_expr; }
+ | USHORT { $$ = TypeManager.system_uint16_expr; }
+ | INT { $$ = TypeManager.system_int32_expr; }
+ | UINT { $$ = TypeManager.system_uint32_expr; }
+ | LONG { $$ = TypeManager.system_int64_expr; }
+ | ULONG { $$ = TypeManager.system_uint64_expr; }
+ | CHAR { $$ = TypeManager.system_char_expr; }
+ | VOID { $$ = TypeManager.system_void_expr; }
;
interface_type
array_type
: type rank_specifiers
{
- $$ = (string) $1 + (string) $2;
+ $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
}
;
| checked_expression
| unchecked_expression
| pointer_member_access
- // TODO: pointer_element_access
- // TODO: sizeof-expression
;
literal
: LITERAL_INTEGER {
object v = lexer.Value;
- //
- // FIXME: Possible optimization would be to
- // compute the *Literal objects directly in the scanner
- //
if (v is int)
$$ = new IntLiteral ((Int32) v);
else if (v is uint)
}
| predefined_type DOT IDENTIFIER
{
- $$ = new MemberAccess (new SimpleName ((string) $1, lexer.Location), (string) $3, lexer.Location);
+ $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
}
;
this_access
: THIS
{
- $$ = new This (lexer.Location);
+ $$ = new This (current_block, lexer.Location);
}
;
object_or_delegate_creation_expression
: NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
{
- $$ = new New ((string) $2, (ArrayList) $4, lexer.Location);
+ $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
}
;
opt_rank_specifier
opt_array_initializer
{
- $$ = new ArrayCreation ((string) $2, (ArrayList) $4, (string) $6, (ArrayList) $7,
- lexer.Location);
+ $$ = new ArrayCreation ((Expression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, lexer.Location);
}
| NEW type rank_specifiers array_initializer
{
- $$ = new ArrayCreation ((string) $2, (string) $3, (ArrayList) $4, lexer.Location);
+ $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, lexer.Location);
}
| NEW type error
{
typeof_expression
: TYPEOF OPEN_PARENS type CLOSE_PARENS
{
- $$ = new TypeOf ((string) $3, lexer.Location);
+ $$ = new TypeOf ((Expression) $3, lexer.Location);
}
;
sizeof_expression
: SIZEOF OPEN_PARENS type CLOSE_PARENS {
- $$ = new SizeOf ((string) $3, lexer.Location);
-
- note ("Verify type is unmanaged");
- note ("if (5.8) builtin, yield constant expression");
+ $$ = new SizeOf ((Expression) $3, lexer.Location);
}
;
checked_expression
: CHECKED OPEN_PARENS expression CLOSE_PARENS
{
- $$ = new CheckedExpr ((Expression) $3);
+ $$ = new CheckedExpr ((Expression) $3, lexer.Location);
}
;
unchecked_expression
: UNCHECKED OPEN_PARENS expression CLOSE_PARENS
{
- $$ = new UnCheckedExpr ((Expression) $3);
+ $$ = new UnCheckedExpr ((Expression) $3, lexer.Location);
}
;
}
| relational_expression IS type
{
- $$ = new Is ((Expression) $1, (string) $3, lexer.Location);
+ $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
}
| relational_expression AS type
{
- $$ = new As ((Expression) $1, (string) $3, lexer.Location);
+ $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
}
;
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Multiply,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_DIV_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Division,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_MOD_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Modulus,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.Modulus, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_ADD_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Addition,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_SUB_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Subtraction,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.LeftShift,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.RightShift,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.RightShift, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_AND_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.BitwiseAnd,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_OR_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.BitwiseOr,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, l);
}
| prefixed_unary_expression OP_XOR_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.ExclusiveOr,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, l);
}
;
block
: OPEN_BRACE
{
- current_block = new Block (current_block, lexer.Location, Location.Null);
+ current_block = new Block (current_block, current_local_parameters,
+ lexer.Location, Location.Null);
}
opt_statement_list CLOSE_BRACE
{
labeled_statement
: IDENTIFIER COLON
{
- LabeledStatement labeled = new LabeledStatement ((string) $1);
+ LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
if (!current_block.AddLabel ((string) $1, labeled)){
Location l = lexer.Location;
{
DictionaryEntry de = (DictionaryEntry) $1;
- $$ = declare_local_variables ((string) de.Key, (ArrayList) de.Value, lexer.Location);
+ $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
}
| local_constant_declaration SEMICOLON
{
DictionaryEntry de = (DictionaryEntry) $1;
- $$ = declare_local_constant ((string) de.Key, (VariableDeclaration) de.Value);
+ $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
}
;
if (!(expr is SimpleName || expr is MemberAccess)) {
Location l = lexer.Location;
Report.Error (-1, l, "Invalid Type definition");
- $$ = "System.Object";
+ $$ = TypeManager.system_object_expr;
}
//
// So we extract the string corresponding to the SimpleName
// or MemberAccess
//
- $$ = GetQualifiedIdentifier (expr) + (string) $2;
+ if ((string) $2 == "")
+ $$ = $1;
+ else
+ $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
}
| builtin_types opt_rank_specifier
{
- $$ = (string) $1 + (string) $2;
+ if ((string) $2 == "")
+ $$ = $1;
+ else
+ $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
}
;
$$ = "System.Object";
}
- $$ = GetQualifiedIdentifier (expr) + "*";
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
}
| builtin_types STAR
{
- $$ = (string) $1 + "*";
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);;
}
| VOID STAR
{
- $$ = "System.Void*";
+ $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);;
}
| local_variable_pointer_type STAR
{
- $$ = (string) $1 + "*";
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
}
;
}
| local_variable_pointer_type opt_rank_specifier variable_declarators
{
- $$ = new DictionaryEntry ((string) $1 + (string) $2, $3);
+ Expression t;
+
+ if ((string) $2 == "")
+ t = (Expression) $1;
+ else
+ t = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+ $$ = new DictionaryEntry (t, $3);
}
;
: SWITCH OPEN_PARENS
{
oob_stack.Push (lexer.Location);
+ switch_stack.Push (current_block);
}
expression CLOSE_PARENS
switch_block
{
$$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) oob_stack.Pop ());
+ current_block = (Block) switch_stack.Pop ();
}
;
while (current_block.Implicit)
current_block = current_block.Parent;
$$ = new SwitchSection ((ArrayList) $1, current_block);
- current_block = current_block.Parent;
}
;
if ($3 is DictionaryEntry){
DictionaryEntry de = (DictionaryEntry) $3;
- string type = (string) de.Key;
+ Expression type = (Expression) de.Key;
ArrayList var_declarators = (ArrayList) de.Value;
foreach (VariableDeclaration decl in var_declarators){
vi = current_block.AddVariable (
type, decl.identifier, current_local_parameters, decl.Location);
- if (vi == null){
- Report.Error (128, decl.Location,
- "A local variable `" + decl.identifier +
- "' is already defined in this scope");
+ if (vi == null)
+ continue;
+
+ Location l = lexer.Location;
+ Expression expr;
+ if (decl.expression_or_array_initializer is Expression){
+ expr = (Expression) decl.expression_or_array_initializer;
} else {
- Location l = lexer.Location;
- Expression expr;
- if (decl.expression_or_array_initializer is Expression){
- expr = (Expression) decl.expression_or_array_initializer;
-
- } else {
-
- ArrayList init = (ArrayList) decl.expression_or_array_initializer;
-
- string base_type = type.Substring (0, type.IndexOf ("["));
- string rank = type.Substring (type.IndexOf ("["));
-
- expr = new ArrayCreation (base_type, rank, init, decl.Location);
- }
+ ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+ expr = new ArrayCreation (type, "", init, decl.Location);
+ }
- LocalVariableReference var;
- var = new LocalVariableReference (
- assign_block, decl.identifier, l);
+ LocalVariableReference var;
+ var = new LocalVariableReference (assign_block, decl.identifier, l);
- Assign a = new Assign (var, expr, decl.Location);
+ Assign a = new Assign (var, expr, decl.Location);
- assign_block.AddStatement (new StatementExpression (a, lexer.Location));
- }
+ assign_block.AddStatement (new StatementExpression (a, lexer.Location));
}
$3 = null;
oob_stack.Push (current_block);
Block foreach_block = new Block (current_block, true);
- LocalVariableReference v;
+ LocalVariableReference v = null;
Location l = lexer.Location;
VariableInfo vi;
- vi = foreach_block.AddVariable ((string) $3, (string) $4, current_local_parameters, l);
- if (vi == null){
- Report.Error (
- 128, l, "A local variable `" + (string) $4 + "' is already "+
- "defined in this scope");
- }
+ vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l);
+ if (vi != null) {
+ vi.ReadOnly = true;
- v = new LocalVariableReference (foreach_block, (string) $4, l);
+ // Get a writable reference to this read-only variable.
+ v = new LocalVariableReference (foreach_block, (string) $4, l, vi, false);
+ }
current_block = foreach_block;
oob_stack.Push (v);
current_block = prev_block;
- Foreach f = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
- foreach_block.AddStatement (f);
+ if (v != null) {
+ Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l);
+ foreach_block.AddStatement (f);
+ }
$$ = foreach_block;
}
ArrayList s = new ArrayList ();
foreach (Catch cc in (ArrayList) $3) {
- if (cc.Type == null)
+ if (cc.IsGeneral)
g = cc;
else
s.Add (cc);
// Now s contains the list of specific catch clauses
// and g contains the general one.
- $$ = new Try ((Block) $2, s, g, null);
+ $$ = new Try ((Block) $2, s, g, null, lexer.Location);
}
| TRY block opt_catch_clauses FINALLY block
{
if (catch_list != null){
foreach (Catch cc in catch_list) {
- if (cc.Type == null)
+ if (cc.IsGeneral)
g = cc;
else
s.Add (cc);
}
}
- $$ = new Try ((Block) $2, s, g, (Block) $5);
+ $$ = new Try ((Block) $2, s, g, (Block) $5, lexer.Location);
}
| TRY block error
{
catch_clause
: CATCH opt_catch_args
{
- string type = null, id = null;
+ Expression type = null;
+ string id = null;
if ($2 != null) {
DictionaryEntry cc = (DictionaryEntry) $2;
- type = (string) cc.Key;
+ type = (Expression) cc.Key;
id = (string) cc.Value;
if (id != null){
current_block = new Block (current_block);
Block b = declare_local_variables (type, one, loc);
current_block = b;
-
-
}
}
} block {
- string type = null, id = null;
+ Expression type = null;
+ string id = null;
if ($2 != null){
DictionaryEntry cc = (DictionaryEntry) $2;
- type = (string) cc.Key;
+ type = (Expression) cc.Key;
id = (string) cc.Value;
if ($1 != null){
+ //
+ // FIXME: I can change this for an assignment.
+ //
while (current_block != (Block) $1)
current_block = current_block.Parent;
}
{
Block assign_block = new Block (current_block, true);
ArrayList list = (ArrayList) $4;
- string type = (string) $3;
+ Expression type = (Expression) $3;
Location l = lexer.Location;
int top = list.Count;
VariableInfo v;
v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
- if (v == null){
- Report.Error (
- 128, l, "A local variable `" + (string) p.First + "' is already "+
- "defined in this scope");
- }
+ if (v == null)
+ continue;
v.ReadOnly = true;
p.First = v;
list [i] = p;
ArrayList list = (ArrayList) $4;
int top = list.Count;
- $$ = new Fixed ((string) $3, (ArrayList) $4, (Statement) $7, l);
+ $$ = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
}
;
DictionaryEntry de = (DictionaryEntry) $3;
Location l = lexer.Location;
- string type = (string) de.Key;
+ Expression type = (Expression) de.Key;
ArrayList var_declarators = (ArrayList) de.Value;
- foreach (VariableDeclaration decl in var_declarators){
- if (current_block.AddVariable (
- type, decl.identifier,
- current_local_parameters, decl.Location) == null){
- Report.Error (128, decl.Location,
- "A local variable `" + decl.identifier + "' is already" +
- "defined in this scope");
- }
- }
-
ArrayList vars = new ArrayList ();
foreach (VariableDeclaration decl in var_declarators){
+ VariableInfo vi = current_block.AddVariable (
+ type, decl.identifier,
+ current_local_parameters, decl.Location);
+ if (vi == null)
+ continue;
+ vi.ReadOnly = true;
+
Expression expr;
if (decl.expression_or_array_initializer is Expression){
expr = (Expression) decl.expression_or_array_initializer;
-
} else {
-
ArrayList init = (ArrayList) decl.expression_or_array_initializer;
- string base_type = type.Substring (0, type.IndexOf ("["));
- string rank = type.Substring (type.IndexOf ("["));
-
- expr = new ArrayCreation (base_type, rank, init, decl.Location);
+ expr = new ArrayCreation (type, "", init, decl.Location);
}
LocalVariableReference var;
- VariableInfo vi;
- var = new LocalVariableReference (assign_block, decl.identifier, l);
- vi = var.VariableInfo;
- vi.ReadOnly = true;
+ // Get a writable reference to this read-only variable.
+ var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
// This is so that it is not a warning on using variables
vi.Used = true;
public string identifier;
public object expression_or_array_initializer;
public Location Location;
+ public Attributes OptAttributes;
- public VariableDeclaration (string id, object eoai, Location l){
+ public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs)
+ {
this.identifier = id;
this.expression_or_array_initializer = eoai;
this.Location = l;
+ this.OptAttributes = opt_attrs;
+ }
+
+ public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
+ {
}
}
// </summary>
public class IndexerDeclaration {
- public string type;
+ public Expression type;
public string interface_type;
public Parameters param_list;
- public IndexerDeclaration (string type, string interface_type, Parameters param_list)
+ public IndexerDeclaration (Expression type, string interface_type, Parameters param_list)
{
this.type = type;
this.interface_type = interface_type;
public class OperatorDeclaration {
public Operator.OpType optype;
- public string ret_type;
- public string arg1type;
- public string arg1name;
- public string arg2type;
- public string arg2name;
+ public Expression ret_type, arg1type, arg2type;
+ public string arg1name, arg2name;
public Location location;
- public OperatorDeclaration (Operator.OpType op, string ret_type, string arg1type, string arg1name,
- string arg2type, string arg2name, Location location)
+ public OperatorDeclaration (Operator.OpType op, Expression ret_type,
+ Expression arg1type, string arg1name,
+ Expression arg2type, string arg2name, Location location)
{
optype = op;
this.ret_type = ret_type;
CheckDef (AdditionResult.NameExists, name, l);
}
-//
-// This routine should be removed soon. I am in the process of making
-// changes to never keep anything but SimpleNames during parsing, as
-// that breaks some kinds of code (documented in the ChangeLog).
-//
-Expression
-SimpleLookup (string name, Location loc)
-{
- //
- // we need to check against current_block not being null
- // as `expression' is allowed in argument_lists, which
- // do not exist inside a block.
- //
-#if BLAH
- if (current_block != null){
- if (current_block.IsVariableDefined (name)){
- return new LocalVariableReference (current_block, name, loc);
- }
- }
-#endif
-
- if (current_local_parameters != null){
- int idx;
- Parameter par = current_local_parameters.GetParameterByName (name, out idx);
- if (par != null)
- return new ParameterReference (current_local_parameters, idx, name);
- }
-
- return null;
-}
-
Expression DecomposeQI (string name, Location loc)
{
Expression o;
if (name.IndexOf ('.') == -1){
- o = SimpleLookup (name, loc);
- if (o == null)
- return new SimpleName (name, loc);
- return o;
+ return new SimpleName (name, loc);
} else {
int pos = name.LastIndexOf (".");
string left = name.Substring (0, pos);
string right = name.Substring (pos + 1);
o = DecomposeQI (left, loc);
+
return new MemberAccess (o, right, loc);
}
}
}
-Block declare_local_variables (string type, ArrayList variable_declarators, Location loc)
+Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
{
Block implicit_block;
ArrayList inits = null;
inits = new ArrayList ();
inits.Add (decl);
}
- } else {
- Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
- "' is already defined in this scope");
}
}
} else {
ArrayList init = (ArrayList) decl.expression_or_array_initializer;
- string base_type = type.Substring (0, type.IndexOf ("["));
- string rank = type.Substring (type.IndexOf ("["));
-
- expr = new ArrayCreation (base_type, rank, init, decl.Location);
-
+ expr = new ArrayCreation (type, "", init, decl.Location);
}
LocalVariableReference var;
return implicit_block;
}
-Block declare_local_constant (string type, VariableDeclaration decl)
+Block declare_local_constant (Expression type, VariableDeclaration decl)
{
Block implicit_block;
if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
current_local_parameters, decl.Location))){
- Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
- "' is already defined in this scope");
}
return implicit_block;
current_container = RootContext.Tree.Types;
current_container.Namespace = current_namespace;
oob_stack = new Stack ();
+ switch_stack = new Stack ();
lexer = new Tokenizer (input, name, defines);
}
-public override int parse ()
+public override void parse ()
{
- StringBuilder value = new StringBuilder ();
-
- global_errors = 0;
try {
if (yacc_verbose_flag)
yyparse (lexer, new yydebug.yyDebugSimple ());
else
yyparse (lexer);
} catch (Exception e){
- // Console.WriteLine ("Fatal error: " + name);
- // Console.WriteLine (lexer.location);
-
- //
// Please do not remove this, it is used during debugging
// of the grammar
//
Console.WriteLine (lexer.location + " : Parsing error ");
Console.WriteLine (e);
- global_errors++;
}
-
- return global_errors;
}
/* end end end */