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
28 public class Parser : GenericParser
33 /// Current block is used to add statements as we find
39 /// Tmp block is used to store block endings in if/select's
44 /// Tmp block is used to store tmp copies of expressions
49 /// Tmp catch is used to store catch clauses in try..catch..finally
51 ArrayList tmp_catch_clauses;
54 /// Current interface is used by the various declaration
55 /// productions in the interface declaration to "add"
56 /// the interfaces as we find them.
58 Interface current_interface;
61 /// This is used by the unary_expression code to resolve
62 /// a name against a parameter.
64 Parameters current_local_parameters;
67 /// This are used when parsing parameters in property
70 Parameters set_parameters;
71 Parameters get_parameters;
74 /// This is used by the sub_header parser to store modifiers
75 /// to be passed to sub/constructor
77 int current_modifiers;
80 /// This is used by the sub_header parser to store attributes
81 /// to be passed to sub/constructor
83 Attributes current_attributes;
86 /// Using during property parsing to describe the implicit
87 /// value parameter that is passed to the "set" accessor
90 string get_implicit_value_parameter_name;
93 // Using during property parsing to describe the implicit
94 // value parameter that is passed to the "set" and "get"accesor
95 // methods (properties and indexers).
97 Expression get_implicit_value_parameter_type;
100 /// Using during property parsing to describe the implicit
101 /// value parameter that is passed to the "set" accessor
104 string set_implicit_value_parameter_name;
107 // Using during property parsing to describe the implicit
108 // value parameter that is passed to the "set" and "get"accesor
109 // methods (properties and indexers).
111 Expression set_implicit_value_parameter_type;
113 // An out-of-band stack.
117 ArrayList current_rank_specifiers;
125 // Expression stack for nested ifs
129 Stack statement_stack;
131 // A stack for With expressions.
136 static public bool InitialOptionExplicit = false;
137 static public bool InitialOptionStrict = false;
138 static public bool InitialOptionCompareBinary = true;
142 bool OptionCompareBinary;
144 static public bool UseExtendedSyntax; // for ".mbs" files
146 bool implicit_modifiers;
148 public override string[] extensions()
150 string [] list = { ".vb", ".mbs" };
157 %token NONE /* This token is never returned by our lexer */
158 %token ERROR // This is used not by the parser, but by the tokenizer.
162 *These are the MonoBASIC keywords
251 %token NOTINHERITABLE
252 %token NOTOVERRIDABLE
307 %token YIELD // MonoBASIC extension
309 /* MonoBASIC single character operators/punctuation. */
311 %token OPEN_BRACKET "["
312 %token CLOSE_BRACKET "]"
313 %token OPEN_PARENS "("
314 %token OPEN_BRACE "{"
315 %token CLOSE_BRACE "}"
316 %token CLOSE_PARENS ")"
333 %token ATTR_ASSIGN ":="
335 /* MonoBASIC multi-character operators. */
340 //%token OP_AND "and"
343 //%token OP_MODULUS //"mod"
344 %token OP_MULT_ASSIGN "*="
345 %token OP_DIV_ASSIGN "/="
346 %token OP_IDIV_ASSIGN "\\="
347 %token OP_ADD_ASSIGN "+="
348 %token OP_SUB_ASSIGN "-="
349 %token OP_CONCAT_ASSIGN "&="
350 %token OP_EXP_ASSIGN "^="
353 %token LITERAL_INTEGER "int literal"
354 %token LITERAL_SINGLE "float literal"
355 %token LITERAL_DOUBLE "double literal"
356 %token LITERAL_DECIMAL "decimal literal"
357 %token LITERAL_CHARACTER "character literal"
358 %token LITERAL_STRING "string literal"
362 /* Add precedence rules to solve dangling else s/r conflict */
371 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
373 %left STAR DIV PERCENT
374 %right BITWISE_NOT CARRET UMINUS
375 %nonassoc OP_INC OP_DEC
377 %left OPEN_BRACKET OPEN_BRACE
382 %start compilation_unit
386 : opt_option_directives
387 opt_imports_directives
396 opt_option_directives
403 | option_directives option_directive
407 : option_explicit_directive
408 | option_strict_directive
409 | option_compare_directive
438 option_explicit_directive
439 : OPTION EXPLICIT on_off EOL
441 if (!UseExtendedSyntax)
442 OptionExplicit = (bool)$3;
445 9999, lexer.Location,
446 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
451 option_strict_directive
452 : OPTION STRICT on_off EOL
454 if (!UseExtendedSyntax)
455 OptionStrict = (bool)$3;
458 9999, lexer.Location,
459 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
463 option_compare_directive
464 : OPTION COMPARE text_or_binary EOL
466 OptionCompareBinary = (bool)$3;
477 | declarations declaration
481 : namespace_declaration
488 Class c = (Class) $1;
489 mod_flags = c.ModFlags;
491 } else if ($1 is Struct){
492 Struct s = (Struct) $1;
493 mod_flags = s.ModFlags;
495 } else if ($1 is Module){
496 Module m = (Module) $1;
497 mod_flags = m.ModFlags;
502 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
504 1527, lexer.Location,
505 "Namespace elements cannot be explicitly " +
506 "declared private or protected in '" + name + "'");
522 | qualified_identifier DOT identifier
524 $$ = (($1).ToString ()) + "." + ($3.ToString ());
527 opt_imports_directives
534 | imports_directives imports_directive
538 : IMPORTS imports_terms EOL
543 | imports_terms COMMA imports_terms
547 : qualified_identifier
549 current_namespace.Using ((string) $1, lexer.Location);
551 | qualified_identifier ASSIGN qualified_identifier
553 current_namespace.UsingAlias ((string) $1, (string) $3, lexer.Location);
559 | attribute_sections { $$ = $1; }
565 AttributeSection sect = (AttributeSection) $1;
567 if (sect.Target == "assembly")
568 RootContext.AddGlobalAttributeSection (current_container, sect);
570 $$ = new Attributes ((AttributeSection) $1, lexer.Location);
574 FIXME: we should check if extended syntax is enabled;
575 otherwise an exception should be thrown since VB.NET
576 only allows one attribute section
578 | attribute_sections attribute_section
580 Attributes attrs = null;
581 AttributeSection sect = (AttributeSection) $2;
583 if (sect.Target == "assembly")
584 RootContext.AddGlobalAttributeSection (current_container, sect);
587 attrs = (Attributes) $1;
588 attrs.AddAttributeSection (sect);
596 : OP_LT attribute_target_specifier attribute_list OP_GT
598 string target = null;
601 target = (string) $2;
603 $$ = new AttributeSection (target, (ArrayList) $3);
605 | OP_LT attribute_list OP_GT
607 $$ = new AttributeSection (null, (ArrayList) $2);
611 attribute_target_specifier
612 : attribute_target COLON
621 CheckAttributeTarget ((string) $1);
624 | EVENT { $$ = "event"; }
625 | RETURN { $$ = "return"; }
631 ArrayList attrs = new ArrayList ();
637 | attribute_list COMMA attribute
639 ArrayList attrs = (ArrayList) $1;
651 opt_attribute_arguments
653 $$ = new Mono.CSharp.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
661 opt_attribute_arguments
662 : /* empty */ { $$ = null; }
663 | OPEN_PARENS attribute_arguments CLOSE_PARENS
670 : opt_positional_argument_list
675 ArrayList args = new ArrayList ();
681 | positional_argument_list COMMA named_argument_list
683 ArrayList args = new ArrayList ();
689 | named_argument_list
691 ArrayList args = new ArrayList ();
700 opt_positional_argument_list
701 : /* empty */ { $$ = null; }
702 | positional_argument_list
705 positional_argument_list
708 ArrayList args = new ArrayList ();
709 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
713 | positional_argument_list COMMA expression
715 ArrayList args = (ArrayList) $1;
716 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
725 ArrayList args = new ArrayList ();
730 | named_argument_list COMMA named_argument
732 ArrayList args = (ArrayList) $1;
740 : identifier ATTR_ASSIGN expression
742 $$ = new DictionaryEntry (
744 new Argument ((Expression) $3, Argument.AType.Expression));
748 namespace_declaration
749 : opt_attributes NAMESPACE qualified_identifier EOL
751 Attributes attrs = (Attributes) $1;
754 foreach (AttributeSection asec in attrs.AttributeSections)
755 if (asec.Target == "assembly")
756 RootContext.AddGlobalAttributeSection (current_container, asec);
759 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
761 opt_imports_directives
765 current_namespace = current_namespace.Parent;
773 current_attributes = (Attributes) $1;
774 current_modifiers = (int) $2;
776 type_spec_declaration
779 type_spec_declaration
782 | interface_declaration
783 | delegate_declaration
789 : CLASS identifier EOL opt_inherits opt_implements
794 name = MakeName ((string) $2);
795 new_class = new Class (current_container, name, current_modifiers,
796 (Attributes) current_attributes, lexer.Location);
798 current_container = new_class;
799 current_container.Namespace = current_namespace;
800 RootContext.Tree.RecordDecl (name, new_class);
802 opt_class_member_declarations
805 Class new_class = (Class) current_container;
806 new_class.Bases = (ArrayList) $4;
808 current_container = current_container.Parent;
809 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
816 : /* empty */ { $$ = null; }
817 | INHERITS type_list EOL { $$ = $2; }
821 : /* empty */ { $$ = null; }
822 | IMPLEMENTS type_list EOL { $$ = $2; }
826 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
827 | modifiers { $$ = $1; current_modifiers = (int) $1; }
837 if ((m1 & m2) != 0) {
838 Location l = lexer.Location;
839 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
841 $$ = (int) (m1 | m2);
846 : PUBLIC { $$ = Modifiers.PUBLIC; }
847 | PROTECTED { $$ = Modifiers.PROTECTED; }
848 | PRIVATE { $$ = Modifiers.PRIVATE; }
849 | SHARED { $$ = Modifiers.STATIC; }
850 | FRIEND { $$ = Modifiers.INTERNAL; }
851 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
852 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
853 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
854 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
855 | OVERLOADS { $$ = Modifiers.OVERLOADS; }
856 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
857 | READONLY { $$ = Modifiers.READONLY; }
858 | DEFAULT { $$ = Modifiers.DEFAULT; }
859 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
863 : MODULE identifier EOL
867 name = MakeName((string) $2);
868 new_module = new Module(current_container,
870 current_modifiers, // already checks then
871 (Attributes) current_attributes,
873 current_container = new_module;
874 current_container.Namespace = current_namespace;
875 RootContext.Tree.RecordDecl(name, new_module);
877 opt_module_member_declarations
880 Module new_module = (Module)current_container;
882 current_container = current_container.Parent;
883 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
889 opt_module_member_declarations
891 | module_member_declarations
894 module_member_declarations
895 : module_member_declaration
896 | module_member_declarations module_member_declaration
899 module_member_declaration
903 current_attributes = (Attributes) $1;
904 current_modifiers = ((int)$2) | Modifiers.STATIC;
905 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
906 implicit_modifiers = (!explicit_static);
908 module_member_declarator
910 implicit_modifiers = false;
915 module_member_declarator
916 : static_constructor_declaration
919 Method method = (Method) $1;
920 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
923 | withevents_declaration /* This is a field but must be treated specially, see below */
924 | constant_declaration
925 | property_declaration
927 | type_spec_declaration
930 constant_declaration // TODO: implement truly the logic
931 : CONST identifier ASSIGN primary_expression EOL
932 | CONST identifier AS type ASSIGN constant_expression EOL
935 opt_class_member_declarations
937 | class_member_declarations
940 class_member_declarations
941 : class_member_declaration
942 | class_member_declarations class_member_declaration
945 class_member_declaration
949 current_attributes = (Attributes) $1;
950 current_modifiers = (int) $2;
952 class_member_declarator
958 class_member_declarator
959 : constructor_declaration
962 Method method = (Method) $1;
963 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
966 | constant_declaration
967 | property_declaration
969 | withevents_declaration /* This is a field but must be treated specially, see below */
970 /*| type_declaration */
979 | must_override_declaration
982 must_override_declaration
983 : must_override_sub_declaration
984 | must_override_func_declaration
987 must_override_sub_declaration
988 : MUSTOVERRIDE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
990 if (current_container is Module)
991 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
993 if (current_container is Struct)
994 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
996 current_modifiers |= Modifiers.ABSTRACT;
998 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
999 (Parameters) $5, null, null, lexer.Location);
1001 if (!(current_container is Class))
1002 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1004 // FIXME ASAP: This will crash the compiler at resolution time
1009 must_override_func_declaration
1010 : MUSTOVERRIDE FUNCTION identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type EOL
1012 if (current_container is Module)
1013 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1015 if (current_container is Struct)
1016 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1018 current_modifiers |= Modifiers.ABSTRACT;
1020 Method method = new Method ((Expression) $8, (int) current_modifiers, (string) $3,
1021 (Parameters) $5, null, null, lexer.Location);
1023 if (!(current_container is Class))
1024 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1026 // FIXME ASAP: This will crash the compiler at resolution time
1032 : SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler opt_implement_clause EOL
1034 current_local_parameters = (Parameters) $4;
1037 // Structure members are Public by default
1038 if ((current_container is Struct) && (current_modifiers == 0))
1039 current_modifiers = Modifiers.PUBLIC;
1044 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1045 (Parameters) current_local_parameters, null, (Expression) $7,
1048 method.Block = (Block) end_block();
1051 if ($6 != null) { /* we have an event handler to take care of */
1052 // This wouldn't work: AddHandler ((Expression)$6, (string) $2);
1053 string evt_def = ((MemberAccess)$6).ToString();
1054 int pos = evt_def.LastIndexOf (".");
1055 string evt_target = ((string) $2).Substring (0, pos);
1057 foreach (Property p in current_container.Properties) {
1058 if (p.Name == evt_target) {
1060 // RemoveHandler (p.Set.Block, (Expression)$6, (string) $2);
1061 AddHandler (p.Set.Block, (Expression)$6, (string) $2);
1070 : FUNCTION identifier
1071 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks opt_implement_clause EOL
1074 current_local_parameters = (Parameters) $4;
1077 Expression ftype = ($6 == null) ? TypeManager.system_object_expr : (Expression) $6;
1079 // Structure members are Public by default
1080 if ((current_container is Struct) && (current_modifiers == 0))
1081 current_modifiers = Modifiers.PUBLIC;
1082 // Add local var declaration
1084 ArrayList retval = new ArrayList ();
1085 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1086 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1091 Expression ftype = ($6 == null) ? TypeManager.system_object_expr : (Expression) $6;
1092 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1093 (Parameters) current_local_parameters, null,
1094 (Expression) ftype, lexer.Location);
1095 method.Block = end_block();
1097 /*Console.WriteLine ("Declaring Function '{0}' with {1} statements and {2} arguments",
1098 current_container.Name + "." + (string) $2,
1099 method.Block.statements.Count,
1100 current_local_parameters.FixedParameters != null ? current_local_parameters.FixedParameters.Length : 0);
1106 : STRUCTURE identifier EOL
1107 opt_implement_clause
1110 string full_struct_name = MakeName ((string) $2);
1112 // Module members are static by default, but structures *can't* be declared static
1113 // so we must fix it, if mbas was the one actually responsible for this
1114 // instead of triggering an error.
1115 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1116 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1118 new_struct = new Struct (current_container, full_struct_name,
1119 (int) current_modifiers,
1120 (Attributes) current_attributes, lexer.Location);
1121 current_container = new_struct;
1122 current_container.Namespace = current_namespace;
1123 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1125 opt_struct_member_declarations
1127 Struct new_struct = (Struct) current_container;
1130 new_struct.Bases = (ArrayList) $4;
1132 current_container = current_container.Parent;
1133 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1139 opt_struct_member_declarations
1141 | struct_member_declarations
1144 struct_member_declarations
1145 : struct_member_declaration
1146 | struct_member_declarations struct_member_declaration
1149 struct_member_declaration
1151 struct_member_declarator
1153 struct_member_declarator
1155 //| constant_declaration
1156 | method_declaration
1157 | property_declaration
1159 | constructor_declaration
1163 * This is only included so we can flag error 575:
1164 * destructors only allowed on class types
1166 //| destructor_declaration
1170 : EVENT identifier AS type EOL
1172 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1174 Event e = new Event ((Expression) $4, var.identifier,
1175 null, current_modifiers, null, null,
1176 current_attributes, lexer.Location);
1178 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1181 // | EVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1183 // throw new NotSupportedException();
1188 : ENUM identifier opt_type_spec EOL
1189 opt_enum_member_declarations
1191 Location enum_location = lexer.Location;
1192 string full_name = MakeName ((string) $2);
1193 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1194 ArrayList enum_members = (ArrayList) $5;
1196 // Module members are static by default, but enums *can't* be declared static
1197 // so we must fix it if mbas was the one actually responsible for this
1198 // instead of triggering an error.
1199 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1200 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1202 Mono.CSharp.Enum e = new Mono.CSharp.Enum (current_container, enum_type,
1203 (int) current_modifiers, full_name,
1204 (Attributes) current_attributes, enum_location);
1206 foreach (VariableDeclaration ev in enum_members) {
1207 Location loc = (Location) ev.Location;
1209 CheckDef (e.AddEnumMember (ev.identifier,
1210 (Expression) ev.expression_or_array_initializer,
1211 loc, ev.OptAttributes), ev.identifier, loc);
1214 e.Namespace = current_namespace;
1216 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1217 RootContext.Tree.RecordDecl (full_name, e);
1223 opt_enum_member_declarations
1224 : /* empty */ { $$ = new ArrayList (); }
1225 | enum_member_declarations { $$ = $1; }
1228 enum_member_declarations
1229 : enum_member_declaration
1231 ArrayList l = new ArrayList ();
1236 | enum_member_declarations enum_member_declaration
1238 ArrayList l = (ArrayList) $1;
1246 enum_member_declaration
1247 : opt_attributes identifier EOL
1249 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1251 | opt_attributes identifier
1253 $$ = lexer.Location;
1255 ASSIGN expression EOL
1257 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1261 interface_declaration
1262 : INTERFACE identifier EOL
1264 Interface new_interface;
1265 string full_interface_name = MakeName ((string) $2);
1267 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1268 (Attributes) current_attributes, lexer.Location);
1269 if (current_interface != null) {
1270 Location l = lexer.Location;
1271 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1273 current_interface = new_interface;
1274 new_interface.Namespace = current_namespace;
1275 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1280 Interface new_interface = (Interface) current_interface;
1283 new_interface.Bases = (ArrayList) $5;
1285 current_interface = null;
1286 CheckDef (current_container.AddInterface (new_interface),
1287 new_interface.Name, new_interface.Location);
1294 : /* empty */ { $$ = null; }
1299 : INHERITS interface_type_list { $$ = $2; }
1305 ArrayList interfaces = new ArrayList ();
1307 interfaces.Add ($1);
1310 | interface_type_list COMMA interface_type
1312 ArrayList interfaces = (ArrayList) $1;
1313 interfaces.Add ($3);
1319 : opt_interface_member_declarations
1322 opt_interface_member_declarations
1324 | interface_member_declarations
1327 interface_member_declarations
1328 : interface_member_declaration
1329 | interface_member_declarations interface_member_declaration
1332 interface_member_declaration
1333 : interface_method_declaration
1335 InterfaceMethod m = (InterfaceMethod) $1;
1337 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1339 | interface_property_declaration
1341 InterfaceProperty p = (InterfaceProperty) $1;
1343 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1345 | interface_event_declaration
1347 InterfaceEvent e = (InterfaceEvent) $1;
1349 CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1354 : /* empty */ { $$ = false; }
1355 | NEW { $$ = true; }
1358 interface_method_declaration
1360 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1362 $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
1363 (Parameters) $4, current_attributes, lexer.Location);
1365 | FUNCTION identifier
1366 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
1368 $$ = new InterfaceMethod (
1369 (Expression) $7, (string) $2, false, (Parameters) $4,
1370 current_attributes, lexer.Location);
1374 interface_property_declaration
1375 : opt_modifiers PROPERTY identifier
1377 opt_formal_parameter_list
1378 CLOSE_PARENS opt_type_spec EOL
1380 // FIXME we MUST pass property parameters
1381 $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
1382 true, true, current_attributes,
1387 interface_event_declaration
1388 : opt_attributes opt_new EVENT type identifier EOL
1390 $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
1395 property_declaration
1396 : opt_modifiers PROPERTY identifier opt_property_parameters AS type opt_implement_clause EOL
1398 get_implicit_value_parameter_type = (Expression) $6;
1399 get_implicit_value_parameter_name = (string) $3;
1401 current_modifiers = (int) $1;
1403 current_local_parameters = (Parameters) $4;
1404 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1405 get_parameters = current_local_parameters.Copy (lexer.Location);
1406 set_parameters = current_local_parameters.Copy (lexer.Location);
1410 get_parameters = Parameters.EmptyReadOnlyParameters;
1411 set_parameters = new Parameters (null, null ,lexer.Location);
1413 lexer.PropertyParsing = true;
1415 $$ = lexer.Location;
1417 accessor_declarations
1420 lexer.PropertyParsing = false;
1423 Pair pair = (Pair) $10;
1424 Accessor get_block = (Accessor) pair.First;
1425 Accessor set_block = (Accessor) pair.Second;
1427 Location loc = lexer.Location;
1429 // Structure members are Public by default
1430 if ((current_container is Struct) && (current_modifiers == 0))
1431 current_modifiers = Modifiers.PUBLIC;
1433 prop = new Property ((Expression) $6, (string) $3, current_modifiers, get_block, set_block,
1434 current_attributes, loc, set_implicit_value_parameter_name,
1435 get_parameters, set_parameters, (Expression) $7);
1437 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1438 get_implicit_value_parameter_type = null;
1439 set_implicit_value_parameter_type = null;
1440 get_parameters = null;
1441 set_parameters = null;
1442 current_local_parameters = null;
1446 opt_property_parameters
1449 $$ = Parameters.EmptyReadOnlyParameters;
1451 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1457 opt_implement_clause
1462 | IMPLEMENTS qualified_identifier
1464 $$ = DecomposeQI ((string)$2, lexer.Location);
1468 accessor_declarations
1469 : get_accessor_declaration opt_set_accessor_declaration
1471 $$ = new Pair ($1, $2);
1473 | set_accessor_declaration opt_get_accessor_declaration
1475 $$ = new Pair ($2, $1);
1479 opt_get_accessor_declaration
1480 : /* empty */ { $$ = null; }
1481 | get_accessor_declaration
1484 opt_set_accessor_declaration
1485 : /* empty */ { $$ = null; }
1486 | set_accessor_declaration
1489 get_accessor_declaration
1490 : opt_attributes GET EOL
1492 current_local_parameters = get_parameters;
1494 lexer.PropertyParsing = false;
1497 // Add local var declaration
1499 ArrayList retval = new ArrayList ();
1500 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1501 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1507 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1508 current_local_parameters = null;
1509 lexer.PropertyParsing = true;
1513 set_accessor_declaration
1514 : opt_attributes SET opt_set_parameter EOL
1516 Parameter implicit_value_parameter = new Parameter (
1517 set_implicit_value_parameter_type,
1518 set_implicit_value_parameter_name,
1519 Parameter.Modifier.NONE, null);
1521 current_local_parameters = set_parameters;
1522 current_local_parameters.AppendParameter (implicit_value_parameter);
1525 lexer.PropertyParsing = false;
1530 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1531 current_local_parameters = null;
1532 lexer.PropertyParsing = true;
1539 set_implicit_value_parameter_type = (Expression) TypeManager.system_object_expr;
1540 set_implicit_value_parameter_name = "Value";
1542 | OPEN_PARENS opt_identifier opt_type_spec CLOSE_PARENS
1544 /* FIXME: possible syntax error which must be caught
1545 Set ( As <type>) is currently (and wrongly so) legal
1547 set_implicit_value_parameter_type = (Expression) $3;
1549 set_implicit_value_parameter_name = (string) $2;
1551 set_implicit_value_parameter_name = "Value";
1557 variable_declarators EOL
1559 int mod = (int) current_modifiers;
1562 VariableDeclaration.FixupTypes ((ArrayList) $2);
1563 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1565 if (current_container is Module)
1566 mod = mod | Modifiers.STATIC;
1568 // Structure members are Public by default
1569 if ((current_container is Struct) && (mod == 0))
1570 mod = Modifiers.PUBLIC;
1572 foreach (VariableDeclaration var in (ArrayList) $2){
1573 Location l = var.Location;
1575 Field field = new Field (var.type, mod, var.identifier,
1576 var.expression_or_array_initializer,
1577 (Attributes) null, l);
1579 CheckDef (current_container.AddField (field), field.Name, l);
1584 withevents_declaration
1585 : WITHEVENTS variable_declarators EOL
1587 /* WithEvents Fields must be resolved into properties
1588 with a bit of magic behind the scenes */
1590 VariableDeclaration.FixupTypes ((ArrayList) $2);
1592 foreach (VariableDeclaration var in (ArrayList) $2) {
1593 // 1 - We create a private field
1594 Location l = var.Location;
1596 if ((current_modifiers & Modifiers.STATIC) > 0)
1597 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
1599 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
1600 var.expression_or_array_initializer,
1601 (Attributes) null, l);
1603 CheckDef (current_container.AddField (field), field.Name, l);
1605 // 2 - Public property
1607 prop = BuildSimpleProperty (var.type, (string) var.identifier,
1608 field, (int) current_modifiers,
1609 (Attributes) current_attributes, l);
1611 CheckDef (current_container.AddProperty (prop), prop.Name, l);
1621 delegate_declaration
1623 identifier OPEN_PARENS
1624 opt_formal_parameter_list
1628 Location l = lexer.Location;
1629 // Module members are static by default, but delegates *can't* be declared static
1630 // so we must fix it, if mbas was the one actually responsible for this
1631 // instead of triggering an error.
1632 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1633 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1635 Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (current_container, TypeManager.system_void_expr,
1636 (int) current_modifiers,
1637 MakeName ((string) $3), (Parameters) $5,
1638 (Attributes) current_attributes, l);
1640 del.Namespace = current_namespace;
1641 CheckDef (current_container.AddDelegate (del), del.Name, l);
1644 identifier OPEN_PARENS
1645 opt_formal_parameter_list
1646 CLOSE_PARENS AS type
1648 Location l = lexer.Location;
1649 Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (
1651 (Expression) $8, (int) current_modifiers, MakeName ((string) $3),
1652 (Parameters) $5, (Attributes) current_attributes, l);
1654 del.Namespace = current_namespace;
1655 CheckDef (current_container.AddDelegate (del), del.Name, l);
1662 | HANDLES qualified_identifier
1664 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
1666 | HANDLES MYBASE DOT qualified_identifier
1668 // FIXME: this is blatantly wrong and crash-prone
1669 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
1675 | OPEN_PARENS CLOSE_PARENS
1678 static_constructor_declaration
1679 : SHARED SUB NEW opt_empty_parens EOL
1681 current_local_parameters = Parameters.EmptyReadOnlyParameters;
1683 oob_stack.Push (lexer.Location);
1685 Location l = (Location) oob_stack.Pop ();
1686 $$ = new Constructor ((string) "New", Parameters.EmptyReadOnlyParameters, (ConstructorInitializer) null, l);
1690 Constructor c = (Constructor) $1;
1691 c.Block = (Block) end_block();
1692 c.ModFlags = (int) current_modifiers;
1693 c.OptAttributes = current_attributes;
1695 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1696 current_local_parameters = null;
1700 constructor_declaration
1701 : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1703 current_local_parameters = (Parameters) $4;
1705 oob_stack.Push (lexer.Location);
1707 Location l = (Location) oob_stack.Pop ();
1708 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
1713 Constructor c = (Constructor) $1;
1714 c.Block = (Block) end_block();
1715 c.ModFlags = (int) current_modifiers;
1716 c.OptAttributes = current_attributes;
1718 // FIXME: This should happen at grammar level, but doing it
1719 // triggers a lot of conflicts/problems.
1720 c.Initializer = FixConstructorInitializer (ref c.Block.statements);
1722 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1723 current_local_parameters = null;
1728 opt_formal_parameter_list
1731 $$ = Parameters.EmptyReadOnlyParameters;
1733 | formal_parameter_list
1736 //Parameter p = ((Parameters) $1).FixedParameters[0];
1740 formal_parameter_list
1743 ArrayList pars_list = (ArrayList) $1;
1745 Parameter [] pars = new Parameter [pars_list.Count];
1746 pars_list.CopyTo (pars);
1747 $$ = new Parameters (pars, null, lexer.Location);
1749 | fixed_parameters COMMA parameter_array
1751 ArrayList pars_list = (ArrayList) $1;
1753 Parameter [] pars = new Parameter [pars_list.Count];
1754 pars_list.CopyTo (pars);
1756 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
1760 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1767 ArrayList pars = new ArrayList ();
1772 | fixed_parameters COMMA fixed_parameter
1774 ArrayList pars = (ArrayList) $1;
1783 opt_parameter_modifier
1784 identifier opt_rank_specifiers opt_type_spec opt_variable_initializer
1786 Parameter.Modifier pm = (Parameter.Modifier)$2;
1787 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
1790 if (opt_parm && ($6 == null))
1791 Report.Error (999, "Optional parameters must have a default value");
1794 if ((pm & Parameter.Modifier.REF) !=0)
1795 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
1797 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
1801 ptype = (Expression) $5;
1804 //string t = ((Expression) $5).ToString() + (string) $4;
1805 string t = ((Expression) $5).ToString() + VariableDeclaration.BuildRank ((ArrayList) $4);
1806 ptype = DecomposeQI (t, lexer.Location);
1808 $$ = new Parameter (ptype, (string) $3, pm,
1809 (Attributes) $1, (Expression) $6, opt_parm);
1814 : PARAM_ARRAY identifier opt_parens AS type
1816 string s_patype = ((Expression) $5).ToString();
1820 Expression patype = DecomposeQI (s_patype, Location.Null);
1821 $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
1822 // note ("type must be a single-dimension array type");
1829 | OPEN_PARENS CLOSE_PARENS
1833 opt_parameter_modifier
1834 : /* empty */ { $$ = Parameter.Modifier.VAL; }
1835 | parameter_modifiers { $$ = $1; }
1839 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
1840 | parameter_modifier { $$ = $1; }
1844 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
1845 | BYVAL { $$ = Parameter.Modifier.VAL; }
1846 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
1851 | statement_list end_of_stmt
1856 | statement_list end_of_stmt statement
1860 declaration_statement
1862 if ($1 != null && (Block) $1 != current_block){
1863 current_block.AddStatement ((Statement) $1);
1864 current_block = (Block) $1;
1867 | embedded_statement
1869 Statement s = (Statement) $1;
1871 current_block.AddStatement ((Statement) $1);
1874 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
1876 AddHandler ((Expression) $2, (string) $5);
1878 | RAISEEVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1880 RaiseEvent ((string) $2, (ArrayList) $4);
1882 /* | array_handling_statement */
1883 /* | empty_statement */
1886 Statement s = (Statement) $1;
1888 current_block.AddStatement ((Statement) $1);
1893 : identifier COLON end_of_stmt
1895 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
1897 if (!current_block.AddLabel ((string) $1, labeled)){
1898 Location l = lexer.Location;
1899 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
1901 current_block.AddStatement (labeled);
1907 : expression_statement
1908 | selection_statement
1909 | iteration_statement
1912 | array_handling_statement
1918 $$ = new EmptyStatement ();
1924 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
1926 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
1927 Expression e = (Expression) $2;
1934 Block b = end_block();
1941 array_handling_statement
1947 : REDIM opt_preserve redim_clauses
1949 ArrayList list = (ArrayList) $3;
1950 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
1957 : /* empty */ { $$ = false; }
1958 | PRESERVE { $$ = true; }
1964 ArrayList clauses = new ArrayList ();
1969 | redim_clauses COMMA redim_clause
1971 ArrayList clauses = (ArrayList) ($1);
1979 : invocation_expression
1981 Invocation i = (Invocation) $1;
1982 RedimClause rc = new RedimClause (i.expr, i.Arguments);
1988 : ERASE erase_clauses
1990 ArrayList list = (ArrayList) $2;
1991 foreach(Expression e in list)
1993 Erase r = new Erase (e, lexer.Location);
2002 ArrayList clauses = new ArrayList ();
2007 | erase_clauses COMMA erase_clause
2009 ArrayList clauses = (ArrayList) ($1);
2017 : primary_expression
2022 | continue_statement
2023 | */return_statement
2033 $$ = new Goto (current_block, (string) $2, lexer.Location);
2038 : THROW opt_expression
2040 $$ = new Throw ((Expression) $2, lexer.Location);
2047 $$ = new Exit ((ExitType)$2, lexer.Location);
2052 : DO { $$ = ExitType.DO; }
2053 | FOR { $$ = ExitType.FOR; }
2054 | WHILE { $$ = ExitType.WHILE; }
2055 | SELECT { $$ = ExitType.SELECT; }
2056 | SUB { $$ = ExitType.SUB; }
2057 | FUNCTION { $$ = ExitType.FUNCTION; }
2058 | PROPERTY { $$ = ExitType.PROPERTY; }
2059 | TRY { $$ = ExitType.TRY; }
2062 : RETURN opt_expression
2064 $$ = new Return ((Expression) $2, lexer.Location);
2076 : FOR EACH identifier IN
2078 oob_stack.Push (lexer.Location);
2080 expression end_of_stmt
2084 Block foreach_block = current_block;
2085 Location l = lexer.Location;
2086 LocalVariableReference v = null;
2089 vi = foreach_block.GetVariableInfo ((string) $3);
2091 // Get a reference to this variable.
2092 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2095 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2102 Block foreach_block = current_block;
2103 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2104 Block prev_block = end_block();
2105 Location l = (Location) oob_stack.Pop ();
2109 f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
2119 if (!UseExtendedSyntax)
2125 if (iterator_container == null){
2126 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2129 iterator_container.SetYields ();
2130 $$ = new Yield ((Expression) $2, lexer.Location);
2135 if (!UseExtendedSyntax)
2141 if (iterator_container == null){
2142 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2145 iterator_container.SetYields ();
2146 $$ = new YieldBreak (lexer.Location);
2166 tmp_catch_clauses = (ArrayList) $5;
2175 ArrayList s = new ArrayList ();
2177 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2184 // Now s contains the list of specific catch clauses
2185 // and g contains the general one.
2186 Block b = end_block();
2188 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2195 tmp_block = end_block();
2205 ArrayList s = new ArrayList ();
2206 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2208 if (catch_list != null){
2209 foreach (Catch cc in catch_list) {
2217 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2223 : /* empty */ { $$ = null; }
2230 ArrayList l = new ArrayList ();
2235 | catch_clauses catch_clause
2237 ArrayList l = (ArrayList) $1;
2245 : /* empty */ { $$ = null; }
2250 : CATCH opt_catch_args end_of_stmt
2252 Expression type = null;
2256 DictionaryEntry cc = (DictionaryEntry) $2;
2257 type = (Expression) cc.Key;
2258 id = (string) cc.Value;
2261 ArrayList one = new ArrayList ();
2262 Location loc = lexer.Location;
2264 one.Add (new VariableDeclaration (id, type, loc));
2268 current_block = new Block (current_block);
2269 Block b = declare_local_variables (type, one, loc);
2275 opt_statement_list {
2276 Expression type = null;
2278 Block b_catch = current_block;
2281 DictionaryEntry cc = (DictionaryEntry) $2;
2282 type = (Expression) cc.Key;
2283 id = (string) cc.Value;
2287 // FIXME: I can change this for an assignment.
2289 while (current_block != (Block) $1)
2290 current_block = current_block.Parent;
2294 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2299 : /* empty */ { $$ = null; }
2304 : identifier AS type
2306 $$ = new DictionaryEntry ($3, $1);
2312 : DO opt_do_construct end_of_stmt
2315 oob_stack.Push (lexer.Location);
2318 LOOP opt_do_construct
2320 Expression t_before = (Expression) $2;
2321 Expression t_after = (Expression) $7;
2324 if ((t_before != null) && (t_after != null))
2325 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2327 if ((t_before == null) && (t_after == null))
2328 t = new BoolLiteral (true);
2330 t = (t_before != null) ? t_before : t_after;
2332 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2334 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2335 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2336 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2338 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2343 : /* empty */ { $$ = null; }
2344 | while_or_until boolean_expression
2346 do_type = (DoOptions)$1;
2347 $$ = (Expression) $2;
2352 : WHILE { $$ = DoOptions.WHILE; }
2353 | UNTIL { $$ = DoOptions.UNTIL; }
2360 oob_stack.Push (lexer.Location);
2362 boolean_expression end_of_stmt
2366 Location l = (Location) oob_stack.Pop ();
2367 Block b = end_block();
2368 Expression e = (Expression) $3;
2369 $$ = new While ((Expression) e, (Statement) b, l);
2375 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2382 Block statement = end_block();
2383 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2385 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2386 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2387 for_var, (Expression) $6, lexer.Location);
2388 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2389 for_var, (Expression) $7, lexer.Location), lexer.Location);
2391 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2392 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2394 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2399 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2400 | STEP expression { $$ = $2; }
2409 : if_statement_open opt_then if_statement_rest
2413 | if_statement_open THEN pre_embedded_statement
2415 Location l = (Location) oob_stack.Pop ();
2416 tmp_expr = (Expression)expr_stack.Pop();
2417 $$ = new If ((Expression) tmp_expr, end_block(), l);
2421 pre_embedded_statement
2422 : embedded_statement
2424 Statement s = (Statement) $1;
2426 current_block.AddStatement ((Statement) $1);
2431 : IF boolean_expression
2433 oob_stack.Push (lexer.Location);
2435 tmp_expr = (Expression) $2;
2436 expr_stack.Push(tmp_expr);
2450 Location l = (Location) oob_stack.Pop ();
2451 Expression expr = (Expression)expr_stack.Pop();
2452 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2458 Block bl = end_block();
2459 tmp_blocks.Push(bl);
2465 Location l = (Location) oob_stack.Pop ();
2466 tmp_expr = (Expression)expr_stack.Pop();
2467 tmp_block = (Block) tmp_blocks.Pop();
2468 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2472 ELSEIF boolean_expression opt_then
2474 tmp_expr = (Expression) $4;
2475 expr_stack.Push(tmp_expr);
2476 tmp_block = end_block();
2477 tmp_blocks.Push(tmp_block);
2480 else_if_statement_rest
2482 Statement stmt = (Statement) statement_stack.Pop();
2483 Block bl = (Block) tmp_blocks.Pop();
2484 Expression expr = (Expression)expr_stack.Pop();
2485 Location l = (Location) oob_stack.Pop ();
2486 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
2491 else_if_statement_rest
2496 Location l = (Location) oob_stack.Pop ();
2498 Expression expr = (Expression)expr_stack.Pop();
2499 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
2500 statement_stack.Push(stmt);
2506 Block bl = end_block();
2507 tmp_blocks.Push(bl);
2513 Location l = (Location) oob_stack.Pop ();
2515 Expression expr = (Expression)expr_stack.Pop();
2516 Block bl = (Block)tmp_blocks.Pop();
2517 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
2518 statement_stack.Push(stmt);
2522 ELSEIF boolean_expression opt_then
2524 expr_stack.Push((Expression) $4);
2525 Block bl = end_block();
2526 tmp_blocks.Push(bl);
2529 else_if_statement_rest
2531 Location l = (Location) oob_stack.Pop ();
2533 Statement tmp_stmt = (Statement)statement_stack.Pop();
2534 Block bl = (Block) tmp_blocks.Pop();
2535 Expression expr = (Expression)expr_stack.Pop();
2536 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
2537 statement_stack.Push(stmt);
2542 : SELECT opt_case expression end_of_stmt
2544 oob_stack.Push (lexer.Location);
2545 switch_stack.Push (current_block);
2550 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2551 current_block = (Block) switch_stack.Pop ();
2556 : /* empty */ { $$ = null; }
2557 | case_sections { $$ = $1; }
2561 : case_sections case_section
2563 ArrayList sections = (ArrayList) $1;
2570 ArrayList sections = new ArrayList ();
2584 : CASE case_clauses ends
2590 //Block topmost = current_block;
2591 Block topmost = end_block();
2593 while (topmost.Implicit)
2594 topmost = topmost.Parent;
2596 // FIXME: This is a horrible hack which MUST go
2597 topmost.statements.Add (new Break (lexer.Location));
2598 $$ = new SwitchSection ((ArrayList) $2, topmost);
2601 /* FIXME: we should somehow flag an error
2602 (BC30321 'Case' cannot follow a 'Case Else'
2603 in the same 'Select' statement.)
2604 if Case Else is not the last of the Case clauses
2611 //Block topmost = current_block;
2612 Block topmost = end_block();
2614 while (topmost.Implicit)
2615 topmost = topmost.Parent;
2617 // FIXME: This is a horrible hack which MUST go
2618 topmost.statements.Add (new Break (lexer.Location));
2620 ArrayList a = new ArrayList();
2621 a.Add (new SwitchLabel (null, lexer.Location));
2622 $$ = new SwitchSection ((ArrayList) a, topmost);
2629 ArrayList labels = new ArrayList ();
2634 | case_clauses COMMA case_clause
2636 ArrayList labels = (ArrayList) ($1);
2644 : opt_is comparison_operator expression
2647 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
2669 expression_statement
2670 : statement_expression
2677 statement_expression
2678 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2679 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2680 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2683 object_creation_expression
2684 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2686 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2690 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
2694 array_creation_expression
2695 : object_creation_expression array_initializer
2698 ArrayList dims = new ArrayList();
2700 if (n.Arguments != null) {
2701 foreach (Argument a in n.Arguments) {
2706 Expression atype = n.RequestedType;
2708 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
2709 VariableDeclaration.VBFixIndexList (ref dims);
2710 $$ = new ArrayCreation (atype, dims, "", (ArrayList) $2, lexer.Location);
2714 string rank = VariableDeclaration.BuildRank (dims);
2715 $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
2717 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
2722 : object_creation_expression
2723 | array_creation_expression
2726 declaration_statement
2727 : local_variable_declaration
2730 DictionaryEntry de = (DictionaryEntry) $1;
2732 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2736 | local_constant_declaration
2739 DictionaryEntry de = (DictionaryEntry) $1;
2741 $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
2746 local_variable_declaration
2747 : DIM variable_declarators
2749 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
2754 local_constant_declaration
2755 : CONST constant_declarator
2758 $$ = new DictionaryEntry ($1, $2);
2765 : identifier ASSIGN constant_expression
2767 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
2771 variable_declarators
2772 : variable_declarator
2774 ArrayList decl = new ArrayList ();
2778 | variable_declarators COMMA variable_declarator
2780 ArrayList decls = (ArrayList) $1;
2787 : variable_identifier opt_type_decl opt_variable_initializer
2789 string varname = (string)$1;
2790 object varinit = $3;
2792 ArrayList a_dims = null;
2794 // Some checking is required for particularly weird declarations
2795 // like Dim a As Integer(,)
2797 vartype = (Expression) ((Pair) $2).First;
2798 if ($3 != null && $3 is ArrayList)
2799 Report.Error (205, "End of statement expected.");
2801 ArrayList args = (ArrayList) ((Pair) $2).Second;
2802 if (VariableDeclaration.IndexesSpecifiedInRank (args))
2803 Report.Error (638, "Array bounds cannot appear in type specifiers.");
2805 string s_vartype = vartype.ToString();
2808 for (int x = 0; x < args.Count; x++)
2812 vartype = DecomposeQI(s_vartype, Location.Null);
2815 vartype = (Expression) $2;
2818 Check for a declaration like Dim a(2) or Dim a(2,3)
2819 If this is the case, we must generate an ArrayCreationExpression
2820 and, in case, add the initializer after the array has been created.
2822 if (VariableDeclaration.IsArrayDecl (this)) {
2823 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
2824 a_dims = (ArrayList) current_rank_specifiers;
2825 VariableDeclaration.VBFixIndexLists (ref a_dims);
2826 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
2829 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
2832 if (vartype is New) {
2833 if (varinit != null) {
2834 Report.Error (30205, lexer.Location, "End of statement expected");
2840 vartype = ((New)vartype).RequestedType;
2843 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
2844 //Console.WriteLine ("varname: {0} - vartype: {1} - init: {2}", varname, vartype, varinit);
2849 : identifier opt_array_name_modifier
2852 current_rank_specifiers = (ArrayList) $2;
2863 $$ = (Expression) $2;
2869 | AS type rank_specifiers
2871 $$ = TypeManager.system_object_expr;
2880 | AS type OPEN_PARENS opt_argument_list CLOSE_PARENS
2882 $$ = new Pair ($2, $4);
2886 New n = new New ((Expression)$3, null, lexer.Location);
2887 $$ = (Expression) n;
2889 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2891 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
2892 $$ = (Expression) n;
2896 opt_array_name_modifier
2897 : /* empty */ { $$ = null; }
2898 | array_type_modifier { $$ = $1; }
2902 : rank_specifiers { $$ = $1; }
2905 opt_variable_initializer
2906 : /* empty */ { $$ = null; }
2907 | ASSIGN variable_initializer { $$ = $2; }
2910 variable_initializer
2923 : OPEN_BRACE CLOSE_BRACE
2925 ArrayList list = new ArrayList ();
2928 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
2930 $$ = (ArrayList) $2;
2934 variable_initializer_list
2935 : variable_initializer
2937 ArrayList list = new ArrayList ();
2941 | variable_initializer_list COMMA variable_initializer
2943 ArrayList list = (ArrayList) $1;
2964 ArrayList rs = new ArrayList();
2968 | rank_specifiers rank_specifier
2970 ArrayList rs = (ArrayList) $1;
2977 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
2986 ArrayList ds = new ArrayList();
2987 ds.Add (new EmptyExpression());
2992 ArrayList ds = (ArrayList) $1;
2993 ds.Add (new EmptyExpression());
3005 ArrayList ds = new ArrayList();
3006 ds.Add (new EmptyExpression());
3009 | dim_separators COMMA
3011 ArrayList ds = (ArrayList) $1;
3012 ds.Add (new EmptyExpression());
3020 ArrayList ds = new ArrayList();
3021 ds.Add ((Expression) $1);
3024 | dim_specifiers COMMA expression
3026 ArrayList ds = (ArrayList) $1;
3027 ds.Add ((Expression) $3);
3039 | qualified_identifier
3041 string name = (string) $1;
3043 $$ = DecomposeQI (name, lexer.Location);
3045 | parenthesized_expression
3047 | invocation_expression
3059 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3060 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3061 | NOTHING { $$ = NullLiteral.Null; }
3065 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3066 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3067 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3072 object v = lexer.Value;
3075 $$ = new IntLiteral ((Int32) v);
3077 $$ = new UIntLiteral ((UInt32) v);
3079 $$ = new LongLiteral ((Int64) v);
3080 else if (v is ulong)
3081 $$ = new ULongLiteral ((UInt64) v);
3083 Console.WriteLine ("OOPS. Unexpected result from scanner");
3089 : TRUE { $$ = new BoolLiteral (true); }
3090 | FALSE { $$ = new BoolLiteral (false); }
3093 parenthesized_expression
3094 : OPEN_PARENS expression CLOSE_PARENS
3099 : primary_expression DOT identifier
3102 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3105 if (with_stack.Count > 0) {
3106 Expression e = (Expression) with_stack.Peek();
3107 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3115 | primary_expression DOT NEW
3117 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3119 | predefined_type DOT identifier
3122 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3125 if (with_stack.Count > 0) {
3126 Expression e = (Expression) with_stack.Peek();
3127 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3141 invocation_expression
3142 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3145 Location l = lexer.Location;
3146 Report.Error (1, l, "THIS IS CRAZY");
3148 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3149 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3154 : MYBASE DOT IDENTIFIER
3156 $$ = new BaseAccess ((string) $3, lexer.Location);
3160 $$ = new BaseAccess ("New", lexer.Location);
3168 The 'argument' rule returns an 'empty' argument
3169 of type NoArg (used for default arguments in invocations)
3170 if no arguments are actually passed.
3172 If there is only one argument and it is o type NoArg,
3173 we return a null (empty) list
3175 ArrayList args = (ArrayList) $1;
3176 if (args.Count == 1 &&
3177 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3187 ArrayList list = new ArrayList ();
3191 | argument_list COMMA argument
3193 ArrayList list = (ArrayList) $1;
3202 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3204 | BYREF variable_reference
3206 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3210 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3215 : expression {/* note ("section 5.4"); */ $$ = $1; }
3221 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3226 : conditional_expression { $$ = $1; }
3227 | negation_expression
3228 /*| assignment_expression*/
3239 ArrayList list = new ArrayList ();
3243 | expression_list COMMA expression
3245 ArrayList list = (ArrayList) $1;
3252 : /*empty */ { $$ = null; }
3259 $$ = new This (current_block, lexer.Location);
3263 // FIXME: This is actually somewhat different from Me
3264 // because it is for accessing static (classifier) methods/properties/fields
3265 $$ = new This (current_block, lexer.Location);
3270 : primary_expression
3271 /*| NOT prefixed_unary_expression
3273 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3275 | cast_expression */
3279 : cast_operator OPEN_PARENS expression CLOSE_PARENS
3281 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3283 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3285 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3290 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3291 | CBYTE { $$ = TypeManager.system_byte_expr; }
3292 | CCHAR { $$ = TypeManager.system_char_expr; }
3293 | CDATE { $$ = TypeManager.system_decimal_expr; } //FIXME
3294 | CDBL { $$ = TypeManager.system_double_expr; }
3295 | CDEC { $$ = TypeManager.system_decimal_expr; }
3296 | CINT { $$ = TypeManager.system_int32_expr; }
3297 | CLNG { $$ = TypeManager.system_int64_expr; }
3298 | COBJ { $$ = TypeManager.system_object_expr; }
3299 | CSHORT { $$ = TypeManager.system_int16_expr; }
3300 | CSNG { $$ = TypeManager.system_single_expr; }
3301 | CSTR { $$ = TypeManager.system_string_expr; }
3305 // The idea to split this out is from Rhys' grammar
3306 // to solve the problem with casts.
3308 prefixed_unary_expression
3310 | PLUS prefixed_unary_expression
3312 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3314 | MINUS prefixed_unary_expression
3316 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3318 | ADDRESSOF prefixed_unary_expression
3320 // FIXME: We should generate an error if AddressOf is NOT used
3321 // during delegate creation
3326 multiplicative_expression
3327 : prefixed_unary_expression
3328 | multiplicative_expression STAR prefixed_unary_expression
3330 $$ = new Binary (Binary.Operator.Multiply,
3331 (Expression) $1, (Expression) $3, lexer.Location);
3333 | multiplicative_expression DIV prefixed_unary_expression
3335 $$ = new Binary (Binary.Operator.Division,
3336 (Expression) $1, (Expression) $3, lexer.Location);
3338 | multiplicative_expression OP_IDIV prefixed_unary_expression
3340 $$ = new Binary (Binary.Operator.Division,
3341 (Expression) $1, (Expression) $3, lexer.Location);
3343 | multiplicative_expression MOD prefixed_unary_expression
3345 $$ = new Binary (Binary.Operator.Modulus,
3346 (Expression) $1, (Expression) $3, lexer.Location);
3351 : multiplicative_expression
3352 | additive_expression PLUS multiplicative_expression
3354 $$ = new Binary (Binary.Operator.Addition,
3355 (Expression) $1, (Expression) $3, lexer.Location);
3357 | additive_expression MINUS multiplicative_expression
3359 $$ = new Binary (Binary.Operator.Subtraction,
3360 (Expression) $1, (Expression) $3, lexer.Location);
3362 | additive_expression OP_CONCAT multiplicative_expression
3364 // FIXME: This should only work for String expressions
3365 // We probably need to use something from the runtime
3366 $$ = new Binary (Binary.Operator.Addition,
3367 (Expression) $1, (Expression) $3, lexer.Location);
3371 relational_expression
3372 : additive_expression
3373 | relational_expression OP_LT additive_expression
3375 $$ = new Binary (Binary.Operator.LessThan,
3376 (Expression) $1, (Expression) $3, lexer.Location);
3378 | relational_expression OP_GT additive_expression
3380 $$ = new Binary (Binary.Operator.GreaterThan,
3381 (Expression) $1, (Expression) $3, lexer.Location);
3383 | relational_expression OP_LE additive_expression
3385 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3386 (Expression) $1, (Expression) $3, lexer.Location);
3388 | relational_expression OP_GE additive_expression
3390 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3391 (Expression) $1, (Expression) $3, lexer.Location);
3393 | relational_expression IS unary_expression
3395 $$ = new Binary (Binary.Operator.Equality,
3396 (Expression) $1, (Expression) $3, lexer.Location);
3398 | relational_expression AS type_name
3400 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3405 : relational_expression
3406 | equality_expression ASSIGN relational_expression
3408 $$ = new Binary (Binary.Operator.Equality,
3409 (Expression) $1, (Expression) $3, lexer.Location);
3411 | equality_expression OP_NE relational_expression
3413 $$ = new Binary (Binary.Operator.Inequality,
3414 (Expression) $1, (Expression) $3, lexer.Location);
3419 : equality_expression
3420 | and_expression AND equality_expression
3422 $$ = new Binary (Binary.Operator.BitwiseAnd,
3423 (Expression) $1, (Expression) $3, lexer.Location);
3427 exclusive_or_expression
3429 | exclusive_or_expression OP_XOR and_expression
3431 $$ = new Binary (Binary.Operator.ExclusiveOr,
3432 (Expression) $1, (Expression) $3, lexer.Location);
3436 conditional_and_expression
3437 : exclusive_or_expression
3438 | conditional_and_expression AND exclusive_or_expression
3440 $$ = new Binary (Binary.Operator.LogicalAnd,
3441 (Expression) $1, (Expression) $3, lexer.Location);
3443 | conditional_and_expression ANDALSO exclusive_or_expression
3444 { // FIXME: this is likely to be broken
3445 $$ = new Binary (Binary.Operator.LogicalAnd,
3446 (Expression) $1, (Expression) $3, lexer.Location);
3450 conditional_or_expression
3451 : conditional_and_expression
3452 | conditional_or_expression OR conditional_and_expression
3454 $$ = new Binary (Binary.Operator.LogicalOr,
3455 (Expression) $1, (Expression) $3, lexer.Location);
3457 | conditional_or_expression ORELSE conditional_and_expression
3458 { // FIXME: this is likely to be broken
3459 $$ = new Binary (Binary.Operator.LogicalOr,
3460 (Expression) $1, (Expression) $3, lexer.Location);
3464 conditional_expression
3465 : conditional_or_expression
3468 assignment_expression
3469 : prefixed_unary_expression ASSIGN expression
3471 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3473 | prefixed_unary_expression OP_MULT_ASSIGN expression
3475 Location l = lexer.Location;
3477 $$ = new CompoundAssign (
3478 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3480 | prefixed_unary_expression OP_DIV_ASSIGN expression
3482 Location l = lexer.Location;
3484 $$ = new CompoundAssign (
3485 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3487 | prefixed_unary_expression OP_IDIV_ASSIGN expression
3489 Location l = lexer.Location;
3491 $$ = new CompoundAssign (
3492 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3494 | prefixed_unary_expression OP_ADD_ASSIGN expression
3496 Location l = lexer.Location;
3498 $$ = new CompoundAssign (
3499 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3501 | prefixed_unary_expression OP_SUB_ASSIGN expression
3503 Location l = lexer.Location;
3505 $$ = new CompoundAssign (
3506 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3508 | prefixed_unary_expression OP_CONCAT_ASSIGN expression
3510 Location l = lexer.Location;
3512 $$ = new CompoundAssign (
3513 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3526 : type_name { /* class_type */
3528 This does interfaces, delegates, struct_types, class_types,
3529 parent classes, and more! 4.2
3531 $$ = DecomposeQI ((string) $1, lexer.Location);
3541 ArrayList types = new ArrayList ();
3546 | type_list COMMA type
3548 ArrayList types = (ArrayList) $1;
3556 : namespace_or_type_name
3559 namespace_or_type_name
3560 : qualified_identifier
3563 /* Built-in / Integral types */
3565 : OBJECT { $$ = TypeManager.system_object_expr; }
3566 | STRING { $$ = TypeManager.system_string_expr; }
3567 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
3568 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
3569 | SINGLE { $$ = TypeManager.system_single_expr; }
3570 | DOUBLE { $$ = TypeManager.system_double_expr; }
3576 | BYTE { $$ = TypeManager.system_byte_expr; }
3577 | SHORT { $$ = TypeManager.system_int16_expr; }
3578 | LONG { $$ = TypeManager.system_int64_expr; }
3579 | INTEGER { $$ = TypeManager.system_int32_expr; }
3580 | CHAR { $$ = TypeManager.system_char_expr; }
3582 | SBYTE { $$ = TypeManager.system_sbyte_expr; }
3583 | UINT { $$ = TypeManager.system_uint32_expr; }
3584 | ULONG { $$ = TypeManager.system_uint64_expr; }
3585 | USHORT { $$ = TypeManager.system_uint16_expr; }
3586 | CHAR { $$ = TypeManager.system_char_expr; }
3587 | VOID { $$ = TypeManager.system_void_expr; }
3604 public Tokenizer Lexer {
3610 public static Expression DecomposeQI (string name, Location loc)
3614 if (name.IndexOf ('.') == -1){
3615 return new SimpleName (name, loc);
3617 int pos = name.LastIndexOf (".");
3618 string left = name.Substring (0, pos);
3619 string right = name.Substring (pos + 1);
3621 o = DecomposeQI (left, loc);
3623 return new MemberAccess (o, right, loc);
3627 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
3629 Block implicit_block;
3630 ArrayList inits = null;
3633 // We use the `Used' property to check whether statements
3634 // have been added to the current block. If so, we need
3635 // to create another block to contain the new declaration
3636 // otherwise, as an optimization, we use the same block to
3637 // add the declaration.
3639 // FIXME: A further optimization is to check if the statements
3640 // that were added were added as part of the initialization
3641 // below. In which case, no other statements have been executed
3642 // and we might be able to reduce the number of blocks for
3643 // situations like this:
3645 // int j = 1; int k = j + 1;
3648 VariableDeclaration.FixupTypes (variable_declarators);
3650 if (current_block.Used) {
3651 implicit_block = new Block (current_block, true, loc, Location.Null);
3652 implicit_block.AddChildVariableNames (current_block);
3654 implicit_block = current_block;
3656 foreach (VariableDeclaration decl in variable_declarators){
3657 Expression type = decl.type;
3658 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
3659 if (decl.expression_or_array_initializer != null){
3661 inits = new ArrayList ();
3668 return implicit_block;
3670 foreach (VariableDeclaration decl in inits){
3673 Expression type = decl.type;
3675 if ((decl.expression_or_array_initializer is Expression) ||
3676 (decl.expression_or_array_initializer is New)) {
3677 expr = (Expression) decl.expression_or_array_initializer;
3679 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3681 expr = new ArrayCreation (type, "", init, decl.Location);
3684 LocalVariableReference var;
3685 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
3687 assign = new Assign (var, expr, decl.Location);
3689 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
3692 return implicit_block;
3696 Block declare_local_constant (Expression type, VariableDeclaration decl)
3698 Block implicit_block;
3700 if (current_block.Used)
3701 implicit_block = new Block (current_block, true);
3703 implicit_block = current_block;
3705 if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
3706 current_local_parameters, decl.Location))){
3709 return implicit_block;
3713 // A class used to pass around variable declarations and constants
3715 public class VariableDeclaration {
3716 public string identifier;
3717 public object expression_or_array_initializer;
3718 public Location Location;
3719 public Attributes OptAttributes;
3720 public Expression type;
3721 public ArrayList dims;
3723 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
3725 this.identifier = id;
3726 this.expression_or_array_initializer = eoai;
3728 this.OptAttributes = opt_attrs;
3733 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
3737 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
3741 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
3742 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
3746 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
3748 // FIXME : This is broken: only the first rank is parsed
3749 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
3752 public static void FixupTypes (ArrayList vars)
3754 int varcount = vars.Count;
3755 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
3757 if (last_var.type == null)
3758 last_var.type = TypeManager.system_object_expr;
3760 Expression cur_type = last_var.type;
3761 int n = varcount - 1;
3764 VariableDeclaration var = (VariableDeclaration) vars[n--];
3765 if (var.type == null)
3766 var.type = cur_type;
3768 cur_type = var.type;
3772 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
3776 if (IndexList != null) {
3777 foreach (Expression e in IndexList)
3778 if (!(e is EmptyExpression)) {
3787 public static bool IndexesSpecified (ArrayList ranks)
3791 if (ranks != null) {
3792 foreach (ArrayList IndexList in ranks) {
3793 if (IndexesSpecifiedInRank (IndexList)) {
3802 public static string StripDims (string varname, ref string d)
3804 string res = varname;
3807 if (varname.IndexOf("[") >= 0) {
3808 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
3809 res = varname.Substring(0, varname.IndexOf("["));
3815 public static string StripDims (string varname)
3819 return (StripDims(varname, ref dres));
3822 public static string StripIndexesFromDims (string dims)
3824 StringBuilder sb = new StringBuilder();
3826 foreach (char c in dims)
3827 if (c == ',' || c == ']' || c == '[')
3830 return sb.ToString();
3833 public static string BuildRank (ArrayList rank)
3838 for (int x = 0; x < (rank.Count -1 ); x++)
3845 public static string BuildRanks (Parser t)
3849 foreach (ArrayList rank in t.current_rank_specifiers)
3850 res += BuildRank (rank);
3855 public static void VBFixIndexList (ref ArrayList IndexList)
3857 if (IndexList != null) {
3858 for (int x = 0; x < IndexList.Count; x++) {
3859 Expression e = (Expression) IndexList[x];
3860 if (!(e is EmptyExpression)) {
3861 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
3867 public static bool IsArrayDecl (Parser t)
3869 // return (varname.IndexOf("[") >= 0);
3870 return (t.current_rank_specifiers != null);
3873 public static void VBFixIndexLists (ref ArrayList ranks)
3875 if (ranks != null) {
3876 for (int x = 0; x < ranks.Count; x++) {
3877 ArrayList IndexList = (ArrayList) ranks[x];
3878 VBFixIndexList (ref IndexList);
3883 public static void FixupArrayTypes (ArrayList vars)
3885 int varcount = vars.Count;
3888 foreach (VariableDeclaration var in vars) {
3889 if (var.identifier.EndsWith(",")) {
3890 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
3891 var.identifier.LastIndexOf(",")) + "]";
3892 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
3893 var.type = new ComposedCast (var.type, (string) dims, var.Location);
3900 public Property BuildSimpleProperty (Expression p_type, string name,
3901 Field p_fld, int mod_flags,
3902 Attributes attrs, Location loc)
3905 Block get_block, set_block;
3906 Accessor acc_set, acc_get;
3907 StatementExpression a_set;
3912 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
3913 args = new Parameter [1];
3914 args [0] = implicit_value_parameter;
3916 Parameters set_params = new Parameters (args, null, loc);
3917 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
3918 (Expression) new SimpleName("value", loc), loc), loc);
3920 set_block = new Block (current_block, set_params, loc, Location.Null);
3921 set_block.AddStatement ((Statement) a_set);
3922 acc_set = new Accessor (set_block, attrs);
3925 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
3926 get_block = new Block (current_block, null, loc, Location.Null);
3927 get_block.AddStatement ((Statement) a_get);
3928 acc_get = new Accessor (get_block, attrs);
3930 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
3937 current_block = new Block (current_block, current_local_parameters,
3938 lexer.Location, Location.Null);
3945 while (current_block.Implicit)
3946 current_block = current_block.Parent;
3948 res = current_block;
3950 current_block.SetEndLocation (lexer.Location);
3951 current_block = current_block.Parent;
3956 private void AddHandler (Expression evt_definition, string handler_name)
3958 AddHandler (current_block, evt_definition, handler_name);
3961 void CheckAttributeTarget (string a)
3965 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
3969 Location l = lexer.Location;
3970 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
3975 private void AddHandler (Block b, Expression evt_id, string handler_name)
3977 Location loc = lexer.Location;
3978 string evt_target = evt_id.ToString();
3979 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
3980 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
3984 private void RaiseEvent (string evt_name, ArrayList args)
3986 Location loc = lexer.Location;
3988 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
3989 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
3990 current_block.AddStatement (s);
3993 // FIXME: THIS DOES NOT WORK!!!
3994 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
3996 Location loc = lexer.Location;
3997 ArrayList neh_args = new ArrayList();
3998 neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
4000 ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
4002 CompoundAssign ca = new CompoundAssign (
4003 Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
4005 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc));
4010 // This method is used to get at the complete string representation of
4011 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4012 // This is necessary because local_variable_type admits primary_expression
4013 // as the type of the variable. So we do some extra checking
4015 string GetQualifiedIdentifier (Expression expr)
4017 if (expr is SimpleName)
4018 return ((SimpleName)expr).Name;
4019 else if (expr is MemberAccess)
4020 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4022 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4026 private void RemoveHandler (Expression evt_definition, string handler_name)
4028 RemoveHandler (current_block, evt_definition, handler_name);
4031 private ConstructorInitializer FixConstructorInitializer (ref ArrayList s)
4033 ConstructorInitializer ci = null;
4036 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4037 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4039 if (i.expr is BaseAccess) {
4040 BaseAccess ba = (BaseAccess) i.expr;
4041 if (ba.member == "New" || ba.member == ".ctor") {
4042 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4046 if (i.expr.ToString() == "Mono.CSharp.This..ctor") {
4047 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4055 void Error_ExpectingTypeName (Location l, Expression expr)
4057 if (expr is Invocation){
4058 Report.Error (1002, l, "; expected");
4060 Report.Error (-1, l, "Invalid Type definition");
4064 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4068 private void ReportError9998()
4070 Report.Error (9998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4073 protected override int parse ()
4075 current_namespace = new Namespace (null, RootContext.RootNamespace);
4076 current_container = RootContext.Tree.Types;
4077 current_container.Namespace = current_namespace;
4078 oob_stack = new Stack ();
4079 switch_stack = new Stack ();
4080 expr_stack = new Stack ();
4081 tmp_blocks = new Stack();
4082 with_stack = new Stack();
4083 statement_stack = new Stack();
4085 UseExtendedSyntax = name.EndsWith(".mbs");
4086 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4087 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4088 OptionCompareBinary = InitialOptionCompareBinary;
4090 lexer = new Tokenizer (input, name, defines);
4091 StringBuilder value = new StringBuilder ();
4092 //yacc_verbose_flag=true;
4095 if (yacc_verbose_flag)
4096 yyparse (lexer, new yydebug.yyDebugSimple ());
4102 Report.Error (9999, lexer.Location, lexer.location + "Parsing error in " + lexer.ref_name + "\n");
4103 Console.WriteLine (e);
4106 return Report.Errors;