3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
5 // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
7 // Licensed under the terms of the GNU GPL
9 // Copyright (C) 2001 A Rafael D Teixeira
15 namespace Mono.MonoBASIC
19 using System.Reflection;
20 using System.Collections;
25 /// The MonoBASIC Parser
27 public class Parser : GenericParser
32 /// Current block is used to add statements as we find
38 /// Tmp block is used to store block endings in if/select's
43 /// Tmp block is used to store tmp copies of expressions
48 /// Tmp catch is used to store catch clauses in try..catch..finally
50 ArrayList tmp_catch_clauses;
53 /// Current interface is used by the various declaration
54 /// productions in the interface declaration to "add"
55 /// the interfaces as we find them.
57 Interface current_interface;
60 /// This is used by the unary_expression code to resolve
61 /// a name against a parameter.
63 Parameters current_local_parameters;
66 /// This are used when parsing parameters in property
69 Parameters set_parameters;
70 Parameters get_parameters;
73 /// This is used by the sub_header parser to store modifiers
74 /// to be passed to sub/constructor
76 int current_modifiers;
79 /// This is used by the sub_header parser to store attributes
80 /// to be passed to sub/constructor
82 Attributes current_attributes;
85 /// Using during property parsing to describe the implicit
86 /// value parameter that is passed to the "set" accessor
89 string get_implicit_value_parameter_name;
92 // Using during property parsing to describe the implicit
93 // value parameter that is passed to the "set" and "get"accesor
94 // methods (properties and indexers).
96 Expression get_implicit_value_parameter_type;
99 /// Using during property parsing to describe the implicit
100 /// value parameter that is passed to the "set" accessor
103 string set_implicit_value_parameter_name;
106 // Using during property parsing to describe the implicit
107 // value parameter that is passed to the "set" and "get"accesor
108 // methods (properties and indexers).
110 Expression set_implicit_value_parameter_type;
112 // An out-of-band stack.
122 static public bool InitialOptionExplicit = false;
123 static public bool InitialOptionStrict = false;
124 static public bool InitialOptionCompareBinary = true;
128 bool OptionCompareBinary;
130 static public bool UseExtendedSyntax; // for ".mbs" files
132 public override string[] extensions()
134 string [] list = { ".vb", ".mbs" };
141 %token NONE /* This token is never returned by our lexer */
142 %token ERROR // This is used not by the parser, but by the tokenizer.
146 *These are the MonoBASIC keywords
235 %token NOTINHERITABLE
236 %token NOTOVERRIDABLE
291 %token YIELD // MonoBASIC extension
293 /* MonoBASIC single character operators/punctuation. */
295 %token OPEN_BRACKET "["
296 %token CLOSE_BRACKET "]"
297 %token OPEN_PARENS "("
298 %token OPEN_BRACE "{"
299 %token CLOSE_BRACE "}"
300 %token CLOSE_PARENS ")"
317 %token ATTR_ASSIGN ":="
319 /* MonoBASIC multi-character operators. */
324 %token OP_AND //"and"
326 %token OP_XOR //"xor"
327 %token OP_MODULUS //"mod"
328 %token OP_MULT_ASSIGN "*="
329 %token OP_DIV_ASSIGN "/="
330 %token OP_IDIV_ASSIGN "\\="
331 %token OP_ADD_ASSIGN "+="
332 %token OP_SUB_ASSIGN "-="
333 %token OP_CONCAT_ASSIGN "&="
334 %token OP_EXP_ASSIGN "^="
337 %token LITERAL_INTEGER "int literal"
338 %token LITERAL_SINGLE "float literal"
339 %token LITERAL_DOUBLE "double literal"
340 %token LITERAL_DECIMAL "decimal literal"
341 %token LITERAL_CHARACTER "character literal"
342 %token LITERAL_STRING "string literal"
346 /* Add precedence rules to solve dangling else s/r conflict */
355 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
357 %left STAR DIV PERCENT
358 %right BITWISE_NOT CARRET UMINUS
359 %nonassoc OP_INC OP_DEC
361 %left OPEN_BRACKET OPEN_BRACE
365 %start compilation_unit
369 : opt_option_directives
370 opt_imports_directives
379 opt_option_directives
386 | option_directives option_directive
390 : option_explicit_directive
391 | option_strict_directive
392 | option_compare_directive
421 option_explicit_directive
422 : OPTION EXPLICIT on_off EOL
424 if (!UseExtendedSyntax)
425 OptionExplicit = (bool)$3;
428 9999, lexer.Location,
429 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
434 option_strict_directive
435 : OPTION STRICT on_off EOL
437 if (!UseExtendedSyntax)
438 OptionStrict = (bool)$3;
441 9999, lexer.Location,
442 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
446 option_compare_directive
447 : OPTION COMPARE text_or_binary EOL
449 OptionCompareBinary = (bool)$3;
460 | declarations declaration
464 : namespace_declaration
471 Class c = (Class) $1;
472 mod_flags = c.ModFlags;
474 } else if ($1 is Struct){
475 Struct s = (Struct) $1;
476 mod_flags = s.ModFlags;
478 } else if ($1 is Module){
479 Module m = (Module) $1;
480 mod_flags = m.ModFlags;
485 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
487 1527, lexer.Location,
488 "Namespace elements cannot be explicitly " +
489 "declared private or protected in '" + name + "'");
505 | qualified_identifier DOT identifier
507 $$ = (($1).ToString ()) + "." + ($3.ToString ());
510 opt_imports_directives
517 | imports_directives imports_directive
521 : IMPORTS imports_terms EOL
526 | imports_terms COMMA imports_terms
530 : qualified_identifier
532 current_namespace.Using ((string) $1, lexer.Location);
534 | qualified_identifier ASSIGN qualified_identifier
536 current_namespace.UsingAlias ((string) $1, (string) $3, lexer.Location);
542 | attribute_sections { $$ = $1; }
548 AttributeSection sect = (AttributeSection) $1;
550 if (sect.Target == "assembly")
551 RootContext.AddGlobalAttributeSection (current_container, sect);
553 $$ = new Attributes ((AttributeSection) $1, lexer.Location);
557 FIXME: we should check if extended syntax is enabled;
558 otherwise an exception should be thrown since VB.NET
559 only allows one attribute section
561 | attribute_sections attribute_section
563 Attributes attrs = null;
564 AttributeSection sect = (AttributeSection) $2;
566 if (sect.Target == "assembly")
567 RootContext.AddGlobalAttributeSection (current_container, sect);
570 attrs = (Attributes) $1;
571 attrs.AddAttributeSection (sect);
579 : OP_LT attribute_target_specifier attribute_list OP_GT
581 string target = null;
584 target = (string) $2;
586 $$ = new AttributeSection (target, (ArrayList) $3);
588 | OP_LT attribute_list OP_GT
590 $$ = new AttributeSection (null, (ArrayList) $2);
594 attribute_target_specifier
595 : attribute_target COLON
604 CheckAttributeTarget ((string) $1);
607 | EVENT { $$ = "event"; }
608 | RETURN { $$ = "return"; }
614 ArrayList attrs = new ArrayList ();
620 | attribute_list COMMA attribute
622 ArrayList attrs = (ArrayList) $1;
634 opt_attribute_arguments
636 $$ = new Mono.CSharp.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
644 opt_attribute_arguments
645 : /* empty */ { $$ = null; }
646 | OPEN_PARENS attribute_arguments CLOSE_PARENS
653 : opt_positional_argument_list
658 ArrayList args = new ArrayList ();
664 | positional_argument_list COMMA named_argument_list
666 ArrayList args = new ArrayList ();
672 | named_argument_list
674 ArrayList args = new ArrayList ();
683 opt_positional_argument_list
684 : /* empty */ { $$ = null; }
685 | positional_argument_list
688 positional_argument_list
691 ArrayList args = new ArrayList ();
692 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
696 | positional_argument_list COMMA expression
698 ArrayList args = (ArrayList) $1;
699 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
708 ArrayList args = new ArrayList ();
713 | named_argument_list COMMA named_argument
715 ArrayList args = (ArrayList) $1;
723 : identifier ATTR_ASSIGN expression
725 $$ = new DictionaryEntry (
727 new Argument ((Expression) $3, Argument.AType.Expression));
731 namespace_declaration
732 : opt_attributes NAMESPACE qualified_identifier EOL
734 Attributes attrs = (Attributes) $1;
737 foreach (AttributeSection asec in attrs.AttributeSections)
738 if (asec.Target == "assembly")
739 RootContext.AddGlobalAttributeSection (current_container, asec);
742 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
744 opt_imports_directives
748 current_namespace = current_namespace.Parent;
756 current_attributes = (Attributes) $1;
757 current_modifiers = (int) $2;
759 type_spec_declaration
762 type_spec_declaration
765 | interface_declaration
766 | delegate_declaration
772 : CLASS identifier EOL opt_class_base
777 name = MakeName ((string) $2);
778 new_class = new Class (current_container, name, current_modifiers,
779 (Attributes) current_attributes, lexer.Location);
781 current_container = new_class;
782 current_container.Namespace = current_namespace;
783 RootContext.Tree.RecordDecl (name, new_class);
785 opt_class_member_declarations
788 Class new_class = (Class) current_container;
789 new_class.Bases = (ArrayList) $4;
791 current_container = current_container.Parent;
792 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
799 : /* empty */ { $$ = null; }
800 | class_base { $$ = $1; }
804 : inherits_or_implements type_list EOL { $$ = $2; }
807 inherits_or_implements
813 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
814 | modifiers { $$ = $1; current_modifiers = (int) $1; }
824 if ((m1 & m2) != 0) {
825 Location l = lexer.Location;
826 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
828 $$ = (int) (m1 | m2);
833 : PUBLIC { $$ = Modifiers.PUBLIC; }
834 | PROTECTED { $$ = Modifiers.PROTECTED; }
835 | PRIVATE { $$ = Modifiers.PRIVATE; }
836 | SHARED { $$ = Modifiers.STATIC; }
837 | FRIEND { $$ = Modifiers.INTERNAL; }
838 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
839 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
840 | NOTOVERRIDABLE { $$ = 0; }
841 | OVERLOADS { $$ = 0; }
842 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
846 : MODULE identifier EOL
850 name = MakeName((string) $2);
851 new_module = new Module(current_container,
853 current_modifiers, // already checks then
854 (Attributes) current_attributes,
856 current_container = new_module;
857 current_container.Namespace = current_namespace;
858 RootContext.Tree.RecordDecl(name, new_module);
860 opt_module_member_declarations
863 Module new_module = (Module)current_container;
865 current_container = current_container.Parent;
866 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
872 opt_module_member_declarations
874 | module_member_declarations
877 module_member_declarations
878 : module_member_declaration
879 | module_member_declarations module_member_declaration
882 module_member_declaration
886 current_attributes = (Attributes) $1;
887 current_modifiers = (int) $2 | (int)Modifiers.STATIC; // FIXME: for type_declaration it can result in trouble
889 module_member_declarator
895 module_member_declarator
896 : static_constructor_declaration
899 Method method = (Method) $1;
900 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
903 | withevents_declaration /* This is a field but must be treated specially, see below */
904 | constant_declaration
905 | property_declaration
910 constant_declaration // TODO: implement truly the logic
911 : CONST identifier ASSIGN constant_expression
912 | CONST identifier AS qualified_identifier ASSIGN constant_expression
915 opt_class_member_declarations
917 | class_member_declarations
920 class_member_declarations
921 : class_member_declaration
922 | class_member_declarations class_member_declaration
925 class_member_declaration
929 current_attributes = (Attributes) $1;
930 current_modifiers = (int) $2;
932 class_member_declarator
938 class_member_declarator
939 : constructor_declaration
942 Method method = (Method) $1;
943 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
946 | constant_declaration
947 | property_declaration
949 | withevents_declaration /* This is a field but must be treated specially, see below */
950 /*| type_declaration */
959 | must_override_declaration
962 must_override_declaration
963 : must_override_sub_declaration
964 | must_override_func_declaration
967 must_override_sub_declaration
968 : MUSTOVERRIDE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
970 if (current_container is Module)
971 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
973 if (current_container is Struct)
974 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
976 current_modifiers |= Modifiers.ABSTRACT;
978 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
979 (Parameters) $5, null, null, lexer.Location);
981 if (!(current_container is Class))
982 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
984 // FIXME ASAP: This will crash the compiler at resolution time
989 must_override_func_declaration
990 : MUSTOVERRIDE FUNCTION identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type EOL
992 if (current_container is Module)
993 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
995 if (current_container is Struct)
996 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
998 current_modifiers |= Modifiers.ABSTRACT;
1000 Method method = new Method ((Expression) $8, (int) current_modifiers, (string) $3,
1001 (Parameters) $5, null, null, lexer.Location);
1003 if (!(current_container is Class))
1004 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1006 // FIXME ASAP: This will crash the compiler at resolution time
1012 : SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler opt_implement_clause EOL
1014 current_local_parameters = (Parameters) $4;
1017 /* This is WEIRD: declaring a method (sub) in a module as static will
1018 trigger a syntax error, but the same methods MUST be static in order
1019 to be properly called
1021 /* THIS SHOULD NOT BE NEEDED ANYMORE
1022 if (current_container is Module) {
1023 if ((current_modifiers & Modifiers.STATIC) != 0) {
1024 Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
1028 current_modifiers = Modifiers.STATIC;
1033 // Structure members are Public by default
1034 if ((current_container is Struct) && (current_modifiers == 0))
1035 current_modifiers = Modifiers.PUBLIC;
1040 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1041 (Parameters) current_local_parameters, null, (Expression) $7,
1044 method.Block = (Block) end_block();
1047 if ($6 != null) { /* we have an event handler to take care of */
1048 // This wouldn't work: AddHandler ((Expression)$6, (string) $2);
1049 string evt_def = ((MemberAccess)$6).ToString();
1050 int pos = evt_def.LastIndexOf (".");
1051 string evt_target = ((string) $2).Substring (0, pos);
1053 foreach (Property p in current_container.Properties) {
1054 if (p.Name == evt_target) {
1056 // RemoveHandler (p.Set.Block, (Expression)$6, (string) $2);
1057 AddHandler (p.Set.Block, (Expression)$6, (string) $2);
1066 : FUNCTION identifier
1067 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type opt_implement_clause EOL
1070 current_local_parameters = (Parameters) $4;
1073 /* This is WEIRD: declaring a method (sub) in a module as static will
1074 trigger a syntax error, but the same methods MUST be static in order
1075 to be properly called
1077 /* THIS SHOULD NOT BE NEEDED ANYMORE
1078 if (current_container is Module) {
1079 if ((current_modifiers & Modifiers.STATIC) != 0) {
1080 Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
1084 current_modifiers |= Modifiers.STATIC;
1088 // Structure members are Public by default
1089 if ((current_container is Struct) && (current_modifiers == 0))
1090 current_modifiers = Modifiers.PUBLIC;
1091 // Add local var declaration
1093 ArrayList retval = new ArrayList ();
1094 retval.Add (new VariableDeclaration ((string) $2, (Expression) $7, lexer.Location));
1095 declare_local_variables ((Expression) $7, retval, lexer.Location);
1100 Method method = new Method ((Expression) $7, (int) current_modifiers, (string) $2,
1101 (Parameters) current_local_parameters, null,
1102 (Expression) $7, lexer.Location);
1103 method.Block = end_block();
1105 /*Console.WriteLine ("Declaring Function '{0}' with {1} statements and {2} arguments",
1106 current_container.Name + "." + (string) $2,
1107 method.Block.statements.Count,
1108 current_local_parameters.FixedParameters != null ? current_local_parameters.FixedParameters.Length : 0);
1114 : STRUCTURE identifier EOL
1115 opt_implement_clause
1118 string full_struct_name = MakeName ((string) $2);
1120 new_struct = new Struct (current_container, full_struct_name,
1121 (int) current_modifiers,
1122 (Attributes) current_attributes, lexer.Location);
1123 current_container = new_struct;
1124 current_container.Namespace = current_namespace;
1125 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1127 opt_struct_member_declarations
1129 Struct new_struct = (Struct) current_container;
1132 new_struct.Bases = (ArrayList) $4;
1134 current_container = current_container.Parent;
1135 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1141 opt_struct_member_declarations
1143 | struct_member_declarations
1146 struct_member_declarations
1147 : struct_member_declaration
1148 | struct_member_declarations struct_member_declaration
1151 struct_member_declaration
1153 struct_member_declarator
1155 struct_member_declarator
1157 //| constant_declaration
1158 | method_declaration
1159 | property_declaration
1161 | constructor_declaration
1165 * This is only included so we can flag error 575:
1166 * destructors only allowed on class types
1168 //| destructor_declaration
1172 : EVENT identifier AS type EOL
1174 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1176 Event e = new Event ((Expression) $4, var.identifier,
1177 null, current_modifiers, null, null,
1178 current_attributes, lexer.Location);
1180 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1183 // | EVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1185 // throw new NotSupportedException();
1190 : ENUM identifier opt_type_spec EOL
1191 opt_enum_member_declarations
1193 Location enum_location = lexer.Location;
1194 string full_name = MakeName ((string) $2);
1195 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1196 ArrayList enum_members = (ArrayList) $5;
1198 Mono.CSharp.Enum e = new Mono.CSharp.Enum (current_container, enum_type,
1199 (int) current_modifiers, full_name,
1200 (Attributes) current_attributes, enum_location);
1202 foreach (VariableDeclaration ev in enum_members) {
1203 Location loc = (Location) ev.Location;
1205 CheckDef (e.AddEnumMember (ev.identifier,
1206 (Expression) ev.expression_or_array_initializer,
1207 loc, ev.OptAttributes), ev.identifier, loc);
1210 e.Namespace = current_namespace;
1212 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1213 RootContext.Tree.RecordDecl (full_name, e);
1219 opt_enum_member_declarations
1220 : /* empty */ { $$ = new ArrayList (); }
1221 | enum_member_declarations { $$ = $1; }
1224 enum_member_declarations
1225 : enum_member_declaration
1227 ArrayList l = new ArrayList ();
1232 | enum_member_declarations enum_member_declaration
1234 ArrayList l = (ArrayList) $1;
1242 enum_member_declaration
1243 : opt_attributes identifier EOL
1245 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1247 | opt_attributes identifier
1249 $$ = lexer.Location;
1251 ASSIGN expression EOL
1253 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1257 interface_declaration
1258 : INTERFACE identifier EOL
1260 Interface new_interface;
1261 string full_interface_name = MakeName ((string) $2);
1263 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1264 (Attributes) current_attributes, lexer.Location);
1265 if (current_interface != null) {
1266 Location l = lexer.Location;
1267 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1269 current_interface = new_interface;
1270 new_interface.Namespace = current_namespace;
1271 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1276 Interface new_interface = (Interface) current_interface;
1279 new_interface.Bases = (ArrayList) $5;
1281 current_interface = null;
1282 CheckDef (current_container.AddInterface (new_interface),
1283 new_interface.Name, new_interface.Location);
1290 : /* empty */ { $$ = null; }
1295 : INHERITS interface_type_list { $$ = $2; }
1301 ArrayList interfaces = new ArrayList ();
1303 interfaces.Add ($1);
1306 | interface_type_list COMMA interface_type
1308 ArrayList interfaces = (ArrayList) $1;
1309 interfaces.Add ($3);
1315 : opt_interface_member_declarations
1318 opt_interface_member_declarations
1320 | interface_member_declarations
1323 interface_member_declarations
1324 : interface_member_declaration
1325 | interface_member_declarations interface_member_declaration
1328 interface_member_declaration
1329 : interface_method_declaration
1331 InterfaceMethod m = (InterfaceMethod) $1;
1333 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1335 | interface_property_declaration
1337 InterfaceProperty p = (InterfaceProperty) $1;
1339 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1341 | interface_event_declaration
1343 InterfaceEvent e = (InterfaceEvent) $1;
1345 CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1350 : /* empty */ { $$ = false; }
1351 | NEW { $$ = true; }
1354 interface_method_declaration
1356 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1358 $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
1359 (Parameters) $4, current_attributes, lexer.Location);
1361 | FUNCTION identifier
1362 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
1364 $$ = new InterfaceMethod (
1365 (Expression) $7, (string) $2, false, (Parameters) $4,
1366 current_attributes, lexer.Location);
1370 interface_property_declaration
1371 : PROPERTY identifier
1373 opt_formal_parameter_list
1374 CLOSE_PARENS opt_type_spec EOL
1376 // FIXME we MUST pass property parameters
1377 $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
1378 true, true, current_attributes,
1383 opt_access_specifier
1385 | READONLY { $$ = Modifiers.READONLY; }
1386 | WRITEONLY { $$ = 0; }
1387 | DEFAULT { $$ = 0; }
1390 interface_event_declaration
1391 : opt_attributes opt_new EVENT type identifier EOL
1393 $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
1398 property_declaration
1399 : opt_access_specifier PROPERTY identifier opt_property_parameters AS type opt_implement_clause EOL
1401 get_implicit_value_parameter_type = (Expression) $6;
1402 get_implicit_value_parameter_name = (string) $3;
1404 current_local_parameters = (Parameters) $4;
1405 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1406 get_parameters = current_local_parameters.Copy (lexer.Location);
1407 set_parameters = current_local_parameters.Copy (lexer.Location);
1411 get_parameters = Parameters.EmptyReadOnlyParameters;
1412 set_parameters = new Parameters (null, null ,lexer.Location);
1414 lexer.PropertyParsing = true;
1416 $$ = lexer.Location;
1418 accessor_declarations
1421 lexer.PropertyParsing = false;
1424 Pair pair = (Pair) $10;
1425 Accessor get_block = (Accessor) pair.First;
1426 Accessor set_block = (Accessor) pair.Second;
1428 Location loc = lexer.Location;
1430 // Structure members are Public by default
1431 if ((current_container is Struct) && (current_modifiers == 0))
1432 current_modifiers = Modifiers.PUBLIC;
1434 prop = new Property ((Expression) $6, (string) $3, current_modifiers, get_block, set_block,
1435 current_attributes, loc, set_implicit_value_parameter_name,
1436 get_parameters, set_parameters, (Expression) $7);
1438 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1439 get_implicit_value_parameter_type = null;
1440 set_implicit_value_parameter_type = null;
1441 get_parameters = null;
1442 set_parameters = null;
1443 current_local_parameters = null;
1447 opt_property_parameters
1450 $$ = Parameters.EmptyReadOnlyParameters;
1452 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1458 opt_implement_clause
1463 | IMPLEMENTS qualified_identifier
1465 $$ = DecomposeQI ((string)$2, lexer.Location);
1469 accessor_declarations
1470 : get_accessor_declaration opt_set_accessor_declaration
1472 $$ = new Pair ($1, $2);
1474 | set_accessor_declaration opt_get_accessor_declaration
1476 $$ = new Pair ($2, $1);
1480 opt_get_accessor_declaration
1481 : /* empty */ { $$ = null; }
1482 | get_accessor_declaration
1485 opt_set_accessor_declaration
1486 : /* empty */ { $$ = null; }
1487 | set_accessor_declaration
1490 get_accessor_declaration
1491 : opt_attributes GET EOL
1493 current_local_parameters = get_parameters;
1495 lexer.PropertyParsing = false;
1498 // Add local var declaration
1500 ArrayList retval = new ArrayList ();
1501 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1502 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1508 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1509 current_local_parameters = null;
1510 lexer.PropertyParsing = true;
1514 set_accessor_declaration
1515 : opt_attributes SET opt_set_parameter EOL
1517 Parameter implicit_value_parameter = new Parameter (
1518 set_implicit_value_parameter_type,
1519 set_implicit_value_parameter_name,
1520 Parameter.Modifier.NONE, null);
1522 current_local_parameters = set_parameters;
1523 current_local_parameters.AppendParameter (implicit_value_parameter);
1526 lexer.PropertyParsing = false;
1531 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1532 current_local_parameters = null;
1533 lexer.PropertyParsing = true;
1540 set_implicit_value_parameter_type = (Expression) TypeManager.system_object_expr;
1541 set_implicit_value_parameter_name = "Value";
1543 | OPEN_PARENS opt_identifier opt_type_spec CLOSE_PARENS
1545 /* FIXME: possible syntax error which must be caught
1546 Set ( As <type>) is currently (and wrongly so) legal
1548 set_implicit_value_parameter_type = (Expression) $3;
1550 set_implicit_value_parameter_name = (string) $2;
1552 set_implicit_value_parameter_name = "Value";
1558 variable_declarators EOL
1560 int mod = (int) current_modifiers;
1563 VariableDeclaration.FixupTypes ((ArrayList) $2);
1564 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1566 if (current_container is Module)
1567 mod = mod | Modifiers.STATIC;
1569 // Structure members are Public by default
1570 if ((current_container is Struct) && (mod == 0))
1571 mod = Modifiers.PUBLIC;
1573 foreach (VariableDeclaration var in (ArrayList) $2){
1574 Location l = var.Location;
1576 Field field = new Field (var.type, mod, var.identifier,
1577 var.expression_or_array_initializer,
1578 (Attributes) null, l);
1580 CheckDef (current_container.AddField (field), field.Name, l);
1585 withevents_declaration
1586 : WITHEVENTS variable_declarators EOL
1588 /* WithEvents Fields must be resolved into properties
1589 with a bit of magic behind the scenes */
1591 VariableDeclaration.FixupTypes ((ArrayList) $2);
1593 foreach (VariableDeclaration var in (ArrayList) $2) {
1594 // 1 - We create a private field
1595 Location l = var.Location;
1597 if ((current_modifiers & Modifiers.STATIC) > 0)
1598 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
1600 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
1601 var.expression_or_array_initializer,
1602 (Attributes) null, l);
1604 CheckDef (current_container.AddField (field), field.Name, l);
1606 // 2 - Public property
1608 prop = BuildSimpleProperty (var.type, (string) var.identifier,
1609 field, (int) current_modifiers,
1610 (Attributes) current_attributes, l);
1612 CheckDef (current_container.AddProperty (prop), prop.Name, l);
1622 delegate_declaration
1624 identifier OPEN_PARENS
1625 opt_formal_parameter_list
1629 Location l = lexer.Location;
1630 Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (current_container, TypeManager.system_void_expr,
1631 (int) current_modifiers,
1632 MakeName ((string) $3), (Parameters) $5,
1633 (Attributes) current_attributes, l);
1635 del.Namespace = current_namespace;
1636 CheckDef (current_container.AddDelegate (del), del.Name, l);
1639 identifier OPEN_PARENS
1640 opt_formal_parameter_list
1641 CLOSE_PARENS AS type
1643 Location l = lexer.Location;
1644 Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (
1646 (Expression) $8, (int) current_modifiers, MakeName ((string) $3),
1647 (Parameters) $5, (Attributes) current_attributes, l);
1649 del.Namespace = current_namespace;
1650 CheckDef (current_container.AddDelegate (del), del.Name, l);
1657 | HANDLES qualified_identifier
1659 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
1665 | OPEN_PARENS CLOSE_PARENS
1668 static_constructor_declaration
1669 : SHARED SUB NEW opt_empty_parens EOL
1671 current_local_parameters = Parameters.EmptyReadOnlyParameters;
1673 oob_stack.Push (lexer.Location);
1675 Location l = (Location) oob_stack.Pop ();
1676 $$ = new Constructor ((string) "New", Parameters.EmptyReadOnlyParameters, (ConstructorInitializer) null, l);
1680 Constructor c = (Constructor) $1;
1681 c.Block = (Block) end_block();
1682 c.ModFlags = (int) current_modifiers;
1683 c.OptAttributes = current_attributes;
1685 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1686 current_local_parameters = null;
1690 constructor_declaration
1691 : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1693 current_local_parameters = (Parameters) $4;
1695 oob_stack.Push (lexer.Location);
1697 Location l = (Location) oob_stack.Pop ();
1698 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
1703 Constructor c = (Constructor) $1;
1704 c.Block = (Block) end_block();
1705 c.ModFlags = (int) current_modifiers;
1706 c.OptAttributes = current_attributes;
1708 // FIXME: This should happen at grammar level, but doing it
1709 // triggers a lot of conflicts/problems.
1710 c.Initializer = FixConstructorInitializer (ref c.Block.statements);
1712 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1713 current_local_parameters = null;
1718 opt_formal_parameter_list
1721 $$ = Parameters.EmptyReadOnlyParameters;
1723 | formal_parameter_list
1726 //Parameter p = ((Parameters) $1).FixedParameters[0];
1730 formal_parameter_list
1733 ArrayList pars_list = (ArrayList) $1;
1735 Parameter [] pars = new Parameter [pars_list.Count];
1736 pars_list.CopyTo (pars);
1737 $$ = new Parameters (pars, null, lexer.Location);
1739 | fixed_parameters COMMA parameter_array
1741 ArrayList pars_list = (ArrayList) $1;
1743 Parameter [] pars = new Parameter [pars_list.Count];
1744 pars_list.CopyTo (pars);
1746 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
1750 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1757 ArrayList pars = new ArrayList ();
1762 | fixed_parameters COMMA fixed_parameter
1764 ArrayList pars = (ArrayList) $1;
1773 opt_parameter_modifier
1774 identifier opt_rank_specifier opt_type_spec opt_variable_initializer
1776 Parameter.Modifier pm = (Parameter.Modifier)$2;
1777 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
1780 if (opt_parm && ($6 == null))
1781 Report.Error (999, "Optional parameters must have a default value");
1784 if ((pm & Parameter.Modifier.REF) !=0)
1785 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
1787 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
1791 ptype = (Expression) $5;
1794 string t = ((Expression) $5).ToString() + (string) $4;
1795 ptype = DecomposeQI (t, lexer.Location);
1797 $$ = new Parameter (ptype, (string) $3, pm,
1798 (Attributes) $1, (Expression) $6, opt_parm);
1803 : PARAM_ARRAY identifier opt_parens AS type
1805 $$ = new Parameter ((Expression) $5, (string) $2, Parameter.Modifier.PARAMS, null);
1806 // note ("type must be a single-dimension array type");
1812 | OPEN_PARENS CLOSE_PARENS
1815 opt_parameter_modifier
1816 : /* empty */ { $$ = Parameter.Modifier.VAL; }
1817 | parameter_modifiers { $$ = $1; }
1821 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
1822 | parameter_modifier { $$ = $1; }
1826 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
1827 | BYVAL { $$ = Parameter.Modifier.VAL; }
1828 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
1833 | statement_list EOL
1838 | statement_list EOL statement
1842 declaration_statement
1844 if ($1 != null && (Block) $1 != current_block){
1845 current_block.AddStatement ((Statement) $1);
1846 current_block = (Block) $1;
1849 | embedded_statement
1851 Statement s = (Statement) $1;
1853 current_block.AddStatement ((Statement) $1);
1856 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
1858 AddHandler ((Expression) $2, (string) $5);
1860 | RAISEEVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1862 RaiseEvent ((string) $2, (ArrayList) $4);
1869 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
1871 if (!current_block.AddLabel ((string) $1, labeled)){
1872 Location l = lexer.Location;
1873 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
1875 current_block.AddStatement (labeled);
1881 : expression_statement
1882 | selection_statement
1883 | iteration_statement
1890 | continue_statement
1893 | */return_statement
1901 $$ = new Exit ((ExitType)$2, lexer.Location);
1906 : DO { $$ = ExitType.DO; }
1907 | FOR { $$ = ExitType.FOR; }
1908 | WHILE { $$ = ExitType.WHILE; }
1909 | SELECT { $$ = ExitType.SELECT; }
1910 | SUB { $$ = ExitType.SUB; }
1911 | FUNCTION { $$ = ExitType.FUNCTION; }
1912 | PROPERTY { $$ = ExitType.PROPERTY; }
1913 | TRY { $$ = ExitType.TRY; }
1916 : RETURN opt_expression
1918 $$ = new Return ((Expression) $2, lexer.Location);
1930 : FOR EACH identifier IN
1932 oob_stack.Push (lexer.Location);
1938 Block foreach_block = current_block;
1939 Location l = lexer.Location;
1940 LocalVariableReference v = null;
1943 vi = foreach_block.GetVariableInfo ((string) $3);
1945 // Get a reference to this variable.
1946 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
1954 Block foreach_block = current_block;
1955 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
1956 Block prev_block = end_block();
1957 Location l = (Location) oob_stack.Pop ();
1961 f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
1971 if (!UseExtendedSyntax)
1977 if (iterator_container == null){
1978 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
1981 iterator_container.SetYields ();
1982 $$ = new Yield ((Expression) $2, lexer.Location);
1987 if (!UseExtendedSyntax)
1993 if (iterator_container == null){
1994 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
1997 iterator_container.SetYields ();
1998 $$ = new YieldBreak (lexer.Location);
2018 tmp_catch_clauses = (ArrayList) $5;
2027 ArrayList s = new ArrayList ();
2029 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2036 // Now s contains the list of specific catch clauses
2037 // and g contains the general one.
2038 Block b = end_block();
2040 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2047 tmp_block = end_block();
2057 ArrayList s = new ArrayList ();
2058 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2060 if (catch_list != null){
2061 foreach (Catch cc in catch_list) {
2069 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2075 : /* empty */ { $$ = null; }
2082 ArrayList l = new ArrayList ();
2087 | catch_clauses catch_clause
2089 ArrayList l = (ArrayList) $1;
2097 : /* empty */ { $$ = null; }
2102 : CATCH opt_catch_args EOL
2104 Expression type = null;
2108 DictionaryEntry cc = (DictionaryEntry) $2;
2109 type = (Expression) cc.Key;
2110 id = (string) cc.Value;
2113 ArrayList one = new ArrayList ();
2114 Location loc = lexer.Location;
2116 one.Add (new VariableDeclaration (id, null, loc));
2120 current_block = new Block (current_block);
2121 Block b = declare_local_variables (type, one, loc);
2127 opt_statement_list {
2128 Expression type = null;
2130 Block b_catch = current_block;
2133 DictionaryEntry cc = (DictionaryEntry) $2;
2134 type = (Expression) cc.Key;
2135 id = (string) cc.Value;
2139 // FIXME: I can change this for an assignment.
2141 while (current_block != (Block) $1)
2142 current_block = current_block.Parent;
2146 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2151 : /* empty */ { $$ = null; }
2156 : identifier AS type
2158 $$ = new DictionaryEntry ($3, $1);
2164 : DO opt_do_construct EOL
2167 oob_stack.Push (lexer.Location);
2170 LOOP opt_do_construct
2172 Expression t_before = (Expression) $2;
2173 Expression t_after = (Expression) $7;
2176 if ((t_before != null) && (t_after != null))
2177 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2179 if ((t_before == null) && (t_after == null))
2180 t = new BoolLiteral (true);
2182 t = (t_before != null) ? t_before : t_after;
2184 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2186 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2187 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2188 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2190 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2195 : /* empty */ { $$ = null; }
2196 | while_or_until boolean_expression
2198 do_type = (DoOptions)$1;
2199 $$ = (Expression) $2;
2204 : WHILE { $$ = DoOptions.WHILE; }
2205 | UNTIL { $$ = DoOptions.UNTIL; }
2212 oob_stack.Push (lexer.Location);
2214 boolean_expression EOL
2218 Location l = (Location) oob_stack.Pop ();
2219 Block b = end_block();
2220 Expression e = (Expression) $3;
2221 $$ = new While ((Expression) e, (Statement) b, l);
2227 : FOR qualified_identifier ASSIGN expression TO expression opt_step EOL
2234 Block statement = end_block();
2235 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2237 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2238 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2239 for_var, (Expression) $6, lexer.Location);
2240 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2241 for_var, (Expression) $7, lexer.Location), lexer.Location);
2243 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2244 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2246 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2251 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2252 | STEP expression { $$ = $2; }
2257 | qualified_identifier
2266 : if_statement_open opt_then if_statement_rest
2270 | if_statement_open THEN embedded_statement
2272 Location l = (Location) oob_stack.Pop ();
2273 $$ = new If ((Expression) tmp_expr, end_block(), l);
2278 : IF boolean_expression
2280 oob_stack.Push (lexer.Location);
2282 tmp_expr = (Expression) $2;
2296 Location l = (Location) oob_stack.Pop ();
2298 $$ = new If ((Expression) tmp_expr, (Statement) end_block(), l);
2305 tmp_block = end_block();
2311 Location l = (Location) oob_stack.Pop ();
2313 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2318 : SELECT opt_case expression EOL
2320 oob_stack.Push (lexer.Location);
2321 switch_stack.Push (current_block);
2326 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2327 current_block = (Block) switch_stack.Pop ();
2332 : /* empty */ { $$ = null; }
2333 | case_sections { $$ = $1; }
2337 : case_sections case_section
2339 ArrayList sections = (ArrayList) $1;
2346 ArrayList sections = new ArrayList ();
2354 : CASE case_clauses EOL
2360 Block topmost = current_block;
2362 while (topmost.Implicit)
2363 topmost = topmost.Parent;
2365 // FIXME: This is a horrible hack which MUST go
2366 topmost.statements.Add (new Break (lexer.Location));
2367 $$ = new SwitchSection ((ArrayList) $2, topmost);
2370 /* FIXME: we should somehow flag an error
2371 (BC30321 'Case' cannot follow a 'Case Else'
2372 in the same 'Select' statement.)
2373 if Case Else is not the last of the Case clauses
2380 Block topmost = current_block;
2382 while (topmost.Implicit)
2383 topmost = topmost.Parent;
2385 // FIXME: This is a horrible hack which MUST go
2386 topmost.statements.Add (new Break (lexer.Location));
2388 ArrayList a = new ArrayList();
2389 a.Add (new SwitchLabel (null, lexer.Location));
2390 $$ = new SwitchSection ((ArrayList) a, topmost);
2397 ArrayList labels = new ArrayList ();
2402 | case_clauses COMMA case_clause
2404 ArrayList labels = (ArrayList) ($1);
2412 : opt_is comparison_operator expression
2415 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
2437 expression_statement
2438 : statement_expression
2445 statement_expression
2446 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2447 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2448 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2451 object_creation_expression
2452 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2454 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2458 array_creation_expression
2459 : object_creation_expression array_initializer
2464 if (n.Arguments != null) {
2465 foreach (Argument a in n.Arguments) {
2466 if (a.Expr is EmptyExpression)
2469 dims += (((IntLiteral)a.Expr).AsString() + ",");
2471 dims = "[" + dims.Substring (0, dims.Length - 1) + "]";
2476 Expression atype = n.RequestedType;
2478 if (VariableDeclaration.IndexesSpecified(dims)) {
2479 ArrayList dimlist = VariableDeclaration.ParseIndexList (dims);
2480 dims = VariableDeclaration.StripIndexesFromDims (dims);
2481 //$$ = new ArrayCreation (atype, dimlist, dims, (ArrayList) $2, lexer.Location);
2482 $$ = new ArrayCreation (atype, dimlist, "", (ArrayList) $2, lexer.Location);
2486 //$$ = new ArrayCreation (atype, dims, (ArrayList) $2, lexer.Location);
2487 $$ = new ArrayCreation (atype, dims, (ArrayList) $2, lexer.Location);
2489 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
2494 : object_creation_expression
2495 | array_creation_expression
2498 declaration_statement
2499 : local_variable_declaration
2502 DictionaryEntry de = (DictionaryEntry) $1;
2504 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2508 | local_constant_declaration
2511 DictionaryEntry de = (DictionaryEntry) $1;
2513 $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
2518 local_variable_declaration
2519 : DIM variable_declarators
2521 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
2526 local_constant_declaration
2527 : CONST constant_declarator
2530 $$ = new DictionaryEntry ($1, $2);
2537 : identifier ASSIGN constant_expression
2539 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
2543 variable_declarators
2544 : variable_declarator
2546 ArrayList decl = new ArrayList ();
2550 | variable_declarators COMMA variable_declarator
2552 ArrayList decls = (ArrayList) $1;
2559 : variable_identifier opt_type_decl opt_variable_initializer
2561 string varname = (string)$1;
2563 object varinit = $3;
2566 // Some checking is required for particularly weird declarations
2568 vartype = (Expression) ((Pair) $2).First;
2569 if ($3 != null && $3 is ArrayList)
2570 Report.Error (205, "End of statement expected.");
2572 ArrayList args = (ArrayList) ((Pair) $2).Second;
2573 if (VariableDeclaration.HasExplicitIndexes (args))
2574 Report.Error (638, "Array bounds cannot appear in type specifiers.");
2578 for (int x = 0; x < args.Count; x++)
2584 vartype = (Expression) $2;
2586 Check for a declaration like Dim a(2) or Dim a(2,3)
2587 If this is the case, we must generate an ArrayCreationExpression
2588 and, in case, add the initializer after the array has been created.
2590 if (VariableDeclaration.IsArrayDecl (varname)) {
2591 if (VariableDeclaration.IndexesSpecified(varname)) {
2592 varname = VariableDeclaration.StripDims (varname, ref dims);
2593 ArrayList a_dims = VariableDeclaration.ParseIndexList(dims);
2594 varinit = new ArrayCreation (vartype, a_dims,"", (ArrayList) varinit, lexer.Location);
2597 varname = VariableDeclaration.StripDims (varname, ref dims);
2599 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.GetRank (dims), lexer.Location);
2602 if (vartype is New) {
2603 if (varinit != null) {
2604 Report.Error (30205, lexer.Location, "End of statement expected");
2610 vartype = ((New)vartype).RequestedType;
2613 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
2614 //Console.WriteLine ("varname: {0} - vartype: {1} - init: {2}", varname, vartype, varinit);
2619 : identifier opt_array_name_modifier
2623 $$ = (string)$$ + (string)$2;
2634 $$ = (Expression) $2;
2643 | AS type OPEN_PARENS opt_argument_list CLOSE_PARENS
2645 // Report.Error (30638, "Array bounds cannot appear in type specifiers");
2646 $$ = new Pair ($2, $4);;
2650 New n = new New ((Expression)$3, null, lexer.Location);
2651 $$ = (Expression) n;
2653 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2655 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
2656 $$ = (Expression) n;
2660 opt_array_name_modifier
2661 : /* empty */ { $$ = null; }
2662 | array_type_modifier { $$ = $1; }
2666 : rank_specifiers { $$ = $1; }
2669 opt_variable_initializer
2670 : /* empty */ { $$ = null; }
2671 | ASSIGN variable_initializer { $$ = $2; }
2674 variable_initializer
2687 : OPEN_BRACE CLOSE_BRACE
2689 ArrayList list = new ArrayList ();
2692 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
2694 $$ = (ArrayList) $2;
2698 variable_initializer_list
2699 : variable_initializer
2701 ArrayList list = new ArrayList ();
2705 | variable_initializer_list COMMA variable_initializer
2707 ArrayList list = (ArrayList) $1;
2714 * The following is from Rhys' grammar:
2715 * > Types in local variable declarations must be recognized as
2716 * > expressions to prevent reduce/reduce errors in the grammar.
2717 * > The expressions are converted into types during semantic analysis.
2720 : primary_expression opt_rank_specifier
2722 // FIXME: Do something smart here regarding the composition of the type.
2724 // Ok, the above "primary_expression" is there to get rid of
2725 // both reduce/reduce and shift/reduces in the grammar, it should
2726 // really just be "type_name". If you use type_name, a reduce/reduce
2727 // creeps up. If you use qualified_identifier (which is all we need
2728 // really) two shift/reduces appear.
2731 // So the super-trick is that primary_expression
2732 // can only be either a SimpleName or a MemberAccess.
2733 // The MemberAccess case arises when you have a fully qualified type-name like :
2735 // SimpleName is when you have
2738 Expression expr = (Expression) $1;
2739 if (!(expr is SimpleName || expr is MemberAccess)) {
2740 Error_ExpectingTypeName (lexer.Location, expr);
2744 // So we extract the string corresponding to the SimpleName
2747 if ((string) $2 == "")
2750 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2753 | builtin_types opt_rank_specifier
2755 if ((string) $2 == "")
2758 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2767 | rank_specifiers rank_specifier
2769 $$ = (string) $2 + (string) $1;
2774 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
2776 $$ = "[" + (string) $2 + "]";
2811 | dim_separators COMMA
2813 $$ = (string) $1 + ",";
2818 : integer_literal { $$ = ((IntLiteral)$1).AsString(); }
2819 | dim_specifiers COMMA integer_literal { $$ = $1 + "," + ((IntLiteral)$3).AsString(); }
2831 | qualified_identifier
2833 string name = (string) $1;
2835 $$ = DecomposeQI (name, lexer.Location);
2837 | parenthesized_expression
2839 | invocation_expression
2851 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
2852 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
2853 | NOTHING { $$ = NullLiteral.Null; }
2857 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
2858 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
2859 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
2864 object v = lexer.Value;
2867 $$ = new IntLiteral ((Int32) v);
2869 $$ = new UIntLiteral ((UInt32) v);
2871 $$ = new LongLiteral ((Int64) v);
2872 else if (v is ulong)
2873 $$ = new ULongLiteral ((UInt64) v);
2875 Console.WriteLine ("OOPS. Unexpected result from scanner");
2881 : TRUE { $$ = new BoolLiteral (true); }
2882 | FALSE { $$ = new BoolLiteral (false); }
2885 parenthesized_expression
2886 : OPEN_PARENS expression CLOSE_PARENS
2891 : primary_expression DOT identifier
2893 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2895 | primary_expression DOT NEW
2897 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
2899 | predefined_type DOT identifier
2901 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2909 invocation_expression
2910 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
2913 Location l = lexer.Location;
2914 Report.Error (1, l, "THIS IS CRAZY");
2916 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
2917 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
2922 : MYBASE DOT IDENTIFIER
2924 $$ = new BaseAccess ((string) $3, lexer.Location);
2928 $$ = new BaseAccess ("New", lexer.Location);
2936 The 'argument' rule returns an 'empty' argument
2937 of type NoArg (used for default arguments in invocations)
2938 if no arguments are actually passed.
2940 If there is only one argument and it is o type NoArg,
2941 we return a null (empty) list
2943 ArrayList args = (ArrayList) $1;
2944 if (args.Count == 1 &&
2945 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
2955 ArrayList list = new ArrayList ();
2959 | argument_list COMMA argument
2961 ArrayList list = (ArrayList) $1;
2970 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
2972 | BYREF variable_reference
2974 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
2978 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
2983 : expression {/* note ("section 5.4"); */ $$ = $1; }
2987 : primary_expression OPEN_PARENS expression_list CLOSE_PARENS
2989 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
2991 | primary_expression rank_specifiers
2993 // So the super-trick is that primary_expression
2994 // can only be either a SimpleName or a MemberAccess.
2995 // The MemberAccess case arises when you have a fully qualified type-name like :
2997 // SimpleName is when you have
2999 Expression expr = (Expression) $1;
3001 if (!(expr is SimpleName || expr is MemberAccess)) {
3002 Error_ExpectingTypeName (lexer.Location, expr);
3003 $$ = TypeManager.system_object_expr;
3006 // So we extract the string corresponding to the SimpleName
3009 $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
3016 : conditional_expression { $$ = $1; }
3017 /*| assignment_expression*/
3028 ArrayList list = new ArrayList ();
3032 | expression_list COMMA expression
3034 ArrayList list = (ArrayList) $1;
3041 : /*empty */ { $$ = null; }
3048 $$ = new This (current_block, lexer.Location);
3052 // FIXME: This is actually somewhat different from Me
3053 $$ = new This (current_block, lexer.Location);
3058 : primary_expression
3059 | NOT prefixed_unary_expression
3061 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3063 /*| cast_expression */
3067 : cast_operator OPEN_PARENS expression CLOSE_PARENS
3069 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3071 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3073 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3078 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3079 | CBYTE { $$ = TypeManager.system_byte_expr; }
3080 | CCHAR { $$ = TypeManager.system_char_expr; }
3081 | CDATE { $$ = TypeManager.system_decimal_expr; } //FIXME
3082 | CDBL { $$ = TypeManager.system_double_expr; }
3083 | CDEC { $$ = TypeManager.system_decimal_expr; }
3084 | CINT { $$ = TypeManager.system_int32_expr; }
3085 | CLNG { $$ = TypeManager.system_int64_expr; }
3086 | COBJ { $$ = TypeManager.system_object_expr; }
3087 | CSHORT { $$ = TypeManager.system_int16_expr; }
3088 | CSNG { $$ = TypeManager.system_single_expr; }
3089 | CSTR { $$ = TypeManager.system_string_expr; }
3093 // The idea to split this out is from Rhys' grammar
3094 // to solve the problem with casts.
3096 prefixed_unary_expression
3098 | PLUS prefixed_unary_expression
3100 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3102 | MINUS prefixed_unary_expression
3104 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3106 | ADDRESSOF prefixed_unary_expression
3108 // FIXME: We should generate an error if AddressOf is NOT used
3109 // during delegate creation
3114 multiplicative_expression
3115 : prefixed_unary_expression
3116 | multiplicative_expression STAR prefixed_unary_expression
3118 $$ = new Binary (Binary.Operator.Multiply,
3119 (Expression) $1, (Expression) $3, lexer.Location);
3121 | multiplicative_expression DIV prefixed_unary_expression
3123 $$ = new Binary (Binary.Operator.Division,
3124 (Expression) $1, (Expression) $3, lexer.Location);
3126 | multiplicative_expression OP_MODULUS prefixed_unary_expression
3128 $$ = new Binary (Binary.Operator.Modulus,
3129 (Expression) $1, (Expression) $3, lexer.Location);
3134 : multiplicative_expression
3135 | additive_expression PLUS multiplicative_expression
3137 $$ = new Binary (Binary.Operator.Addition,
3138 (Expression) $1, (Expression) $3, lexer.Location);
3140 | additive_expression MINUS multiplicative_expression
3142 $$ = new Binary (Binary.Operator.Subtraction,
3143 (Expression) $1, (Expression) $3, lexer.Location);
3145 | additive_expression OP_CONCAT multiplicative_expression
3147 // FIXME: This should only work for String expressions
3148 // We probably need to use something from the runtime
3149 $$ = new Binary (Binary.Operator.Addition,
3150 (Expression) $1, (Expression) $3, lexer.Location);
3154 relational_expression
3155 : additive_expression
3156 | relational_expression OP_LT additive_expression
3158 $$ = new Binary (Binary.Operator.LessThan,
3159 (Expression) $1, (Expression) $3, lexer.Location);
3161 | relational_expression OP_GT additive_expression
3163 $$ = new Binary (Binary.Operator.GreaterThan,
3164 (Expression) $1, (Expression) $3, lexer.Location);
3166 | relational_expression OP_LE additive_expression
3168 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3169 (Expression) $1, (Expression) $3, lexer.Location);
3171 | relational_expression OP_GE additive_expression
3173 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3174 (Expression) $1, (Expression) $3, lexer.Location);
3176 | relational_expression IS type_name
3178 $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
3180 | relational_expression IS NOTHING
3182 $$ = new Binary (Binary.Operator.Equality,
3183 (Expression) $1, (Expression) NullLiteral.Null, lexer.Location);
3185 | relational_expression AS type_name
3187 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3192 : relational_expression
3193 | equality_expression ASSIGN relational_expression
3195 $$ = new Binary (Binary.Operator.Equality,
3196 (Expression) $1, (Expression) $3, lexer.Location);
3198 | equality_expression OP_NE relational_expression
3200 $$ = new Binary (Binary.Operator.Inequality,
3201 (Expression) $1, (Expression) $3, lexer.Location);
3206 : equality_expression
3207 | and_expression OP_AND equality_expression
3209 $$ = new Binary (Binary.Operator.BitwiseAnd,
3210 (Expression) $1, (Expression) $3, lexer.Location);
3214 exclusive_or_expression
3216 | exclusive_or_expression OP_XOR and_expression
3218 $$ = new Binary (Binary.Operator.ExclusiveOr,
3219 (Expression) $1, (Expression) $3, lexer.Location);
3223 conditional_and_expression
3224 : exclusive_or_expression
3225 | conditional_and_expression OP_AND exclusive_or_expression
3227 $$ = new Binary (Binary.Operator.LogicalAnd,
3228 (Expression) $1, (Expression) $3, lexer.Location);
3232 conditional_or_expression
3233 : conditional_and_expression
3234 | conditional_or_expression OP_OR conditional_and_expression
3236 $$ = new Binary (Binary.Operator.LogicalOr,
3237 (Expression) $1, (Expression) $3, lexer.Location);
3241 conditional_expression
3242 : conditional_or_expression
3245 assignment_expression
3246 : prefixed_unary_expression ASSIGN expression
3248 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3250 | prefixed_unary_expression OP_MULT_ASSIGN expression
3252 Location l = lexer.Location;
3254 $$ = new CompoundAssign (
3255 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3257 | prefixed_unary_expression OP_DIV_ASSIGN expression
3259 Location l = lexer.Location;
3261 $$ = new CompoundAssign (
3262 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3264 | prefixed_unary_expression OP_ADD_ASSIGN expression
3266 Location l = lexer.Location;
3268 $$ = new CompoundAssign (
3269 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3271 | prefixed_unary_expression OP_SUB_ASSIGN expression
3273 Location l = lexer.Location;
3275 $$ = new CompoundAssign (
3276 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3289 : type_name { /* class_type */
3291 This does interfaces, delegates, struct_types, class_types,
3292 parent classes, and more! 4.2
3294 $$ = DecomposeQI ((string) $1, lexer.Location);
3304 ArrayList types = new ArrayList ();
3309 | type_list COMMA type
3311 ArrayList types = (ArrayList) $1;
3319 : namespace_or_type_name
3322 namespace_or_type_name
3323 : qualified_identifier
3327 : type bracketed_rank_specifiers
3329 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3333 bracketed_rank_specifiers
3334 : bracketed_rank_specifier bracketed_opt_rank_specifier
3336 $$ = (string) $2 + (string) $1;
3340 bracketed_rank_specifier
3341 : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
3343 $$ = "[" + (string) $2 + "]";
3347 bracketed_opt_rank_specifier
3352 | bracketed_rank_specifiers
3358 /* Built-in / Integral types */
3360 : OBJECT { $$ = TypeManager.system_object_expr; }
3361 | STRING { $$ = TypeManager.system_string_expr; }
3362 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
3363 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
3364 | SINGLE { $$ = TypeManager.system_single_expr; }
3365 | DOUBLE { $$ = TypeManager.system_double_expr; }
3371 | BYTE { $$ = TypeManager.system_byte_expr; }
3372 | SHORT { $$ = TypeManager.system_int16_expr; }
3373 | LONG { $$ = TypeManager.system_int64_expr; }
3374 | INTEGER { $$ = TypeManager.system_int32_expr; }
3375 | CHAR { $$ = TypeManager.system_char_expr; }
3377 | SBYTE { $$ = TypeManager.system_sbyte_expr; }
3378 | UINT { $$ = TypeManager.system_uint32_expr; }
3379 | ULONG { $$ = TypeManager.system_uint64_expr; }
3380 | USHORT { $$ = TypeManager.system_uint16_expr; }
3381 | CHAR { $$ = TypeManager.system_char_expr; }
3382 | VOID { $$ = TypeManager.system_void_expr; }
3394 public Tokenizer Lexer {
3400 public static Expression DecomposeQI (string name, Location loc)
3404 if (name.IndexOf ('.') == -1){
3405 return new SimpleName (name, loc);
3407 int pos = name.LastIndexOf (".");
3408 string left = name.Substring (0, pos);
3409 string right = name.Substring (pos + 1);
3411 o = DecomposeQI (left, loc);
3413 return new MemberAccess (o, right, loc);
3417 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
3419 Block implicit_block;
3420 ArrayList inits = null;
3423 // We use the `Used' property to check whether statements
3424 // have been added to the current block. If so, we need
3425 // to create another block to contain the new declaration
3426 // otherwise, as an optimization, we use the same block to
3427 // add the declaration.
3429 // FIXME: A further optimization is to check if the statements
3430 // that were added were added as part of the initialization
3431 // below. In which case, no other statements have been executed
3432 // and we might be able to reduce the number of blocks for
3433 // situations like this:
3435 // int j = 1; int k = j + 1;
3438 VariableDeclaration.FixupTypes (variable_declarators);
3440 if (current_block.Used) {
3441 implicit_block = new Block (current_block, true, loc, Location.Null);
3442 implicit_block.AddChildVariableNames (current_block);
3444 implicit_block = current_block;
3446 foreach (VariableDeclaration decl in variable_declarators){
3447 Expression type = decl.type;
3448 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
3449 if (decl.expression_or_array_initializer != null){
3451 inits = new ArrayList ();
3458 return implicit_block;
3460 foreach (VariableDeclaration decl in inits){
3463 Expression type = decl.type;
3465 if ((decl.expression_or_array_initializer is Expression) ||
3466 (decl.expression_or_array_initializer is New)) {
3467 expr = (Expression) decl.expression_or_array_initializer;
3469 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3471 expr = new ArrayCreation (type, "", init, decl.Location);
3474 LocalVariableReference var;
3475 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
3477 assign = new Assign (var, expr, decl.Location);
3479 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
3482 return implicit_block;
3486 Block declare_local_constant (Expression type, VariableDeclaration decl)
3488 Block implicit_block;
3490 if (current_block.Used)
3491 implicit_block = new Block (current_block, true);
3493 implicit_block = current_block;
3495 if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
3496 current_local_parameters, decl.Location))){
3499 return implicit_block;
3503 // A class used to pass around variable declarations and constants
3505 public class VariableDeclaration {
3506 public string identifier;
3507 public object expression_or_array_initializer;
3508 public Location Location;
3509 public Attributes OptAttributes;
3510 public Expression type;
3511 public ArrayList dims;
3513 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
3515 this.identifier = id;
3516 this.expression_or_array_initializer = eoai;
3518 this.OptAttributes = opt_attrs;
3523 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
3527 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
3531 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
3532 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
3536 public static void FixupTypes (ArrayList vars)
3538 int varcount = vars.Count;
3539 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
3541 if (last_var.type == null)
3542 last_var.type = TypeManager.system_object_expr;
3544 Expression cur_type = last_var.type;
3545 int n = varcount - 1;
3548 VariableDeclaration var = (VariableDeclaration) vars[n--];
3549 if (var.type == null)
3550 var.type = cur_type;
3552 cur_type = var.type;
3556 public static bool IndexesSpecified (string varname)
3560 if (varname.IndexOf("[") >= 0) {
3561 char[] ds = {'1','2','3','4','5','6','7','8','9'};
3563 string dimpart = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
3564 if (dimpart.IndexOfAny (ds) >= 0)
3570 public static string StripDims (string varname, ref string d)
3572 string res = varname;
3575 if (varname.IndexOf("[") >= 0) {
3576 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
3577 res = varname.Substring(0, varname.IndexOf("["));
3583 public static string StripDims (string varname)
3587 return (StripDims(varname, ref dres));
3590 public static string StripIndexesFromDims (string dims)
3592 StringBuilder sb = new StringBuilder();
3594 foreach (char c in dims)
3595 if (c == ',' || c == ']' || c == '[')
3598 return sb.ToString();
3601 public static string GetRank (string dims)
3606 for (x = 0; x < dims.Length; x++) {
3607 if (dims[x] == '[' || dims[x] == ']' || dims[x] == ',')
3608 res = res + dims[x];
3613 public static bool HasExplicitIndexes (ArrayList a)
3618 foreach (Expression e in a)
3619 if (!(e is EmptyExpression)) {
3627 public static ArrayList ParseIndexList (string dims)
3629 ArrayList res = new ArrayList();
3630 string d = dims.Substring (1, dims.Length -2);
3631 Array a = d.Split (',');
3633 if (a.GetLength(0) > 32) {
3634 Report.Error (999, "Arrays cannot have more than 32 dimensions");
3637 foreach (string s in a)
3639 res.Add (new IntLiteral ((Int32) Convert.ToInt32(s) + 1));
3641 res.Add (new IntLiteral ((Int32) 0));
3646 public static bool IsArrayDecl (string varname)
3648 return (varname.IndexOf("[") >= 0);
3651 public static void FixupArrayTypes (ArrayList vars)
3653 int varcount = vars.Count;
3656 foreach (VariableDeclaration var in vars) {
3657 if (var.identifier.EndsWith(",")) {
3658 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
3659 var.identifier.LastIndexOf(",")) + "]";
3660 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
3661 var.type = new ComposedCast (var.type, (string) dims, var.Location);
3667 public Property BuildSimpleProperty (Expression p_type, string name,
3668 Field p_fld, int mod_flags,
3669 Attributes attrs, Location loc)
3672 Block get_block, set_block;
3673 Accessor acc_set, acc_get;
3674 StatementExpression a_set;
3679 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
3680 args = new Parameter [1];
3681 args [0] = implicit_value_parameter;
3683 Parameters set_params = new Parameters (args, null, loc);
3684 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
3685 (Expression) new SimpleName("value", loc), loc), loc);
3687 set_block = new Block (current_block, set_params, loc, Location.Null);
3688 set_block.AddStatement ((Statement) a_set);
3689 acc_set = new Accessor (set_block, attrs);
3692 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
3693 get_block = new Block (current_block, null, loc, Location.Null);
3694 get_block.AddStatement ((Statement) a_get);
3695 acc_get = new Accessor (get_block, attrs);
3697 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
3704 current_block = new Block (current_block, current_local_parameters,
3705 lexer.Location, Location.Null);
3712 while (current_block.Implicit)
3713 current_block = current_block.Parent;
3715 res = current_block;
3717 current_block.SetEndLocation (lexer.Location);
3718 current_block = current_block.Parent;
3723 private void AddHandler (Expression evt_definition, string handler_name)
3725 AddHandler (current_block, evt_definition, handler_name);
3728 void CheckAttributeTarget (string a)
3732 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
3736 Location l = lexer.Location;
3737 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
3742 private void AddHandler (Block b, Expression evt_id, string handler_name)
3744 Location loc = lexer.Location;
3745 string evt_target = evt_id.ToString();
3746 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
3747 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
3751 private void RaiseEvent (string evt_name, ArrayList args)
3753 Location loc = lexer.Location;
3755 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
3756 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
3757 current_block.AddStatement (s);
3760 // FIXME: THIS DOES NOT WORK!!!
3761 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
3763 Location loc = lexer.Location;
3764 ArrayList neh_args = new ArrayList();
3765 neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
3767 ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
3769 CompoundAssign ca = new CompoundAssign (
3770 Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
3772 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc));
3777 // This method is used to get at the complete string representation of
3778 // a fully-qualified type name, hiding inside a MemberAccess ;-)
3779 // This is necessary because local_variable_type admits primary_expression
3780 // as the type of the variable. So we do some extra checking
3782 string GetQualifiedIdentifier (Expression expr)
3784 if (expr is SimpleName)
3785 return ((SimpleName)expr).Name;
3786 else if (expr is MemberAccess)
3787 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
3789 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
3793 private void RemoveHandler (Expression evt_definition, string handler_name)
3795 RemoveHandler (current_block, evt_definition, handler_name);
3798 private ConstructorInitializer FixConstructorInitializer (ref ArrayList s)
3800 ConstructorInitializer ci = null;
3803 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
3804 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
3806 if (i.expr is BaseAccess) {
3807 BaseAccess ba = (BaseAccess) i.expr;
3808 if (ba.member == "New" || ba.member == ".ctor") {
3809 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
3813 if (i.expr.ToString() == "Mono.CSharp.This..ctor") {
3814 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
3822 void Error_ExpectingTypeName (Location l, Expression expr)
3824 if (expr is Invocation){
3825 Report.Error (1002, l, "; expected");
3827 Report.Error (-1, l, "Invalid Type definition");
3831 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
3835 private void ReportError9998()
3837 Report.Error (9998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
3840 public override int parse ()
3842 current_namespace = new Namespace (null, RootContext.RootNamespace);
3843 current_container = RootContext.Tree.Types;
3844 current_container.Namespace = current_namespace;
3845 oob_stack = new Stack ();
3846 switch_stack = new Stack ();
3848 UseExtendedSyntax = name.EndsWith(".mbs");
3849 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
3850 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
3851 OptionCompareBinary = InitialOptionCompareBinary;
3853 lexer = new Tokenizer (input, name, defines);
3854 StringBuilder value = new StringBuilder ();
3855 //yacc_verbose_flag=true;
3858 if (yacc_verbose_flag)
3859 yyparse (lexer, new yydebug.yyDebugSimple ());
3865 Console.WriteLine (lexer.location + " : Parsing error in " + lexer.ref_name);
3866 Report.Error (9999, lexer.Location, "");
3867 Console.WriteLine (e);
3870 return Report.Errors;