%{
//
+// 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)
+// Ravi Pratap (ravi@ximian.com)
//
// Licensed under the terms of the GNU GPL
//
// separate problem
//
using System.Text;
-using CIR;
using System;
-namespace CIR
+namespace Mono.CSharp
{
using System.Collections;
using Mono.Languages;
// <summary>
// Using during property parsing to describe the implicit
- // value parameter that is passed to the "set" accesor
- // method
+ // value parameter that is passed to the "set" and "get"accesor
+ // methods (properties and indexers).
// </summary>
- Parameter [] implicit_value_parameters;
+ string implicit_value_parameter_type;
+ Parameters indexer_parameters;
// <summary>
// Used to determine if we are parsing the get/set pair
// </summmary>
bool parsing_indexer;
- // <summary>
- // Used to record all types defined
- // </summary>
- Tree tree;
-
- RootContext rc;
-
+ //
+ // An out-of-band stack.
+ //
+ Stack oob_stack;
%}
%token EOF
%token ABSTRACT
%token AS
%token ADD
+%token ASSEMBLY
%token BASE
%token BOOL
%token BREAK
%token SEALED
%token SHORT
%token SIZEOF
+%token STACKALLOC
%token STATIC
%token STRING
%token STRUCT
%token USING
%token VIRTUAL
%token VOID
+%token VOLATILE
%token WHILE
/* C# keywords which are not really keywords */
%nonassoc HIGHPREC
%start compilation_unit
-/*%start namespace_declaration */
%%
compilation_unit
- : opt_using_directives opt_attributes opt_namespace_member_declarations 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 IDENTIFIER ASSIGN
namespace_or_type_name SEMICOLON
{
- // FIXME : Need to implement actual action.
+ current_namespace.UsingAlias ((string) $2, (string) $4, 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 = new Namespace (current_namespace, (string) $2);
- tree.RecordNamespace ((string) $2, current_namespace);
- }
+ : opt_attributes NAMESPACE qualified_identifier
+ {
+ Attributes attrs = (Attributes) $1;
+
+ if (attrs != null) {
+ foreach (AttributeSection asec in attrs.AttributeSections)
+ if (asec.Target == "assembly")
+ RootContext.AddGlobalAttribute (asec, lexer.Location);
+ }
+
+ current_namespace = RootContext.Tree.RecordNamespace (current_namespace, name, (string) $3);
+ }
namespace_body opt_semicolon
{
current_namespace = current_namespace.Parent;
namespace_member_declaration
: type_declaration
{
- int mod_flags = 0;
string name = "";
+ int mod_flags;
if ($1 is Class){
Class c = (Class) $1;
} else
break;
- //
- // We remove this error until we can
- //if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
- // error (1527, "Namespace elements cant be explicitly " +
- // "declared private or protected in `" + name + "'");
- //}
+ if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+ Report.Error (
+ 1527, lexer.Location,
+ "Namespace elements cant be explicitly " +
+ "declared private or protected in `" + name + "'");
+ }
}
| namespace_declaration
;
| struct_declaration
| interface_declaration
| enum_declaration
- | delegate_declaration
+ | delegate_declaration
+//
+// Enable this when we have handled all errors, because this acts as a generic fallback
+//
+// | error {
+// Report.Error (1518, lexer.Location, "Expected class, struct, interface, enum or delegate");
+// }
;
//
// 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 (sect, lexer.Location);
+
+ $$ = new Attributes ((AttributeSection) $1, lexer.Location);
+ }
+ | attribute_sections attribute_section
{
- Attributes attrs;
-
- if ($2 != null) {
- attrs = (Attributes) $2;
- attrs.AddAttribute ((Attribute) $1);
- } else
- attrs = new Attributes ((Attribute) $1);
+ Attributes attrs = null;
+ AttributeSection sect = (AttributeSection) $2;
+
+ if (sect.Target == "assembly")
+ RootContext.AddGlobalAttribute (sect, lexer.Location);
+
+ if ($1 != null) {
+ attrs = (Attributes) $1;
+ attrs.AddAttribute (sect);
+ }
$$ = attrs;
}
if ($2 != null)
target = (string) $2;
- $$ = new Attribute (target, (ArrayList) $3);
+ $$ = new AttributeSection (target, (ArrayList) $3);
}
| OPEN_BRACKET attribute_list CLOSE_BRACKET
{
- $$ = new Attribute (null, (ArrayList) $2);
+ $$ = new AttributeSection (null, (ArrayList) $2);
}
;
;
attribute
- : attribute_name opt_attribute_arguments
+ : attribute_name
{
- $$ = new DictionaryEntry ($1, $2);
+ $$ = lexer.Location;
+ }
+ opt_attribute_arguments
+ {
+ $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
}
;
}
;
+
attribute_arguments
- : expression
+ : opt_positional_argument_list
+ {
+ if ($1 == null)
+ $$ = null;
+ else {
+ ArrayList args = new ArrayList ();
+ args.Add ($1);
+
+ $$ = args;
+ }
+ }
+ | positional_argument_list COMMA named_argument_list
{
ArrayList args = new ArrayList ();
args.Add ($1);
+ args.Add ($3);
+
+ $$ = args;
+ }
+ | named_argument_list
+ {
+ ArrayList args = new ArrayList ();
+ args.Add (null);
+ args.Add ($1);
$$ = args;
}
- | attribute_arguments COMMA expression
+ ;
+
+
+opt_positional_argument_list
+ : /* empty */ { $$ = null; }
+ | positional_argument_list
+ ;
+
+positional_argument_list
+ : expression
+ {
+ ArrayList args = new ArrayList ();
+ args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
+
+ $$ = args;
+ }
+ | positional_argument_list COMMA expression
+ {
+ ArrayList args = (ArrayList) $1;
+ args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
+
+ $$ = args;
+ }
+ ;
+
+named_argument_list
+ : named_argument
{
+ ArrayList args = new ArrayList ();
+ args.Add ($1);
+
+ $$ = args;
+ }
+ | named_argument_list COMMA named_argument
+ {
ArrayList args = (ArrayList) $1;
args.Add ($3);
$$ = args;
}
- ;
+ ;
+named_argument
+ : IDENTIFIER ASSIGN expression
+ {
+ $$ = new DictionaryEntry (
+ (string) $1,
+ new Argument ((Expression) $3, Argument.AType.Expression));
+ }
+ ;
+
class_body
: OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
;
Struct new_struct;
string full_struct_name = MakeName ((string) $4);
- new_struct = new Struct (rc, current_container, full_struct_name, (int) $2,
+ new_struct = new Struct (current_container, full_struct_name, (int) $2,
(Attributes) $1, lexer.Location);
current_container = new_struct;
current_container.Namespace = current_namespace;
- tree.RecordStruct (full_struct_name, new_struct);
+ RootContext.Tree.RecordDecl (full_struct_name, new_struct);
}
opt_struct_interfaces
struct_body
Struct new_struct = (Struct) current_container;
current_container = current_container.Parent;
- CheckDef (current_container.AddStruct (new_struct), new_struct.Name);
+ CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
$$ = new_struct;
}
;
| operator_declaration
| constructor_declaration
| type_declaration
+
+ /*
+ * This is only included so we can flag error 575:
+ * destructors only allowed on class types
+ */
+ | destructor_declaration
;
constant_declaration
constant_declarators
SEMICOLON
{
- foreach (DictionaryEntry constant in (ArrayList) $5){
- Constant c = new Constant (
- (string) $4, (string) constant.Key,
- (Expression) constant.Value, (int) $2, (Attributes) $1);
+ foreach (VariableDeclaration constant in (ArrayList) $5){
+ Location l = constant.Location;
+
+ Const c = new Const (
+ (string) $4, (string) constant.identifier,
+ (Expression) constant.expression_or_array_initializer, (int) $2,
+ (Attributes) $1, l);
- CheckDef (current_container.AddConstant (c), c.Name);
+ CheckDef (current_container.AddConstant (c), c.Name, l);
}
}
;
constant_declarator
: IDENTIFIER ASSIGN constant_expression
{
- $$ = new DictionaryEntry ($1, $3);
+ $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
}
;
type
variable_declarators
SEMICOLON
- {
+ {
string type = (string) $3;
int mod = (int) $2;
foreach (VariableDeclaration var in (ArrayList) $4){
+ Location l = var.Location;
+
Field field = new Field (type, mod, var.identifier,
- var.expression_or_array_initializer, (Attributes) $1);
+ var.expression_or_array_initializer,
+ (Attributes) $1, l);
- CheckDef (current_container.AddField (field), field.Name);
+ CheckDef (current_container.AddField (field), field.Name, l);
}
- }
-
+ }
;
variable_declarators
$$ = $1;
}
| array_initializer
- {
+ {
$$ = $1;
- }
+ }
+ | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
+ {
+ $$ = new StackAlloc ((string) $2, (Expression) $4, lexer.Location);
+ }
;
method_declaration
{
Method method = (Method) $1;
Block b = (Block) $2;
-
+ const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
+
if (b == null){
- if ((method.ModFlags & (Modifiers.EXTERN | Modifiers.ABSTRACT)) == 0){
+ if ((method.ModFlags & extern_abstract) == 0){
Report.Error (
- 501, lexer.Location, "`" +
- current_container.Name + "." + method.Name + "'" +
+ 501, lexer.Location, current_container.MakeName (method.Name) +
"must declare a body because it is not marked abstract or extern");
}
+ } else {
+ if ((method.ModFlags & Modifiers.EXTERN) != 0){
+ Report.Error (
+ 179, lexer.Location, current_container.MakeName (method.Name) +
+ " is declared extern, but has a body");
+ }
}
method.Block = (Block) $2;
- CheckDef (current_container.AddMethod (method), method.Name);
+ CheckDef (current_container.AddMethod (method), method.Name, method.Location);
current_local_parameters = null;
}
;
+opt_error_modifier
+ : /* empty */
+ | modifiers
+ {
+ int m = (int) $1;
+ int i = 1;
+
+ while (m != 0){
+ if ((i & m) != 0){
+ Report.Error (
+ 1585, lexer.Location, "Member modifier `" +
+ Modifiers.Name (i) + "' must precede member type and name");
+ }
+ m &= ~i;
+ i = i << 1;
+ }
+ }
+ ;
+
method_header
: opt_attributes
opt_modifiers
;
opt_formal_parameter_list
- : /* empty */ { $$ = new Parameters (null, null); }
+ : /* empty */ { $$ = Parameters.GetEmptyReadOnlyParameters (); }
| formal_parameter_list
;
Parameter [] pars = new Parameter [pars_list.Count];
pars_list.CopyTo (pars);
- $$ = new Parameters (pars, null);
+ $$ = new Parameters (pars, null, lexer.Location);
}
| fixed_parameters COMMA parameter_array
{
Parameter [] pars = new Parameter [pars_list.Count];
pars_list.CopyTo (pars);
- $$ = new Parameters (pars, (Parameter) $3);
+ $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
}
| parameter_array
{
- $$ = new Parameters (null, (Parameter) $1);
+ $$ = new Parameters (null, (Parameter) $1, lexer.Location);
}
;
;
member_name
- : IDENTIFIER { $$ = $1.ToString (); }
- | interface_type DOT IDENTIFIER { $$ = $1.ToString () + "." + $3.ToString (); }
+ : qualified_identifier
;
property_declaration
type member_name
OPEN_BRACE
{
- Parameter implicit_value_parameter;
- implicit_value_parameter = new Parameter ((string) $3, "value", Parameter.Modifier.NONE, null);
+ implicit_value_parameter_type = (string) $3;
- lexer.properties = true;
-
- implicit_value_parameters = new Parameter [1];
- implicit_value_parameters [0] = implicit_value_parameter;
+ lexer.PropertyParsing = true;
+
+ $$ = lexer.Location;
}
accessor_declarations
{
- lexer.properties = false;
+ lexer.PropertyParsing = false;
}
CLOSE_BRACE
{
Property prop;
- DictionaryEntry pair = (DictionaryEntry) $7;
+ Pair pair = (Pair) $7;
Block get_block = null;
Block set_block = null;
- if (pair.Key != null)
- get_block = (Block) pair.Key;
- if (pair.Value != null)
- set_block = (Block) pair.Value;
+ if (pair.First != null)
+ get_block = (Block) pair.First;
+ if (pair.Second != null)
+ set_block = (Block) pair.Second;
- prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block, (Attributes) $1);
+ Location loc = (Location) $6;
+ prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block,
+ (Attributes) $1, loc);
- CheckDef (current_container.AddProperty (prop), prop.Name);
- implicit_value_parameters = null;
+ CheckDef (current_container.AddProperty (prop), prop.Name, loc);
+ implicit_value_parameter_type = null;
}
;
accessor_declarations
: get_accessor_declaration opt_set_accessor_declaration
{
- $$ = new DictionaryEntry ($1, $2);
+ $$ = new Pair ($1, $2);
}
| set_accessor_declaration opt_get_accessor_declaration
{
- $$ = new DictionaryEntry ($2, $1);
+ $$ = new Pair ($2, $1);
}
;
{
// If this is not the case, then current_local_parameters has already
// been set in indexer_declaration
- if (parsing_indexer == false)
- current_local_parameters = new Parameters (implicit_value_parameters, null);
-
-
+ if (parsing_indexer == false)
+ current_local_parameters = null;
+ else
+ current_local_parameters = indexer_parameters;
+ lexer.PropertyParsing = false;
}
accessor_body
{
$$ = $4;
current_local_parameters = null;
+ lexer.PropertyParsing = true;
}
;
set_accessor_declaration
: opt_attributes SET
{
- if (parsing_indexer == false)
- current_local_parameters = new Parameters (implicit_value_parameters, null);
+ Parameter [] args;
+ Parameter implicit_value_parameter = new Parameter (
+ implicit_value_parameter_type, "value",
+ Parameter.Modifier.NONE, null);
+
+ if (parsing_indexer == false) {
+ args = new Parameter [1];
+ args [0] = implicit_value_parameter;
+ } else {
+ Parameter [] fp = indexer_parameters.FixedParameters;
+ int count = fp.Length;
+
+ args = new Parameter [count + 1];
+
+ fp.CopyTo (args, 0);
+ args [count] = implicit_value_parameter;
+ }
+
+ current_local_parameters = new Parameters (args, null, lexer.Location);
+ lexer.PropertyParsing = false;
}
accessor_body
{
$$ = $4;
current_local_parameters = null;
+ lexer.PropertyParsing = true;
}
;
accessor_body
: block
- | SEMICOLON { $$ = new Block (null); }
+ | SEMICOLON { $$ = null; }
;
interface_declaration
Interface new_interface;
string full_interface_name = MakeName ((string) $4);
- new_interface = new Interface (rc, current_container, full_interface_name, (int) $2,
+ new_interface = new Interface (current_container, full_interface_name, (int) $2,
(Attributes) $1, lexer.Location);
if (current_interface != null) {
Location l = lexer.Location;
Report.Error (-2, l, "Internal compiler error: interface inside interface");
}
current_interface = new_interface;
- tree.RecordInterface (full_interface_name, new_interface);
+ new_interface.Namespace = current_namespace;
+ RootContext.Tree.RecordDecl (full_interface_name, new_interface);
}
opt_interface_base
- interface_body
+ interface_body opt_semicolon
{
Interface new_interface = (Interface) current_interface;
new_interface.Bases = (ArrayList) $6;
current_interface = null;
- CheckDef (current_container.AddInterface (new_interface), new_interface.Name);
+ CheckDef (current_container.AddInterface (new_interface),
+ new_interface.Name, new_interface.Location);
}
;
{
InterfaceMethod m = (InterfaceMethod) $1;
- CheckDef (current_interface.AddMethod (m), m.Name);
+ CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
}
| interface_property_declaration
{
InterfaceProperty p = (InterfaceProperty) $1;
- CheckDef (current_interface.AddProperty (p), p.Name);
+ CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
}
| interface_event_declaration
{
InterfaceEvent e = (InterfaceEvent) $1;
- CheckDef (current_interface.AddEvent (e), e.Name);
+ CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
}
| interface_indexer_declaration
{
InterfaceIndexer i = (InterfaceIndexer) $1;
- CheckDef (current_interface.AddIndexer (i), "indexer");
+ CheckDef (current_interface.AddIndexer (i), "indexer", i.Location);
}
;
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
SEMICOLON
{
- $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2, (Parameters) $6, (Attributes) $1);
+ $$ = new InterfaceMethod ((string) $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, (Attributes) $1);
+ $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6,
+ (Attributes) $1, lexer.Location);
}
;
opt_new
type IDENTIFIER
OPEN_BRACE
- { lexer.properties = true; }
+ { lexer.PropertyParsing = true; }
interface_accesors
- { lexer.properties = false; }
+ { lexer.PropertyParsing = false; }
CLOSE_BRACE
{
int gs = (int) $7;
$$ = new InterfaceProperty ((string) $3, (string) $4, (bool) $2,
- (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1);
+ (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1,
+ lexer.Location);
}
;
: opt_attributes opt_new type THIS
OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
OPEN_BRACE
- { lexer.properties = true; }
+ { lexer.PropertyParsing = true; }
interface_accesors
- { lexer.properties = false; }
+ { lexer.PropertyParsing = false; }
CLOSE_BRACE
{
int a_flags = (int) $10;
bool do_get = (a_flags & 1) == 1;
bool do_set = (a_flags & 2) == 2;
- $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set, (bool) $2, (Attributes) $1);
+ $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set,
+ (bool) $2, (Attributes) $1, lexer.Location);
}
;
operator_declaration
- : opt_attributes opt_modifiers operator_declarator block
+ : opt_attributes opt_modifiers operator_declarator operator_body
{
OperatorDeclaration decl = (OperatorDeclaration) $3;
// Note again, checking is done in semantic analysis
current_container.AddOperator (op);
+
+ current_local_parameters = null;
}
;
+operator_body
+ : block
+ | SEMICOLON { $$ = null; }
+ ;
operator_declarator
: type OPERATOR overloadable_operator
OPEN_PARENS type IDENTIFIER CLOSE_PARENS
if (op == Operator.OpType.Subtraction)
op = Operator.OpType.UnaryNegation;
+ Parameter [] pars = new Parameter [1];
+
+ pars [0] = new Parameter ((string) $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,
null, null, lexer.Location);
}
CLOSE_PARENS
{
CheckBinaryOperator ((Operator.OpType) $3);
+
+ 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);
+
+ 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);
conversion_operator_declarator
: IMPLICIT 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);
+
+ current_local_parameters = new Parameters (pars, null, lexer.Location);
+
$$ = new OperatorDeclaration (Operator.OpType.Implicit, (string) $3, (string) $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);
+
+ current_local_parameters = new Parameters (pars, null, lexer.Location);
+
$$ = new OperatorDeclaration (Operator.OpType.Explicit, (string) $3, (string) $5, (string) $6,
null, null, lexer.Location);
}
+ | IMPLICIT error
+ {
+ syntax_error (lexer.Location, "'operator' expected");
+ }
+ | EXPLICIT error
+ {
+ syntax_error (lexer.Location, "'operator' expected");
+ }
;
constructor_declaration
: opt_attributes
opt_modifiers
constructor_declarator
- block
+ constructor_body
{
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) {
- Location l = lexer.Location;
- Report.Error (515, l, "Access modifiers are not allowed on static constructors");
+ Report.Error (
+ 515, c.Location,
+ "Access modifiers are not allowed on static constructors");
}
if (c.Initializer != null){
- Location l = lexer.Location;
- Report.Error (514, l, "Static constructors can not have an explicit this or base constructor invocations");
+ Report.Error (
+ 514, c.Location,
+ "Static constructors can not have an explicit this or base " +
+ "constructor invocations");
}
if (!c.Parameters.Empty){
- Location l = lexer.Location;
- Report.Error (103, l, "Static constructors should not have parameters");
+ Report.Error (
+ 132, c.Location, "Static constructors should not have parameters");
}
}
- CheckDef (current_container.AddConstructor (c), c.Name);
+ CheckDef (current_container.AddConstructor (c), c.Name, c.Location);
current_local_parameters = null;
}
constructor_declarator
: IDENTIFIER
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
- opt_constructor_initializer
{
- Location l = lexer.Location;
+ oob_stack.Push (lexer.Location);
- $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $5, l);
-
current_local_parameters = (Parameters) $3;
}
+ opt_constructor_initializer
+ {
+ Location l = (Location) oob_stack.Pop ();
+ $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $6, l);
+ }
+ ;
+
+constructor_body
+ : block
+ | SEMICOLON { $$ = null; }
;
opt_constructor_initializer
destructor_declaration
: opt_attributes TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
{
- Method d = new Method ("System.Void", 0, "Finalize",
- new Parameters (null, null), (Attributes) $1, lexer.Location);
+ if ((string) $3 != current_container.Basename){
+ Report.Error (574, lexer.Location, "Name of destructor must match name of class");
+ } else if (!(current_container is Class)){
+ Report.Error (575, lexer.Location, "Destructors are only allowed in class types");
+ } else {
+ Location l = lexer.Location;
+
+ Method d = new Method (
+ "System.Void",
+ Modifiers.PROTECTED | Modifiers.OVERRIDE,
+ "Finalize",
+ new Parameters (null, null, l), (Attributes) $1, l);
- d.Block = (Block) $6;
- CheckDef (current_container.AddMethod (d), d.Name);
+ d.Block = (Block) $6;
+ CheckDef (current_container.AddMethod (d), d.Name, d.Location);
+ }
}
;
{
foreach (VariableDeclaration var in (ArrayList) $5) {
- // FIXME : Is this right ?
Event e = new Event ((string) $4, var.identifier, var.expression_or_array_initializer,
- (int) $2, null, null, (Attributes) $1);
+ (int) $2, null, null, (Attributes) $1, lexer.Location);
- CheckDef (current_container.AddEvent (e), e.Name);
+ CheckDef (current_container.AddEvent (e), e.Name, e.Location);
}
}
| opt_attributes
opt_modifiers
- EVENT type member_name
- OPEN_BRACE event_accessor_declarations CLOSE_BRACE
- {
- DictionaryEntry pair = (DictionaryEntry) $7;
+ EVENT type member_name
+ OPEN_BRACE
+ {
+ implicit_value_parameter_type = (string) $4;
+ lexer.EventParsing = true;
+ oob_stack.Push (lexer.Location);
+ }
+ event_accessor_declarations
+ {
+ lexer.EventParsing = false;
+ }
+ CLOSE_BRACE
+ {
+ Location loc = (Location) oob_stack.Pop ();
+
+ Pair pair = (Pair) $8;
Block add_block = null;
Block rem_block = null;
- if (pair.Key != null)
- add_block = (Block) pair.Key;
- if (pair.Value != null)
- rem_block = (Block) pair.Value;
+ if (pair.First != null)
+ add_block = (Block) pair.First;
+ if (pair.Second != null)
+ rem_block = (Block) pair.Second;
- Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_block, rem_block, (Attributes) $1);
+ Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_block, rem_block,
+ (Attributes) $1, loc);
- CheckDef (current_container.AddEvent (e), e.Name);
- }
+ CheckDef (current_container.AddEvent (e), e.Name, loc);
+ implicit_value_parameter_type = null;
+ }
;
event_accessor_declarations
: add_accessor_declaration remove_accessor_declaration
{
- $$ = new DictionaryEntry ($1, $2);
+ $$ = new Pair ($1, $2);
}
| remove_accessor_declaration add_accessor_declaration
{
- $$ = new DictionaryEntry ($2, $1);
+ $$ = new Pair ($2, $1);
}
;
add_accessor_declaration
- : opt_attributes ADD block
+ : opt_attributes ADD
+ {
+ Parameter [] args = new Parameter [1];
+ Parameter implicit_value_parameter = new Parameter (
+ implicit_value_parameter_type, "value",
+ Parameter.Modifier.NONE, null);
+
+ args [0] = implicit_value_parameter;
+
+ current_local_parameters = new Parameters (args, null, lexer.Location);
+ lexer.EventParsing = false;
+ }
+ block
{
- $$ = $3;
+ $$ = $4;
+ lexer.EventParsing = true;
}
;
remove_accessor_declaration
- : opt_attributes REMOVE block
- {
- $$ = $3;
- }
+ : opt_attributes REMOVE
+ {
+ Parameter [] args = new Parameter [1];
+ Parameter implicit_value_parameter = new Parameter (
+ implicit_value_parameter_type, "value",
+ Parameter.Modifier.NONE, null);
+
+ args [0] = implicit_value_parameter;
+
+ current_local_parameters = new Parameters (args, null, lexer.Location);
+ lexer.EventParsing = false;
+ }
+ block
+ {
+ $$ = $4;
+ lexer.EventParsing = true;
+ }
;
indexer_declaration
OPEN_BRACE
{
IndexerDeclaration decl = (IndexerDeclaration) $3;
-
- lexer.properties = true;
+
+ implicit_value_parameter_type = decl.type;
+
+ lexer.PropertyParsing = true;
parsing_indexer = true;
- current_local_parameters = decl.param_list;
+ indexer_parameters = decl.param_list;
+ $$ = lexer.Location;
}
accessor_declarations
{
- lexer.properties = false;
+ lexer.PropertyParsing = false;
parsing_indexer = false;
}
CLOSE_BRACE
Indexer indexer;
IndexerDeclaration decl = (IndexerDeclaration) $3;
- DictionaryEntry pair = (DictionaryEntry) $6;
+ Pair pair = (Pair) $6;
Block get_block = null;
Block set_block = null;
- if (pair.Key != null)
- get_block = (Block) pair.Key;
- if (pair.Value != null)
- set_block = (Block) pair.Value;
+ if (pair.First != null)
+ get_block = (Block) pair.First;
+ if (pair.Second != null)
+ set_block = (Block) pair.Second;
indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list,
- get_block, set_block, (Attributes) $1);
+ get_block, set_block, (Attributes) $1, (Location) $5);
// Note that there is no equivalent of CheckDef for this case
// We shall handle this in semantic analysis
current_container.AddIndexer (indexer);
current_local_parameters = null;
+ implicit_value_parameter_type = null;
+ indexer_parameters = null;
}
;
indexer_declarator
- : type THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
+ : type THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
{
- $$ = new IndexerDeclaration ((string) $1, null, (Parameters) $4);
+ Parameters pars = (Parameters) $4;
+
+ if (pars.FixedParameters == null){
+ Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
+ }
+
+ $$ = new IndexerDeclaration ((string) $1, null, pars);
}
- | type interface_type DOT THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
+ | type qualified_identifier DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
{
- $$ = new IndexerDeclaration ((string) $1, (string) $2, (Parameters) $6);
+ Parameters pars = (Parameters) $6;
+
+ if (pars.FixedParameters == null){
+ Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
+ }
+ $$ = new IndexerDeclaration ((string) $1, (string) $2, pars);
}
;
enum_declaration
: opt_attributes
opt_modifiers
- ENUM IDENTIFIER
+ ENUM IDENTIFIER
opt_enum_base
enum_body
opt_semicolon
{
- string name = (string) $4;
- Enum e = new Enum ((string) $5, (int) $2, name, (Attributes) $1, lexer.Location);
+ 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){
+ Location loc = (Location) ev.Location;
+
CheckDef (e.AddEnumMember (ev.identifier,
- (Expression) ev.expression_or_array_initializer),
- ev.identifier);
+ (Expression) ev.expression_or_array_initializer,
+ loc),
+ ev.identifier, loc);
}
- CheckDef (current_container.AddEnum (e), name);
+ e.Namespace = current_namespace;
+
+ CheckDef (current_container.AddEnum (e), full_name, enum_location);
+ RootContext.Tree.RecordDecl (full_name, e);
+
}
;
opt_enum_base
- : /* empty */ { $$ = "System.Int32"; }
- | COLON integral_type { $$ = $2; }
+ : /* empty */ { $$ = "System.Int32"; }
+ | COLON type { $$ = $2; }
;
enum_body
{
$$ = new VariableDeclaration ((string) $2, null, lexer.Location);
}
- | opt_attributes IDENTIFIER ASSIGN expression
+ | opt_attributes IDENTIFIER
+ {
+ $$ = lexer.Location;
+ }
+ ASSIGN expression
{
- $$ = new VariableDeclaration ((string) $2, $4, lexer.Location);
+ $$ = new VariableDeclaration ((string) $2, $5, lexer.Location);
}
;
opt_modifiers
DELEGATE type
IDENTIFIER OPEN_PARENS
- formal_parameter_list
+ opt_formal_parameter_list
CLOSE_PARENS
SEMICOLON
{
- Delegate del = new Delegate (rc, (string) $4, (int) $2,
+ Location l = lexer.Location;
+ Delegate del = new Delegate (current_container, (string) $4, (int) $2,
MakeName ((string) $5), (Parameters) $7,
- (Attributes) $1, lexer.Location);
+ (Attributes) $1, l);
- CheckDef (current_container.AddDelegate (del), del.Name);
+ del.Namespace = current_namespace;
+ CheckDef (current_container.AddDelegate (del), del.Name, l);
}
| opt_attributes
opt_modifiers
DELEGATE VOID
IDENTIFIER OPEN_PARENS
- formal_parameter_list
+ opt_formal_parameter_list
CLOSE_PARENS
SEMICOLON
{
- Delegate del = new Delegate (rc, "System.Void", (int) $2, (string) $5, (Parameters) $7,
- (Attributes) $1, lexer.Location);
+ Location l = lexer.Location;
+ Delegate del = new Delegate (
+ current_container,
+ "System.Void", (int) $2, MakeName ((string) $5), (Parameters) $7,
+ (Attributes) $1, l);
- CheckDef (current_container.AddDelegate (del), del.Name);
+ del.Namespace = current_namespace;
+ CheckDef (current_container.AddDelegate (del), del.Name, l);
}
;
}
| builtin_types
| array_type
+ | pointer_type
+ ;
+
+
+pointer_type
+ : type STAR
+ {
+ //
+ // Note that here only unmanaged types are allowed but we
+ // can't perform checks during this phase - we do it during
+ // semantic analysis.
+ //
+ $$ = (string) $1 + "*";
+ }
+ | VOID STAR
+ {
+ $$ = "System.Void*";
+ }
+ ;
+
+non_expression_type
+ : builtin_types
+ {
+ $$ = new SimpleName ((string) $1, lexer.Location);
+ }
+ | non_expression_type rank_specifier
+ {
+ $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+ }
+ | non_expression_type STAR
+ {
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+ }
+ | expression rank_specifiers
+ {
+ $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+ }
+ | expression STAR
+ {
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+ }
;
type_list
| LONG { $$ = "System.Int64"; }
| ULONG { $$ = "System.UInt64"; }
| CHAR { $$ = "System.Char"; }
+ | VOID { $$ = "System.Void"; }
;
interface_type
| sizeof_expression
| checked_expression
| unchecked_expression
+ | pointer_member_access
+ // TODO: pointer_element_access
+ // TODO: sizeof-expression
;
literal
| real_literal
| LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
| LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
- | NULL { $$ = new NullLiteral (); }
+ | NULL { $$ = NullLiteral.Null; }
;
real_literal
}
| predefined_type DOT IDENTIFIER
{
- $$ = new SimpleName ((string) $1 + "." + (string) $3, lexer.Location);
+ $$ = new MemberAccess (new SimpleName ((string) $1, lexer.Location), (string) $3, lexer.Location);
}
;
invocation_expression
: primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
{
- // FIXME:
- // if $1 is MethodGroup
- // $$ = new Call ($1, $3);
- // else
- // $$ = new DelegateCall ($1, $3);
if ($1 == null) {
Location l = lexer.Location;
Report.Error (1, l, "THIS IS CRAZY");
}
$$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
-
}
;
{
$$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
}
+ | primary_expression rank_specifiers
+ {
+ // So the super-trick is that primary_expression
+ // can only be either a SimpleName or a MemberAccess.
+ // The MemberAccess case arises when you have a fully qualified type-name like :
+ // Foo.Bar.Blah i;
+ // SimpleName is when you have
+ // 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";
+ }
+
+ //
+ // So we extract the string corresponding to the SimpleName
+ // or MemberAccess
+ //
+ $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
+ }
;
expression_list
base_access
: BASE DOT IDENTIFIER
{
- $$ = new BaseAccess (BaseAccess.BaseAccessType.Member, (string) $3, null);
+ $$ = new BaseAccess ((string) $3, lexer.Location);
}
| BASE OPEN_BRACKET expression_list CLOSE_BRACKET
{
- $$ = new BaseAccess (BaseAccess.BaseAccessType.Indexer, null, (ArrayList) $3);
+ $$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location);
}
;
post_increment_expression
: primary_expression OP_INC
{
- $$ = new Unary (Unary.Operator.PostIncrement, (Expression) $1, lexer.Location);
+ $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement,
+ (Expression) $1, lexer.Location);
}
;
post_decrement_expression
: primary_expression OP_DEC
{
- $$ = new Unary (Unary.Operator.PostDecrement, (Expression) $1, lexer.Location);
+ $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement,
+ (Expression) $1, lexer.Location);
}
;
opt_rank_specifier
opt_array_initializer
{
- $$ = new New ((string) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, lexer.Location);
+ $$ = new ArrayCreation ((string) $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 type error
+ {
+ Report.Error (1526, lexer.Location, "new expression requires () or [] after type");
}
;
typeof_expression
: TYPEOF OPEN_PARENS type CLOSE_PARENS
{
- $$ = new TypeOf ((string) $3);
+ $$ = new TypeOf ((string) $3, lexer.Location);
}
;
sizeof_expression
: SIZEOF OPEN_PARENS type CLOSE_PARENS {
- $$ = new SizeOf ((string) $3);
+ $$ = new SizeOf ((string) $3, lexer.Location);
note ("Verify type is unmanaged");
note ("if (5.8) builtin, yield constant expression");
}
;
+pointer_member_access
+ : primary_expression OP_PTR IDENTIFIER
+ {
+ Expression deref;
+
+ deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lexer.Location);
+ $$ = new MemberAccess (deref, (string) $3, lexer.Location);
+ }
+
unary_expression
: primary_expression
- | PLUS unary_expression
+ | BANG prefixed_unary_expression
+ {
+ $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
+ }
+ | TILDE prefixed_unary_expression
+ {
+ $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location);
+ }
+ | OPEN_PARENS expression CLOSE_PARENS unary_expression
+ {
+ $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
+ }
+ | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
+ {
+ $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
+ }
+ ;
+
+ //
+ // The idea to split this out is from Rhys' grammar
+ // to solve the problem with casts.
+ //
+prefixed_unary_expression
+ : unary_expression
+ | PLUS prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
}
- | MINUS unary_expression
+ | MINUS prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
}
- | BANG unary_expression
+ | OP_INC prefixed_unary_expression
{
- $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
+ $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
+ (Expression) $2, lexer.Location);
}
- | TILDE unary_expression
+ | OP_DEC prefixed_unary_expression
{
- $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location);
+ $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
+ (Expression) $2, lexer.Location);
}
- | STAR unary_expression
+ | STAR prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.Indirection, (Expression) $2, lexer.Location);
}
- | BITWISE_AND unary_expression
+ | BITWISE_AND prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, lexer.Location);
}
- | OP_INC unary_expression
- {
- $$ = new Unary (Unary.Operator.PreIncrement, (Expression) $2, lexer.Location);
- }
- | OP_DEC unary_expression
- {
- $$ = new Unary (Unary.Operator.PreDecrement, (Expression) $2, lexer.Location);
- }
- | cast_expression
- /*
- we can not do cast expressions at this level,
- as there is an ambiguity. Check "Cast Expressions" 7.6.8
- for the recipe to handle this.
- */
;
pre_increment_expression
- : OP_INC unary_expression
+ : OP_INC prefixed_unary_expression
{
- $$ = new Unary (Unary.Operator.PreIncrement, (Expression) $2, lexer.Location);
+ $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
+ (Expression) $2, lexer.Location);
}
;
pre_decrement_expression
- : OP_DEC unary_expression
+ : OP_DEC prefixed_unary_expression
{
- $$ = new Unary (Unary.Operator.PreDecrement, (Expression) $2, lexer.Location);
- }
- ;
-
-cast_expression
- /*
- * FIXME: This is actually wrong, it should be `type' but that
- * introduces a lot of {shift,reduce}/reduces
- *
- * This is really really wrong. We need to track down
- * the source of problems with QIs because expressions like:
- * foreach (string s in (string []) object) wont be parsed.
- */
- : OPEN_PARENS qualified_identifier CLOSE_PARENS unary_expression
- {
- $$ = new Cast ((string) $2, (Expression) $4, lexer.Location);
- }
- | OPEN_PARENS builtin_types CLOSE_PARENS unary_expression
- {
- $$ = new Cast ((string) $2, (Expression) $4, lexer.Location);
+ $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
+ (Expression) $2, lexer.Location);
}
;
multiplicative_expression
- : unary_expression
- | multiplicative_expression STAR unary_expression
+ : prefixed_unary_expression
+ | multiplicative_expression STAR prefixed_unary_expression
{
$$ = new Binary (Binary.Operator.Multiply,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | multiplicative_expression DIV unary_expression
+ | multiplicative_expression DIV prefixed_unary_expression
{
$$ = new Binary (Binary.Operator.Division,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | multiplicative_expression PERCENT unary_expression
+ | multiplicative_expression PERCENT prefixed_unary_expression
{
$$ = new Binary (Binary.Operator.Modulus,
(Expression) $1, (Expression) $3, lexer.Location);
}
| relational_expression IS type
{
- $$ = new Probe (Probe.Operator.Is,
- (Expression) $1, (string) $3);
+ $$ = new Is ((Expression) $1, (string) $3, lexer.Location);
}
| relational_expression AS type
{
- $$ = new Probe (Probe.Operator.As,
- (Expression) $1, (string) $3);
+ $$ = new As ((Expression) $1, (string) $3, lexer.Location);
}
;
;
assignment_expression
- : unary_expression ASSIGN expression
+ : prefixed_unary_expression ASSIGN expression
{
$$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
}
- | unary_expression OP_MULT_ASSIGN expression
+ | prefixed_unary_expression OP_MULT_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Multiply,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.Multiply,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_DIV_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.Division,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_MOD_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.Modulus,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_ADD_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.Addition,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_SUB_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.Subtraction,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_SHIFT_LEFT_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.LeftShift,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_SHIFT_RIGHT_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.RightShift,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_AND_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.BitwiseAnd,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_OR_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.BitwiseOr,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
- | unary_expression OP_XOR_ASSIGN expression
+ | 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 (
+ (Expression) $1,
+ new Binary (Binary.Operator.ExclusiveOr,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
;
;
boolean_expression
- : expression { CheckBoolean ((Expression) $1); $$ = $1; }
+ : expression
;
//
CLASS IDENTIFIER
{
Class new_class;
- string full_class_name = MakeName ((string) $4);
+ string name;
- new_class = new Class (rc, current_container, full_class_name, (int) $2,
+ name = MakeName ((string) $4);
+
+ new_class = new Class (current_container, name, (int) $2,
(Attributes) $1, lexer.Location);
current_container = new_class;
current_container.Namespace = current_namespace;
- tree.RecordClass (full_class_name, new_class);
+ RootContext.Tree.RecordDecl (name, new_class);
}
opt_class_base
class_body
new_class.Bases = (ArrayList) $6;
current_container = current_container.Parent;
- CheckDef (current_container.AddClass (new_class), new_class.Name);
+ CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
$$ = new_class;
}
if ((m1 & m2) != 0) {
Location l = lexer.Location;
- Report.Error (1002, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
+ Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
}
$$ = (int) (m1 | m2);
}
| VIRTUAL { $$ = Modifiers.VIRTUAL; }
| OVERRIDE { $$ = Modifiers.OVERRIDE; }
| EXTERN { $$ = Modifiers.EXTERN; }
+ | VOLATILE { $$ = Modifiers.VOLATILE; }
+ | UNSAFE { $$ = Modifiers.UNSAFE; }
;
opt_class_base
block
: OPEN_BRACE
{
- current_block = new Block (current_block);
+ current_block = new Block (current_block, lexer.Location, Location.Null);
}
opt_statement_list CLOSE_BRACE
{
while (current_block.Implicit)
current_block = current_block.Parent;
$$ = current_block;
+ current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
}
;
}
| embedded_statement
{
+ Statement s = (Statement) $1;
+
+
current_block.AddStatement ((Statement) $1);
}
- | labeled_statement
- {
- current_block.AddStatement ((Statement) $1);
- }
+ | labeled_statement
;
embedded_statement
| unchecked_statement
| lock_statement
| using_statement
+ | unsafe_statement
+ | fixed_statement
;
empty_statement
;
labeled_statement
- : IDENTIFIER COLON statement
+ : IDENTIFIER COLON
{
- string lab = (String) $1;
- Block block;
+ LabeledStatement labeled = new LabeledStatement ((string) $1);
- block = new Block (current_block, lab);
- block.AddStatement ((Statement) $3);
- $$ = block;
-
- if (!current_block.AddLabel (lab, block)){
+ if (!current_block.AddLabel ((string) $1, labeled)){
Location l = lexer.Location;
- Report.Error (140, l, "The label '" + lab + "' is a duplicate");
- $$ = $3;
+ Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
}
+ current_block.AddStatement (labeled);
}
+ statement
;
declaration_statement
- : local_variable_declaration SEMICOLON // done
- | local_constant_declaration SEMICOLON // finishme
+ : local_variable_declaration SEMICOLON
+ {
+ DictionaryEntry de = (DictionaryEntry) $1;
+
+ $$ = declare_local_variables ((string) de.Key, (ArrayList) de.Value, lexer.Location);
+ }
+
+ | local_constant_declaration SEMICOLON
+ {
+ DictionaryEntry de = (DictionaryEntry) $1;
+
+ $$ = declare_local_constant ((string) de.Key, (VariableDeclaration) de.Value);
+ }
;
/*
// creeps up. If you use qualified_identifier (which is all we need
// really) two shift/reduces appear.
//
- // So, instead we do a super trick: we just allow ($1) to be a
- // SimpleName Expression.
- //
- if (((Expression) $1) is SimpleName)
- $$ = ((SimpleName) $1).Name;
- else {
+
+ // So the super-trick is that primary_expression
+ // can only be either a SimpleName or a MemberAccess.
+ // The MemberAccess case arises when you have a fully qualified type-name like :
+ // Foo.Bar.Blah i;
+ // SimpleName is when you have
+ // 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";
}
+
+ //
+ // So we extract the string corresponding to the SimpleName
+ // or MemberAccess
+ //
+ $$ = GetQualifiedIdentifier (expr) + (string) $2;
}
| builtin_types opt_rank_specifier
{
}
;
-// FIXME : How can the type of a local variable be void ? I don't quite see ;-)
-// | VOID
-// {
-// // FIXME: this is a string that represents the type
-// // Figure out something to make this work.
-// $$ = "void";
-// }
-// ;
+local_variable_pointer_type
+ : 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) + "*";
+ }
+ | builtin_types STAR
+ {
+ $$ = (string) $1 + "*";
+ }
+ | VOID STAR
+ {
+ $$ = "System.Void*";
+ }
+ | local_variable_pointer_type STAR
+ {
+ $$ = (string) $1 + "*";
+ }
+ ;
local_variable_declaration
: local_variable_type variable_declarators
{
- $$ = declare_local_variables ((string) $1, (ArrayList) $2);
+ $$ = new DictionaryEntry ($1, $2);
}
- ;
+ | local_variable_pointer_type opt_rank_specifier variable_declarators
+ {
+ $$ = new DictionaryEntry ((string) $1 + (string) $2, $3);
+ }
+ ;
local_constant_declaration
- : CONST type constant_declarator
- // finishme
+ : CONST local_variable_type constant_declarator
+ {
+ $$ = new DictionaryEntry ($2, $3);
+ }
;
expression_statement
// because statement_expression is used for example in for_statement
//
statement_expression
- : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
+ : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | error {
+ Report.Error (1002, lexer.Location, "Expecting `;'");
+ }
;
object_creation_expression
;
if_statement
- : IF OPEN_PARENS boolean_expression CLOSE_PARENS
+ : if_statement_open if_statement_rest
+ {
+ $$ = $2;
+ }
+ ;
+
+if_statement_open
+ : IF OPEN_PARENS
+ {
+ oob_stack.Push (lexer.Location);
+ }
+ ;
+
+if_statement_rest
+ : boolean_expression CLOSE_PARENS
embedded_statement
{
- $$ = new If ((Expression) $3, (Statement) $5);
+ Location l = (Location) oob_stack.Pop ();
+
+ $$ = new If ((Expression) $1, (Statement) $3, l);
+
+ if (RootContext.WarningLevel >= 3){
+ if ($3 is EmptyStatement)
+ Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
+ }
+
}
- | IF OPEN_PARENS boolean_expression CLOSE_PARENS
+ | boolean_expression CLOSE_PARENS
embedded_statement ELSE embedded_statement
{
- $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7);
+ Location l = (Location) oob_stack.Pop ();
+
+ $$ = new If ((Expression) $1, (Statement) $3, (Statement) $5, l);
}
;
switch_statement
- : SWITCH OPEN_PARENS expression CLOSE_PARENS
+ : SWITCH OPEN_PARENS
+ {
+ oob_stack.Push (lexer.Location);
+ }
+ expression CLOSE_PARENS
switch_block
{
- $$ = new Switch ((Expression) $3, (ArrayList) $5);
+ $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) oob_stack.Pop ());
}
;
;
opt_switch_sections
- : /* empty */ { $$ = new ArrayList (); }
+ : /* empty */
+ {
+ Report.Error (1522, lexer.Location, "Empty switch block");
+ }
| switch_sections
;
;
switch_label
- : CASE constant_expression COLON { $$ = new SwitchLabel ((Expression) $2); }
- | DEFAULT COLON { $$ = new SwitchLabel (null); }
+ : CASE constant_expression COLON { $$ = new SwitchLabel ((Expression) $2, lexer.Location); }
+ | DEFAULT COLON { $$ = new SwitchLabel (null, lexer.Location); }
+ | error {
+ Report.Error (
+ 1523, lexer.Location,
+ "The keyword case or default must precede code in switch block");
+ }
;
iteration_statement
;
while_statement
- : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement
+ : WHILE OPEN_PARENS
{
- $$ = new While ((Expression) $3, (Statement) $5);
+ oob_stack.Push (lexer.Location);
+ }
+ boolean_expression CLOSE_PARENS embedded_statement
+ {
+ Location l = (Location) oob_stack.Pop ();
+ $$ = new While ((Expression) $4, (Statement) $6, l);
+
+ if (RootContext.WarningLevel >= 3){
+ if ($6 is EmptyStatement)
+ Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
+ }
}
;
: DO embedded_statement
WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
{
- $$ = new Do ((Statement) $2, (Expression) $5);
+ $$ = new Do ((Statement) $2, (Expression) $5, lexer.Location);
}
;
for_statement
: FOR OPEN_PARENS
opt_for_initializer SEMICOLON
+ {
+ Block assign_block = new Block (current_block);
+ current_block = assign_block;
+
+ if ($3 is DictionaryEntry){
+ DictionaryEntry de = (DictionaryEntry) $3;
+
+ string type = (string) de.Key;
+ ArrayList var_declarators = (ArrayList) de.Value;
+
+ foreach (VariableDeclaration decl in var_declarators){
+
+ VariableInfo vi;
+
+ 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");
+ } 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);
+
+ Assign a = new Assign (var, expr, decl.Location);
+
+ assign_block.AddStatement (new StatementExpression (a, lexer.Location));
+ }
+ }
+
+ $3 = null;
+ }
+ oob_stack.Push (lexer.Location);
+ }
opt_for_condition SEMICOLON
opt_for_iterator CLOSE_PARENS
embedded_statement
{
- $$ = new For ((Statement) $3, (Expression) $5, (Statement) $7, (Statement) $9);
+ Location l = (Location) oob_stack.Pop ();
+
+ For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l);
+
+ if (RootContext.WarningLevel >= 3){
+ if ($10 is EmptyStatement)
+ Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
+ }
+
+ current_block.AddStatement (f);
+ while (current_block.Implicit)
+ current_block = current_block.Parent;
+ $$ = current_block;
+ current_block = current_block.Parent;
}
;
;
for_initializer
- : local_variable_declaration
- {
- if ((Block) $1 != current_block){
- current_block.AddStatement ((Statement) $1);
- current_block = (Block) $1;
- }
- }
+ : local_variable_declaration
| statement_expression_list
;
opt_for_condition
- : /* empty */ { $$ = new BoolLiteral (true); }
+ : /* empty */ { $$ = null; }
| boolean_expression
;
statement_expression_list
: statement_expression
{
- Block b = new Block (null, true);
+ // CHANGE: was `null'
+ Block b = new Block (current_block, true);
b.AddStatement ((Statement) $1);
$$ = b;
foreach_statement
: FOREACH OPEN_PARENS type IDENTIFIER IN
- {
- $1 = lexer.Location;
- }
+ {
+ oob_stack.Push (lexer.Location);
+ }
expression CLOSE_PARENS
- embedded_statement
{
+ oob_stack.Push (current_block);
+
Block foreach_block = new Block (current_block, true);
LocalVariableReference v;
+ 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");
+ }
+
+ v = new LocalVariableReference (foreach_block, (string) $4, l);
+ current_block = foreach_block;
+
+ oob_stack.Push (v);
+ oob_stack.Push (current_block);
+ }
+ embedded_statement
+ {
+ Block foreach_block = (Block) oob_stack.Pop ();
+ LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
+ Block prev_block = (Block) oob_stack.Pop ();
+ Location l = (Location) oob_stack.Pop ();
+
+ current_block = prev_block;
+
+ Foreach f = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
+ foreach_block.AddStatement (f);
- foreach_block.AddVariable ((string) $3, (string) $4, (Location) $1);
- v = new LocalVariableReference (foreach_block, (string) $4);
- foreach_block.AddStatement (new Foreach ((string) $3, v, (Expression) $7,
- (Statement) $9, (Location) $1));
$$ = foreach_block;
}
;
goto_statement
: GOTO IDENTIFIER SEMICOLON
{
- $$ = new Goto ((string) $2, lexer.Location);
+ $$ = new Goto (current_block, (string) $2, lexer.Location);
}
| GOTO CASE constant_expression SEMICOLON
{
- // FIXME
+ $$ = new GotoCase ((Expression) $3, lexer.Location);
}
| GOTO DEFAULT SEMICOLON
{
- // FIXME
+ $$ = new GotoDefault (lexer.Location);
}
;
throw_statement
: THROW opt_expression SEMICOLON
{
- $$ = new Throw ((Expression) $2);
+ $$ = new Throw ((Expression) $2, lexer.Location);
}
;
{
Catch g = null;
ArrayList s = new ArrayList ();
-
- foreach (Catch cc in (ArrayList) $3) {
- if (cc.Type == null)
- g = cc;
- else
- s.Add (cc);
+ ArrayList catch_list = (ArrayList) $3;
+
+ if (catch_list != null){
+ foreach (Catch cc in catch_list) {
+ if (cc.Type == null)
+ g = cc;
+ else
+ s.Add (cc);
+ }
}
$$ = new Try ((Block) $2, s, g, (Block) $5);
}
+ | TRY block error
+ {
+ Report.Error (1524, lexer.Location, "Expected catch or finally");
+ }
;
opt_catch_clauses
if (id != null){
ArrayList one = new ArrayList ();
- one.Add (new VariableDeclaration (id, null, lexer.Location));
+ Location loc = lexer.Location;
+
+ one.Add (new VariableDeclaration (id, null, loc));
$1 = current_block;
current_block = new Block (current_block);
- Block b = declare_local_variables (type, one);
+ Block b = declare_local_variables (type, one, loc);
current_block = b;
}
- $$ = new Catch (type, id , (Block) $4);
+ $$ = new Catch (type, id , (Block) $4, lexer.Location);
}
;
}
;
+unsafe_statement
+ : UNSAFE
+ {
+ if (!RootContext.Unsafe){
+ Report.Error (227, lexer.Location,
+ "Unsafe code can only be used if --unsafe is used");
+ }
+ } block {
+ $$ = new Unsafe ((Block) $3);
+ }
+ ;
+
+fixed_statement
+ : FIXED OPEN_PARENS
+ pointer_type fixed_pointer_declarators
+ CLOSE_PARENS
+ {
+ Block assign_block = new Block (current_block, true);
+ ArrayList list = (ArrayList) $4;
+ string type = (string) $3;
+ Location l = lexer.Location;
+ int top = list.Count;
+
+ for (int i = 0; i < top; i++){
+ Pair p = (Pair) list [i];
+ 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");
+ }
+ v.ReadOnly = true;
+ p.First = v;
+ list [i] = p;
+ }
+ current_block.AddStatement (assign_block);
+ current_block = assign_block;
+ oob_stack.Push (assign_block);
+ oob_stack.Push (l);
+ }
+ embedded_statement
+ {
+ Location l = (Location) oob_stack.Pop ();
+ Block assign_block = (Block) oob_stack.Pop ();
+
+ ArrayList list = (ArrayList) $4;
+ int top = list.Count;
+
+ $$ = new Fixed ((string) $3, (ArrayList) $4, (Statement) $7, l);
+ }
+ ;
+
+fixed_pointer_declarators
+ : fixed_pointer_declarator {
+ ArrayList declarators = new ArrayList ();
+ declarators.Add ($1);
+ $$ = declarators;
+ }
+ | fixed_pointer_declarators COMMA fixed_pointer_declarator
+ {
+ ArrayList declarators = (ArrayList) $1;
+ declarators.Add ($3);
+ $$ = declarators;
+ }
+ ;
+
+fixed_pointer_declarator
+ : IDENTIFIER ASSIGN expression
+ {
+ $$ = new Pair ($1, $3);
+ }
+ ;
+
lock_statement
- : LOCK OPEN_PARENS expression CLOSE_PARENS embedded_statement
+ : LOCK OPEN_PARENS expression CLOSE_PARENS
+ {
+ //
+ }
+ embedded_statement
{
- $$ = new Lock ((Expression) $3, (Statement) $5);
+ $$ = new Lock ((Expression) $3, (Statement) $6, lexer.Location);
}
;
using_statement
- : USING OPEN_PARENS resource_acquisition CLOSE_PARENS embedded_statement
- // finishme
+ : USING OPEN_PARENS resource_acquisition CLOSE_PARENS
+ {
+ Block assign_block = new Block (current_block);
+ current_block = assign_block;
+
+ oob_stack.Push (lexer.Location);
+
+ if ($3 is DictionaryEntry){
+ DictionaryEntry de = (DictionaryEntry) $3;
+ Location l = lexer.Location;
+
+ string type = (string) 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){
+
+ 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;
+ VariableInfo vi;
+
+ var = new LocalVariableReference (assign_block, decl.identifier, l);
+ vi = var.VariableInfo;
+ vi.ReadOnly = true;
+
+ // This is so that it is not a warning on using variables
+ vi.Used = true;
+
+ vars.Add (new DictionaryEntry (var, expr));
+
+ // Assign a = new Assign (var, expr, decl.Location);
+ // assign_block.AddStatement (new StatementExpression (a, lexer.Location));
+ }
+ $3 = new DictionaryEntry (type, vars);
+ }
+ }
+ embedded_statement
+ {
+ Using u = new Using ($3, (Statement) $6, (Location) oob_stack.Pop ());
+ current_block.AddStatement (u);
+ while (current_block.Implicit)
+ current_block = current_block.Parent;
+ $$ = current_block;
+ current_block = current_block.Parent;
+ }
;
resource_acquisition
: local_variable_declaration
- {
- // FIXME: Add the current block chaining for local_variable_decl
- }
- expression
- // finishme
+ | expression
;
%%
// in the current declaration space
// </summary>
void
-CheckDef (DeclSpace.AdditionResult result, string name)
+CheckDef (AdditionResult result, string name, Location l)
{
- if (result == DeclSpace.AdditionResult.Success)
+ if (result == AdditionResult.Success)
return;
- Location l = lexer.Location;
-
switch (result){
- case DeclSpace.AdditionResult.NameExists:
- Report.Error (102, l, "The namespace `" + current_container.Name +
+ case AdditionResult.NameExists:
+ Report.Error (102, l, "The container `" + current_container.Name +
"' already contains a definition for `"+
name + "'");
break;
-// NEED TO HANDLE THIS IN SEMANTIC ANALYSIS:
-//
-// case DeclSpace.AdditionResult.MethodDuplicated:
-// error (111, "Class `"+current_container.Name+
-// "' already defines a member called '" +
-// name + "' with the same parameter types");
-// break;
-
- case DeclSpace.AdditionResult.EnclosingClash:
+ //
+ // This is handled only for static Constructors, because
+ // in reality we handle these by the semantic analysis later
+ //
+ case AdditionResult.MethodExists:
+ Report.Error (
+ 111, l, "Class `"+current_container.Name+
+ "' already defines a member called '" +
+ name + "' with the same parameter types (more than one default constructor)");
+ break;
+
+ case AdditionResult.EnclosingClash:
Report.Error (542, l, "Member names cannot be the same as their enclosing type");
break;
- case DeclSpace.AdditionResult.NotAConstructor:
+ case AdditionResult.NotAConstructor:
Report.Error (1520, l, "Class, struct, or interface method must have a return type");
break;
}
}
void
-CheckDef (bool result, string name)
+CheckDef (bool result, string name, Location l)
{
if (result)
return;
- CheckDef (DeclSpace.AdditionResult.NameExists, name);
+ 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)
+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 (current_block != null){
- if (current_block.IsVariableDefined (name))
- return new LocalVariableReference (current_block, name);
- }
if (current_local_parameters != null){
int idx;
return null;
}
-Expression DecomposeQI (string name, Location l)
+Expression DecomposeQI (string name, Location loc)
{
Expression o;
if (name.IndexOf ('.') == -1){
- o = SimpleLookup (name);
+ o = SimpleLookup (name, loc);
if (o == null)
- return new SimpleName (name, l);
+ return new SimpleName (name, loc);
return o;
} else {
int pos = name.LastIndexOf (".");
string left = name.Substring (0, pos);
string right = name.Substring (pos + 1);
- o = DecomposeQI (left, l);
- return new MemberAccess (o, right, l);
+ o = DecomposeQI (left, loc);
+ return new MemberAccess (o, right, loc);
}
}
-Block declare_local_variables (string type, ArrayList variable_declarators)
+// <summary>
+// This method is used to get at the complete string representation of
+// a fully-qualified type name, hiding inside a MemberAccess ;-)
+// This is necessary because local_variable_type admits primary_expression
+// as the type of the variable. So we do some extra checking
+// </summary>
+string GetQualifiedIdentifier (Expression expr)
+{
+ if (expr is SimpleName)
+ return ((SimpleName)expr).Name;
+ else if (expr is MemberAccess)
+ return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
+ else
+ throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
+
+}
+
+Block declare_local_variables (string 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);
+ implicit_block = new Block (current_block, true, loc, Location.Null);
else
implicit_block = current_block;
foreach (VariableDeclaration decl in variable_declarators){
- if (implicit_block.AddVariable (type, decl.identifier, decl.Location)){
+
+ if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
if (decl.expression_or_array_initializer != null){
if (inits == null)
inits = new ArrayList ();
inits.Add (decl);
}
} else {
- Location l = lexer.Location;
- Report.Error (128, l, "A local variable `" + decl.identifier +
+ Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
"' is already defined in this scope");
}
}
return implicit_block;
foreach (VariableDeclaration decl in inits){
+ Assign assign;
+ Expression expr;
+
if (decl.expression_or_array_initializer is Expression){
- Expression expr = (Expression) decl.expression_or_array_initializer;
- Assign assign;
-
- assign = new Assign (new LocalVariableReference (
- implicit_block, decl.identifier),
- expr, lexer.Location);
- implicit_block.AddStatement (new StatementExpression (assign));
+ expr = (Expression) decl.expression_or_array_initializer;
+
} else {
- Console.WriteLine ("Not handling Array initializers yet");
+ 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 (implicit_block, decl.identifier, loc);
+
+ assign = new Assign (var, expr, decl.Location);
+
+ implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
}
-
+
return implicit_block;
}
-void CheckConstant (Expression expr)
+Block declare_local_constant (string type, VariableDeclaration decl)
{
- // finishme
-}
+ Block implicit_block;
-void CheckBoolean (Expression expr)
-{
- // finishme
+ if (current_block.Used)
+ implicit_block = new Block (current_block, true);
+ 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;
}
void CheckAttributeTarget (string a)
default :
Location l = lexer.Location;
- Report.Error (658, l, "Invalid attribute target");
+ Report.Error (658, l, "`" + a + "' is an invalid attribute target");
break;
}
}
+void syntax_error (Location l, string msg)
+{
+ Report.Error (1003, l, "Syntax error, " + msg);
+}
+
void output (string s)
{
Console.WriteLine (s);
}
}
-public CSharpParser(RootContext rc, string name, System.IO.Stream input)
+public CSharpParser (string name, System.IO.Stream input, ArrayList defines)
{
current_namespace = new Namespace (null, "");
- this.rc = rc;
- this.tree = rc.Tree;
this.name = name;
this.input = input;
- current_container = tree.Types;
+ current_container = RootContext.Tree.Types;
current_container.Namespace = current_namespace;
+ oob_stack = new Stack ();
- lexer = new Tokenizer (input, name);
+ lexer = new Tokenizer (input, name, defines);
}
public override int parse ()
{
- StringBuilder value = new StringBuilder ();
-
global_errors = 0;
try {
if (yacc_verbose_flag)
// 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 */
}