%{
//
-// 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
+// Possible optimization:
+// Run memory profiler with parsing only, and consider dropping
+// arraylists where not needed. Some pieces can use linked lists.
//
using System.Text;
+using System.IO;
using System;
namespace Mono.CSharp
Namespace current_namespace;
TypeContainer current_container;
+ IIteratorContainer iterator_container;
+
// <summary>
// Current block is used to add statements as we find
// them.
// 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;
+
+ //
+ // The current file.
+ //
+ SourceFile file;
%}
%token EOF
%token VOLATILE
%token WHILE
+/* v2 tokens */
+%token YIELD
+
/* C# keywords which are not really keywords */
%token GET "get"
%token SET "set"
%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 /* allow empty files */
+ ;
+
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.AddGlobalAttributeSection (current_container, asec);
+ else
+ Report.Error(1518, Lexer.Location,
+ "Attributes cannot be applied to namespaces."
+ + " Expected class, delegate, enum, interface, or struct");
+ }
+
+ current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (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 {
+ current_namespace.DeclarationFound = true;
}
- | namespace_declaration
;
type_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.AddGlobalAttributeSection (current_container, sect);
+
+
+ $$ = new Attributes ((AttributeSection) $1);
+ }
+ | 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.AddGlobalAttributeSection (current_container, sect);
- 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.AddAttributeSection (sect);
}
$$ = attrs;
;
attribute_section
- : OPEN_BRACKET attribute_target_specifier attribute_list CLOSE_BRACKET
+ : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
{
string target = null;
$$ = new AttributeSection (target, (ArrayList) $3);
}
- | OPEN_BRACKET attribute_list CLOSE_BRACKET
+ | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
{
$$ = new AttributeSection (null, (ArrayList) $2);
}
(Attributes) $1, lexer.Location);
current_container = new_struct;
current_container.Namespace = current_namespace;
- RootContext.Tree.RecordStruct (full_struct_name, new_struct);
+ 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);
}
;
method_declaration
- : method_header
+ : method_header {
+ iterator_container = (IIteratorContainer) $1;
+ }
method_body
{
Method method = (Method) $1;
- Block b = (Block) $2;
+ Block b = (Block) $3;
const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
if (b == null){
}
}
- method.Block = (Block) $2;
+ method.Block = (Block) $3;
CheckDef (current_container.AddMethod (method), method.Name, method.Location);
current_local_parameters = null;
+ iterator_container = null;
}
;
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
}
current_interface = new_interface;
new_interface.Namespace = current_namespace;
- RootContext.Tree.RecordInterface (full_interface_name, new_interface);
+ RootContext.Tree.RecordDecl (full_interface_name, new_interface);
}
opt_interface_base
interface_body opt_semicolon
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 c = (Constructor) $3;
c.Block = (Block) $4;
- c.ModFlags = (int) $2;
c.OptAttributes = (Attributes) $1;
-
- if ((c.ModFlags & Modifiers.STATIC) != 0){
- if ((c.ModFlags & Modifiers.Accessibility) != 0) {
- Report.Error (
- 515, c.Location,
- "Access modifiers are not allowed on static constructors");
- }
-
- if (c.Initializer != null){
- Report.Error (
- 514, c.Location,
- "Static constructors can not have an explicit this or base " +
- "constructor invocations");
+ c.ModFlags = (int) $2;
+
+ if (c.Name == current_container.Basename){
+ if ((c.ModFlags & Modifiers.STATIC) != 0){
+ if ((c.ModFlags & Modifiers.Accessibility) != 0){
+ Report.Error (
+ 515, c.Location, String.Format (
+ "`{0}.{1}': static constructor can not have access modifiers",
+ c.Name, current_container.Name));
+ }
+
+ c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
+
+ if (c.Initializer != null){
+ Report.Error (
+ 514, c.Location,
+ "Static constructors can not have an explicit this or base " +
+ "constructor invocations");
+ }
+
+ if (!c.Parameters.Empty){
+ Report.Error (
+ 132, c.Location, "Static constructors should not have parameters");
+ }
+ } else {
+ c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
}
+ } else {
+ // We let another layer check the validity of the constructor.
+ Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename);
+ }
- if (!c.Parameters.Empty){
- Report.Error (
- 132, c.Location, "Static constructors should not have parameters");
- }
- }
-
CheckDef (current_container.AddConstructor (c), c.Name, c.Location);
current_local_parameters = null;
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;
}
+ | opt_attributes ADD error {
+ Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
+ $$ = null;
+ }
;
remove_accessor_declaration
}
block
{
- $$ = $4;
+ $$ = new Accessor ((Block) $4, (Attributes) $1);
lexer.EventParsing = true;
}
+ | opt_attributes REMOVE error {
+ Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
+ $$ = null;
+ }
;
indexer_declaration
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);
}
e.Namespace = current_namespace;
CheckDef (current_container.AddEnum (e), full_name, enum_location);
- RootContext.Tree.RecordEnum (full_name, e);
+ RootContext.Tree.RecordDecl (full_name, e);
}
;
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 ((string) $4, (int) $2,
+ Delegate del = new Delegate (current_container, (Expression) $4, (int) $2,
MakeName ((string) $5), (Parameters) $7,
(Attributes) $1, l);
-
+ del.Namespace = current_namespace;
CheckDef (current_container.AddDelegate (del), del.Name, l);
}
| opt_attributes
{
Location l = lexer.Location;
Delegate del = new Delegate (
- "System.Void", (int) $2, MakeName ((string) $5), (Parameters) $7,
- (Attributes) $1, l);
+ current_container,
+ 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);
{
$$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
}
+
+ //
+ // We need this because the parser will happily go and reduce IDENTIFIER STAR
+ // through this different path
+ //
+ | multiplicative_expression STAR
+ {
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+ }
;
type_list
* 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);
}
;
{
if ($1 == null) {
Location l = lexer.Location;
- Report.Error (1, l, "THIS IS CRAZY");
+ Report.Error (1, l, "Parse error");
}
$$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
}
// Blah i;
Expression expr = (Expression) $1;
- if (!(expr is SimpleName || expr is MemberAccess)) {
- Location l = lexer.Location;
- Report.Error (-1, l, "Invalid Type definition");
- $$ = "System.Object";
+ if (expr is ComposedCast){
+ $$ = new ComposedCast (expr, (string) $2, lexer.Location);
+ } else if (!(expr is SimpleName || expr is MemberAccess)){
+ Error_ExpectingTypeName (lexer.Location, expr);
+ $$ = TypeManager.system_object_expr;
+ } else {
+ //
+ // So we extract the string corresponding to the SimpleName
+ // or MemberAccess
+ //
+ $$ = new ComposedCast (expr, (string) $2, lexer.Location);
}
-
- //
- // So we extract the string corresponding to the SimpleName
- // or MemberAccess
- //
- $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, 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
{
;
rank_specifiers
- : rank_specifier
- {
- $$ = $1;
- }
- | rank_specifiers rank_specifier
+ : rank_specifier opt_rank_specifier
{
$$ = (string) $2 + (string) $1;
- }
+ }
;
rank_specifier
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);
}
;
{
$$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location);
}
- | OPEN_PARENS expression CLOSE_PARENS unary_expression
+ | cast_expression
+ ;
+
+cast_expression
+ : OPEN_PARENS expression CLOSE_PARENS unary_expression
{
$$ = new Cast ((Expression) $2, (Expression) $4, 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);
}
;
(Attributes) $1, lexer.Location);
current_container = new_class;
current_container.Namespace = current_namespace;
- RootContext.Tree.RecordClass (name, new_class);
+ RootContext.Tree.RecordDecl (name, new_class);
}
opt_class_base
class_body
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
{
statement
: declaration_statement
{
- if ((Block) $1 != current_block){
+ if ($1 != null && (Block) $1 != current_block){
current_block.AddStatement ((Statement) $1);
current_block = (Block) $1;
}
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;
declaration_statement
: local_variable_declaration SEMICOLON
{
- DictionaryEntry de = (DictionaryEntry) $1;
+ if ($1 != null){
+ 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;
+ if ($1 != null){
+ DictionaryEntry de = (DictionaryEntry) $1;
- $$ = declare_local_constant ((string) de.Key, (VariableDeclaration) de.Value);
+ $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
+ }
}
;
// Blah i;
Expression expr = (Expression) $1;
- if (!(expr is SimpleName || expr is MemberAccess)) {
- Location l = lexer.Location;
- Report.Error (-1, l, "Invalid Type definition");
- $$ = "System.Object";
+ if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
+ Error_ExpectingTypeName (lexer.Location, expr);
+ $$ = null;
+ } else {
+ //
+ // So we extract the string corresponding to the SimpleName
+ // or MemberAccess
+ //
+
+ if ((string) $2 == "")
+ $$ = $1;
+ else
+ $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
}
-
- //
- // So we extract the string corresponding to the SimpleName
- // or MemberAccess
- //
- $$ = GetQualifiedIdentifier (expr) + (string) $2;
}
| builtin_types opt_rank_specifier
{
- $$ = (string) $1 + (string) $2;
+ if ((string) $2 == "")
+ $$ = $1;
+ else
+ $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
}
;
: primary_expression STAR
{
Expression expr = (Expression) $1;
- if (!(expr is SimpleName || expr is MemberAccess)) {
- Location l = lexer.Location;
- Report.Error (-1, l, "Invalid Type definition");
- $$ = "System.Object";
- }
-
- $$ = GetQualifiedIdentifier (expr) + "*";
+ Location l = lexer.Location;
+
+ if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
+ Error_ExpectingTypeName (l, expr);
+
+ $$ = null;
+ } else
+ $$ = new ComposedCast ((Expression) $1, "*", l);
}
| 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_declaration
: local_variable_type variable_declarators
{
- $$ = new DictionaryEntry ($1, $2);
+ if ($1 != null)
+ $$ = new DictionaryEntry ($1, $2);
+ else
+ $$ = null;
}
| local_variable_pointer_type opt_rank_specifier variable_declarators
{
- $$ = new DictionaryEntry ((string) $1 + (string) $2, $3);
+ if ($1 != null){
+ Expression t;
+
+ if ((string) $2 == "")
+ t = (Expression) $1;
+ else
+ t = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+ $$ = new DictionaryEntry (t, $3);
+ } else
+ $$ = null;
}
;
local_constant_declaration
: CONST local_variable_type constant_declarator
{
- $$ = new DictionaryEntry ($2, $3);
+ if ($2 != null)
+ $$ = new DictionaryEntry ($2, $3);
+ else
+ $$ = null;
}
;
: 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 ();
}
;
switch_section
: switch_labels
{
- current_block = new Block (current_block);
+ current_block = new Block (current_block, lexer.Location, lexer.Location);
}
statement_list
{
- while (current_block.Implicit)
- current_block = current_block.Parent;
- $$ = new SwitchSection ((ArrayList) $1, current_block);
- current_block = current_block.Parent;
+ Block topmost = current_block;
+
+ while (topmost.Implicit)
+ topmost = topmost.Parent;
+ $$ = new SwitchSection ((ArrayList) $1, topmost);
}
;
do_statement
: DO embedded_statement
- WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
+ WHILE OPEN_PARENS {
+ oob_stack.Push (lexer.Location);
+ }
+ boolean_expression CLOSE_PARENS SEMICOLON
{
- $$ = new Do ((Statement) $2, (Expression) $5, lexer.Location);
+ Location l = (Location) oob_stack.Pop ();
+
+ $$ = new Do ((Statement) $2, (Expression) $6, l);
}
;
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 if (decl.expression_or_array_initializer == null) {
+ expr = null;
} 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);
- }
-
- LocalVariableReference var;
- var = new LocalVariableReference (
- assign_block, decl.identifier, l);
+ 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);
+
+ if (expr != null) {
Assign a = new Assign (var, expr, decl.Location);
assign_block.AddStatement (new StatementExpression (a, lexer.Location));
: statement_expression
{
// CHANGE: was `null'
- Block b = new Block (current_block, true);
+ Block b = new Block (current_block, Block.Flags.Implicit);
b.AddStatement ((Statement) $1);
$$ = b;
{
oob_stack.Push (current_block);
- Block foreach_block = new Block (current_block, true);
- LocalVariableReference v;
+ Block foreach_block = new Block (current_block, Block.Flags.Implicit);
+ 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;
}
| goto_statement
| return_statement
| throw_statement
+ | yield_statement
;
break_statement
}
;
+yield_statement
+ : YIELD expression SEMICOLON
+ {
+ if (iterator_container == null){
+ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+ $$ = null;
+ } else {
+ iterator_container.SetYields ();
+ $$ = new Yield ((Expression) $2, lexer.Location);
+ }
+ }
+ | YIELD BREAK SEMICOLON
+ {
+ if (iterator_container == null){
+ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+ $$ = null;
+ } else {
+ iterator_container.SetYields ();
+ $$ = new YieldBreak (lexer.Location);
+ }
+ }
+ ;
+
opt_expression
: /* empty */
| expression
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;
}
fixed_statement
: FIXED OPEN_PARENS
- pointer_type fixed_pointer_declarators
+ type fixed_pointer_declarators
CLOSE_PARENS
{
- Block assign_block = new Block (current_block, true);
+ Block assign_block = new Block (current_block, Block.Flags.Implicit);
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;
}
+void Error_ExpectingTypeName (Location l, Expression expr)
+{
+ if (expr is Invocation){
+ Report.Error (1002, l, "; expected");
+ } else {
+ Report.Error (-1, l, "Invalid Type definition");
+ }
+}
+
// <summary>
// Given the @class_name name, it creates a fully qualified name
// based on the containing declaration space
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);
}
}
// This is necessary because local_variable_type admits primary_expression
// as the type of the variable. So we do some extra checking
// </summary>
+#if false
string GetQualifiedIdentifier (Expression expr)
{
if (expr is SimpleName)
throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
}
+#endif
-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;
//
// int j = 1; int k = j + 1;
//
- if (current_block.Used)
- implicit_block = new Block (current_block, true, loc, Location.Null);
- else
+ if (current_block.Used) {
+ implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
+ implicit_block.AddChildVariableNames (current_block);
+ } else
implicit_block = current_block;
foreach (VariableDeclaration decl in variable_declarators){
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 (current_block.Used)
- implicit_block = new Block (current_block, true);
+ implicit_block = new Block (current_block, Block.Flags.Implicit);
else
implicit_block = current_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;
}
}
-public CSharpParser (string name, System.IO.Stream input, ArrayList defines)
+public CSharpParser (StreamReader reader, SourceFile file, ArrayList defines)
{
- current_namespace = new Namespace (null, "");
- this.name = name;
- this.input = input;
+ current_namespace = new Namespace (null, file, "");
+ this.name = file.Name;
+ this.file = file;
current_container = RootContext.Tree.Types;
current_container.Namespace = current_namespace;
oob_stack = new Stack ();
+ switch_stack = new Stack ();
- lexer = new Tokenizer (input, name, defines);
+ lexer = new Tokenizer (reader, file, 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);
+ Tokenizer tokenizer = lexer as Tokenizer;
+ tokenizer.cleanup ();
} 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 ");
+ Report.Error (-25, lexer.Location, ": Parsing error ");
Console.WriteLine (e);
- global_errors++;
}
-
- return global_errors;
}
/* end end end */