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"
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
366 %start compilation_unit
370 : opt_option_directives
371 opt_imports_directives
380 opt_option_directives
387 | option_directives option_directive
391 : option_explicit_directive
392 | option_strict_directive
393 | option_compare_directive
422 option_explicit_directive
423 : OPTION EXPLICIT on_off EOL
425 if (!UseExtendedSyntax)
426 OptionExplicit = (bool)$3;
429 9999, lexer.Location,
430 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
435 option_strict_directive
436 : OPTION STRICT on_off EOL
438 if (!UseExtendedSyntax)
439 OptionStrict = (bool)$3;
442 9999, lexer.Location,
443 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
447 option_compare_directive
448 : OPTION COMPARE text_or_binary EOL
450 OptionCompareBinary = (bool)$3;
461 | declarations declaration
465 : namespace_declaration
472 Class c = (Class) $1;
473 mod_flags = c.ModFlags;
475 } else if ($1 is Struct){
476 Struct s = (Struct) $1;
477 mod_flags = s.ModFlags;
479 } else if ($1 is Module){
480 Module m = (Module) $1;
481 mod_flags = m.ModFlags;
486 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
488 1527, lexer.Location,
489 "Namespace elements cannot be explicitly " +
490 "declared private or protected in '" + name + "'");
506 | qualified_identifier DOT identifier
508 $$ = (($1).ToString ()) + "." + ($3.ToString ());
511 opt_imports_directives
518 | imports_directives imports_directive
522 : IMPORTS imports_terms EOL
527 | imports_terms COMMA imports_terms
531 : qualified_identifier
533 current_namespace.Using ((string) $1, lexer.Location);
535 | qualified_identifier ASSIGN qualified_identifier
537 current_namespace.UsingAlias ((string) $1, (string) $3, lexer.Location);
543 | attribute_sections { $$ = $1; }
549 AttributeSection sect = (AttributeSection) $1;
551 if (sect.Target == "assembly")
552 RootContext.AddGlobalAttributeSection (current_container, sect);
554 $$ = new Attributes ((AttributeSection) $1, lexer.Location);
558 FIXME: we should check if extended syntax is enabled;
559 otherwise an exception should be thrown since VB.NET
560 only allows one attribute section
562 | attribute_sections attribute_section
564 Attributes attrs = null;
565 AttributeSection sect = (AttributeSection) $2;
567 if (sect.Target == "assembly")
568 RootContext.AddGlobalAttributeSection (current_container, sect);
571 attrs = (Attributes) $1;
572 attrs.AddAttributeSection (sect);
580 : OP_LT attribute_target_specifier attribute_list OP_GT
582 string target = null;
585 target = (string) $2;
587 $$ = new AttributeSection (target, (ArrayList) $3);
589 | OP_LT attribute_list OP_GT
591 $$ = new AttributeSection (null, (ArrayList) $2);
595 attribute_target_specifier
596 : attribute_target COLON
605 CheckAttributeTarget ((string) $1);
608 | EVENT { $$ = "event"; }
609 | RETURN { $$ = "return"; }
615 ArrayList attrs = new ArrayList ();
621 | attribute_list COMMA attribute
623 ArrayList attrs = (ArrayList) $1;
635 opt_attribute_arguments
637 $$ = new Mono.CSharp.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
645 opt_attribute_arguments
646 : /* empty */ { $$ = null; }
647 | OPEN_PARENS attribute_arguments CLOSE_PARENS
654 : opt_positional_argument_list
659 ArrayList args = new ArrayList ();
665 | positional_argument_list COMMA named_argument_list
667 ArrayList args = new ArrayList ();
673 | named_argument_list
675 ArrayList args = new ArrayList ();
684 opt_positional_argument_list
685 : /* empty */ { $$ = null; }
686 | positional_argument_list
689 positional_argument_list
692 ArrayList args = new ArrayList ();
693 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
697 | positional_argument_list COMMA expression
699 ArrayList args = (ArrayList) $1;
700 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
709 ArrayList args = new ArrayList ();
714 | named_argument_list COMMA named_argument
716 ArrayList args = (ArrayList) $1;
724 : identifier ATTR_ASSIGN expression
726 $$ = new DictionaryEntry (
728 new Argument ((Expression) $3, Argument.AType.Expression));
732 namespace_declaration
733 : opt_attributes NAMESPACE qualified_identifier EOL
735 Attributes attrs = (Attributes) $1;
738 foreach (AttributeSection asec in attrs.AttributeSections)
739 if (asec.Target == "assembly")
740 RootContext.AddGlobalAttributeSection (current_container, asec);
743 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
745 opt_imports_directives
749 current_namespace = current_namespace.Parent;
757 current_attributes = (Attributes) $1;
758 current_modifiers = (int) $2;
760 type_spec_declaration
763 type_spec_declaration
766 | interface_declaration
767 | delegate_declaration
773 : CLASS identifier EOL opt_class_base
778 name = MakeName ((string) $2);
779 new_class = new Class (current_container, name, current_modifiers,
780 (Attributes) current_attributes, lexer.Location);
782 current_container = new_class;
783 current_container.Namespace = current_namespace;
784 RootContext.Tree.RecordDecl (name, new_class);
786 opt_class_member_declarations
789 Class new_class = (Class) current_container;
790 new_class.Bases = (ArrayList) $4;
792 current_container = current_container.Parent;
793 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
800 : /* empty */ { $$ = null; }
801 | class_base { $$ = $1; }
805 : inherits_or_implements type_list EOL { $$ = $2; }
808 inherits_or_implements
814 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
815 | modifiers { $$ = $1; current_modifiers = (int) $1; }
825 if ((m1 & m2) != 0) {
826 Location l = lexer.Location;
827 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
829 $$ = (int) (m1 | m2);
834 : PUBLIC { $$ = Modifiers.PUBLIC; }
835 | PROTECTED { $$ = Modifiers.PROTECTED; }
836 | PRIVATE { $$ = Modifiers.PRIVATE; }
837 | SHARED { $$ = Modifiers.STATIC; }
838 | FRIEND { $$ = Modifiers.INTERNAL; }
839 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
840 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
841 | NOTOVERRIDABLE { $$ = 0; }
842 | OVERLOADS { $$ = 0; }
843 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
847 : MODULE identifier EOL
851 name = MakeName((string) $2);
852 new_module = new Module(current_container,
854 current_modifiers, // already checks then
855 (Attributes) current_attributes,
857 current_container = new_module;
858 current_container.Namespace = current_namespace;
859 RootContext.Tree.RecordDecl(name, new_module);
861 opt_module_member_declarations
864 Module new_module = (Module)current_container;
866 current_container = current_container.Parent;
867 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
873 opt_module_member_declarations
875 | module_member_declarations
878 module_member_declarations
879 : module_member_declaration
880 | module_member_declarations module_member_declaration
883 module_member_declaration
887 current_attributes = (Attributes) $1;
888 current_modifiers = (int) $2 | (int)Modifiers.STATIC; // FIXME: for type_declaration it can result in trouble
890 module_member_declarator
896 module_member_declarator
897 : static_constructor_declaration
900 Method method = (Method) $1;
901 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
904 | withevents_declaration /* This is a field but must be treated specially, see below */
905 | constant_declaration
906 | property_declaration
911 constant_declaration // TODO: implement truly the logic
912 : CONST identifier ASSIGN constant_expression
913 | CONST identifier AS qualified_identifier ASSIGN constant_expression
916 opt_class_member_declarations
918 | class_member_declarations
921 class_member_declarations
922 : class_member_declaration
923 | class_member_declarations class_member_declaration
926 class_member_declaration
930 current_attributes = (Attributes) $1;
931 current_modifiers = (int) $2;
933 class_member_declarator
939 class_member_declarator
940 : constructor_declaration
943 Method method = (Method) $1;
944 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
947 | constant_declaration
948 | property_declaration
950 | withevents_declaration /* This is a field but must be treated specially, see below */
951 /*| type_declaration */
960 | must_override_declaration
963 must_override_declaration
964 : must_override_sub_declaration
965 | must_override_func_declaration
968 must_override_sub_declaration
969 : MUSTOVERRIDE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
971 if (current_container is Module)
972 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
974 if (current_container is Struct)
975 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
977 current_modifiers |= Modifiers.ABSTRACT;
979 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
980 (Parameters) $5, null, null, lexer.Location);
982 if (!(current_container is Class))
983 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
985 // FIXME ASAP: This will crash the compiler at resolution time
990 must_override_func_declaration
991 : MUSTOVERRIDE FUNCTION identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type EOL
993 if (current_container is Module)
994 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
996 if (current_container is Struct)
997 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
999 current_modifiers |= Modifiers.ABSTRACT;
1001 Method method = new Method ((Expression) $8, (int) current_modifiers, (string) $3,
1002 (Parameters) $5, null, null, lexer.Location);
1004 if (!(current_container is Class))
1005 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1007 // FIXME ASAP: This will crash the compiler at resolution time
1013 : SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler opt_implement_clause EOL
1015 current_local_parameters = (Parameters) $4;
1018 /* This is WEIRD: declaring a method (sub) in a module as static will
1019 trigger a syntax error, but the same methods MUST be static in order
1020 to be properly called
1022 /* THIS SHOULD NOT BE NEEDED ANYMORE
1023 if (current_container is Module) {
1024 if ((current_modifiers & Modifiers.STATIC) != 0) {
1025 Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
1029 current_modifiers = Modifiers.STATIC;
1034 // Structure members are Public by default
1035 if ((current_container is Struct) && (current_modifiers == 0))
1036 current_modifiers = Modifiers.PUBLIC;
1041 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1042 (Parameters) current_local_parameters, null, (Expression) $7,
1045 method.Block = (Block) end_block();
1048 if ($6 != null) { /* we have an event handler to take care of */
1049 // This wouldn't work: AddHandler ((Expression)$6, (string) $2);
1050 string evt_def = ((MemberAccess)$6).ToString();
1051 int pos = evt_def.LastIndexOf (".");
1052 string evt_target = ((string) $2).Substring (0, pos);
1054 foreach (Property p in current_container.Properties) {
1055 if (p.Name == evt_target) {
1057 // RemoveHandler (p.Set.Block, (Expression)$6, (string) $2);
1058 AddHandler (p.Set.Block, (Expression)$6, (string) $2);
1067 : FUNCTION identifier
1068 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type opt_implement_clause EOL
1071 current_local_parameters = (Parameters) $4;
1074 /* This is WEIRD: declaring a method (sub) in a module as static will
1075 trigger a syntax error, but the same methods MUST be static in order
1076 to be properly called
1078 /* THIS SHOULD NOT BE NEEDED ANYMORE
1079 if (current_container is Module) {
1080 if ((current_modifiers & Modifiers.STATIC) != 0) {
1081 Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
1085 current_modifiers |= Modifiers.STATIC;
1089 // Structure members are Public by default
1090 if ((current_container is Struct) && (current_modifiers == 0))
1091 current_modifiers = Modifiers.PUBLIC;
1092 // Add local var declaration
1094 ArrayList retval = new ArrayList ();
1095 retval.Add (new VariableDeclaration ((string) $2, (Expression) $7, lexer.Location));
1096 declare_local_variables ((Expression) $7, retval, lexer.Location);
1101 Method method = new Method ((Expression) $7, (int) current_modifiers, (string) $2,
1102 (Parameters) current_local_parameters, null,
1103 (Expression) $7, lexer.Location);
1104 method.Block = end_block();
1106 /*Console.WriteLine ("Declaring Function '{0}' with {1} statements and {2} arguments",
1107 current_container.Name + "." + (string) $2,
1108 method.Block.statements.Count,
1109 current_local_parameters.FixedParameters != null ? current_local_parameters.FixedParameters.Length : 0);
1115 : STRUCTURE identifier EOL
1116 opt_implement_clause
1119 string full_struct_name = MakeName ((string) $2);
1121 new_struct = new Struct (current_container, full_struct_name,
1122 (int) current_modifiers,
1123 (Attributes) current_attributes, lexer.Location);
1124 current_container = new_struct;
1125 current_container.Namespace = current_namespace;
1126 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1128 opt_struct_member_declarations
1130 Struct new_struct = (Struct) current_container;
1133 new_struct.Bases = (ArrayList) $4;
1135 current_container = current_container.Parent;
1136 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1142 opt_struct_member_declarations
1144 | struct_member_declarations
1147 struct_member_declarations
1148 : struct_member_declaration
1149 | struct_member_declarations struct_member_declaration
1152 struct_member_declaration
1154 struct_member_declarator
1156 struct_member_declarator
1158 //| constant_declaration
1159 | method_declaration
1160 | property_declaration
1162 | constructor_declaration
1166 * This is only included so we can flag error 575:
1167 * destructors only allowed on class types
1169 //| destructor_declaration
1173 : EVENT identifier AS type EOL
1175 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1177 Event e = new Event ((Expression) $4, var.identifier,
1178 null, current_modifiers, null, null,
1179 current_attributes, lexer.Location);
1181 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1184 // | EVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1186 // throw new NotSupportedException();
1191 : ENUM identifier opt_type_spec EOL
1192 opt_enum_member_declarations
1194 Location enum_location = lexer.Location;
1195 string full_name = MakeName ((string) $2);
1196 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1197 ArrayList enum_members = (ArrayList) $5;
1199 Mono.CSharp.Enum e = new Mono.CSharp.Enum (current_container, enum_type,
1200 (int) current_modifiers, full_name,
1201 (Attributes) current_attributes, enum_location);
1203 foreach (VariableDeclaration ev in enum_members) {
1204 Location loc = (Location) ev.Location;
1206 CheckDef (e.AddEnumMember (ev.identifier,
1207 (Expression) ev.expression_or_array_initializer,
1208 loc, ev.OptAttributes), ev.identifier, loc);
1211 e.Namespace = current_namespace;
1213 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1214 RootContext.Tree.RecordDecl (full_name, e);
1220 opt_enum_member_declarations
1221 : /* empty */ { $$ = new ArrayList (); }
1222 | enum_member_declarations { $$ = $1; }
1225 enum_member_declarations
1226 : enum_member_declaration
1228 ArrayList l = new ArrayList ();
1233 | enum_member_declarations enum_member_declaration
1235 ArrayList l = (ArrayList) $1;
1243 enum_member_declaration
1244 : opt_attributes identifier EOL
1246 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1248 | opt_attributes identifier
1250 $$ = lexer.Location;
1252 ASSIGN expression EOL
1254 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1258 interface_declaration
1259 : INTERFACE identifier EOL
1261 Interface new_interface;
1262 string full_interface_name = MakeName ((string) $2);
1264 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1265 (Attributes) current_attributes, lexer.Location);
1266 if (current_interface != null) {
1267 Location l = lexer.Location;
1268 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1270 current_interface = new_interface;
1271 new_interface.Namespace = current_namespace;
1272 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1277 Interface new_interface = (Interface) current_interface;
1280 new_interface.Bases = (ArrayList) $5;
1282 current_interface = null;
1283 CheckDef (current_container.AddInterface (new_interface),
1284 new_interface.Name, new_interface.Location);
1291 : /* empty */ { $$ = null; }
1296 : INHERITS interface_type_list { $$ = $2; }
1302 ArrayList interfaces = new ArrayList ();
1304 interfaces.Add ($1);
1307 | interface_type_list COMMA interface_type
1309 ArrayList interfaces = (ArrayList) $1;
1310 interfaces.Add ($3);
1316 : opt_interface_member_declarations
1319 opt_interface_member_declarations
1321 | interface_member_declarations
1324 interface_member_declarations
1325 : interface_member_declaration
1326 | interface_member_declarations interface_member_declaration
1329 interface_member_declaration
1330 : interface_method_declaration
1332 InterfaceMethod m = (InterfaceMethod) $1;
1334 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1336 | interface_property_declaration
1338 InterfaceProperty p = (InterfaceProperty) $1;
1340 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1342 | interface_event_declaration
1344 InterfaceEvent e = (InterfaceEvent) $1;
1346 CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1351 : /* empty */ { $$ = false; }
1352 | NEW { $$ = true; }
1355 interface_method_declaration
1357 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1359 $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
1360 (Parameters) $4, current_attributes, lexer.Location);
1362 | FUNCTION identifier
1363 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
1365 $$ = new InterfaceMethod (
1366 (Expression) $7, (string) $2, false, (Parameters) $4,
1367 current_attributes, lexer.Location);
1371 interface_property_declaration
1372 : PROPERTY identifier
1374 opt_formal_parameter_list
1375 CLOSE_PARENS opt_type_spec EOL
1377 // FIXME we MUST pass property parameters
1378 $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
1379 true, true, current_attributes,
1384 opt_access_specifier
1386 | READONLY { $$ = Modifiers.READONLY; }
1387 | WRITEONLY { $$ = 0; }
1388 | DEFAULT { $$ = 0; }
1391 interface_event_declaration
1392 : opt_attributes opt_new EVENT type identifier EOL
1394 $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
1399 property_declaration
1400 : opt_access_specifier PROPERTY identifier opt_property_parameters AS type opt_implement_clause EOL
1402 get_implicit_value_parameter_type = (Expression) $6;
1403 get_implicit_value_parameter_name = (string) $3;
1405 current_local_parameters = (Parameters) $4;
1406 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1407 get_parameters = current_local_parameters.Copy (lexer.Location);
1408 set_parameters = current_local_parameters.Copy (lexer.Location);
1412 get_parameters = Parameters.EmptyReadOnlyParameters;
1413 set_parameters = new Parameters (null, null ,lexer.Location);
1415 lexer.PropertyParsing = true;
1417 $$ = lexer.Location;
1419 accessor_declarations
1422 lexer.PropertyParsing = false;
1425 Pair pair = (Pair) $10;
1426 Accessor get_block = (Accessor) pair.First;
1427 Accessor set_block = (Accessor) pair.Second;
1429 Location loc = lexer.Location;
1431 // Structure members are Public by default
1432 if ((current_container is Struct) && (current_modifiers == 0))
1433 current_modifiers = Modifiers.PUBLIC;
1435 prop = new Property ((Expression) $6, (string) $3, current_modifiers, get_block, set_block,
1436 current_attributes, loc, set_implicit_value_parameter_name,
1437 get_parameters, set_parameters, (Expression) $7);
1439 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1440 get_implicit_value_parameter_type = null;
1441 set_implicit_value_parameter_type = null;
1442 get_parameters = null;
1443 set_parameters = null;
1444 current_local_parameters = null;
1448 opt_property_parameters
1451 $$ = Parameters.EmptyReadOnlyParameters;
1453 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1459 opt_implement_clause
1464 | IMPLEMENTS qualified_identifier
1466 $$ = DecomposeQI ((string)$2, lexer.Location);
1470 accessor_declarations
1471 : get_accessor_declaration opt_set_accessor_declaration
1473 $$ = new Pair ($1, $2);
1475 | set_accessor_declaration opt_get_accessor_declaration
1477 $$ = new Pair ($2, $1);
1481 opt_get_accessor_declaration
1482 : /* empty */ { $$ = null; }
1483 | get_accessor_declaration
1486 opt_set_accessor_declaration
1487 : /* empty */ { $$ = null; }
1488 | set_accessor_declaration
1491 get_accessor_declaration
1492 : opt_attributes GET EOL
1494 current_local_parameters = get_parameters;
1496 lexer.PropertyParsing = false;
1499 // Add local var declaration
1501 ArrayList retval = new ArrayList ();
1502 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1503 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1509 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1510 current_local_parameters = null;
1511 lexer.PropertyParsing = true;
1515 set_accessor_declaration
1516 : opt_attributes SET opt_set_parameter EOL
1518 Parameter implicit_value_parameter = new Parameter (
1519 set_implicit_value_parameter_type,
1520 set_implicit_value_parameter_name,
1521 Parameter.Modifier.NONE, null);
1523 current_local_parameters = set_parameters;
1524 current_local_parameters.AppendParameter (implicit_value_parameter);
1527 lexer.PropertyParsing = false;
1532 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1533 current_local_parameters = null;
1534 lexer.PropertyParsing = true;
1541 set_implicit_value_parameter_type = (Expression) TypeManager.system_object_expr;
1542 set_implicit_value_parameter_name = "Value";
1544 | OPEN_PARENS opt_identifier opt_type_spec CLOSE_PARENS
1546 /* FIXME: possible syntax error which must be caught
1547 Set ( As <type>) is currently (and wrongly so) legal
1549 set_implicit_value_parameter_type = (Expression) $3;
1551 set_implicit_value_parameter_name = (string) $2;
1553 set_implicit_value_parameter_name = "Value";
1559 variable_declarators EOL
1561 int mod = (int) current_modifiers;
1564 VariableDeclaration.FixupTypes ((ArrayList) $2);
1565 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1567 if (current_container is Module)
1568 mod = mod | Modifiers.STATIC;
1570 // Structure members are Public by default
1571 if ((current_container is Struct) && (mod == 0))
1572 mod = Modifiers.PUBLIC;
1574 foreach (VariableDeclaration var in (ArrayList) $2){
1575 Location l = var.Location;
1577 Field field = new Field (var.type, mod, var.identifier,
1578 var.expression_or_array_initializer,
1579 (Attributes) null, l);
1581 CheckDef (current_container.AddField (field), field.Name, l);
1586 withevents_declaration
1587 : WITHEVENTS variable_declarators EOL
1589 /* WithEvents Fields must be resolved into properties
1590 with a bit of magic behind the scenes */
1592 VariableDeclaration.FixupTypes ((ArrayList) $2);
1594 foreach (VariableDeclaration var in (ArrayList) $2) {
1595 // 1 - We create a private field
1596 Location l = var.Location;
1598 if ((current_modifiers & Modifiers.STATIC) > 0)
1599 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
1601 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
1602 var.expression_or_array_initializer,
1603 (Attributes) null, l);
1605 CheckDef (current_container.AddField (field), field.Name, l);
1607 // 2 - Public property
1609 prop = BuildSimpleProperty (var.type, (string) var.identifier,
1610 field, (int) current_modifiers,
1611 (Attributes) current_attributes, l);
1613 CheckDef (current_container.AddProperty (prop), prop.Name, l);
1623 delegate_declaration
1625 identifier OPEN_PARENS
1626 opt_formal_parameter_list
1630 Location l = lexer.Location;
1631 Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (current_container, TypeManager.system_void_expr,
1632 (int) current_modifiers,
1633 MakeName ((string) $3), (Parameters) $5,
1634 (Attributes) current_attributes, l);
1636 del.Namespace = current_namespace;
1637 CheckDef (current_container.AddDelegate (del), del.Name, l);
1640 identifier OPEN_PARENS
1641 opt_formal_parameter_list
1642 CLOSE_PARENS AS type
1644 Location l = lexer.Location;
1645 Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (
1647 (Expression) $8, (int) current_modifiers, MakeName ((string) $3),
1648 (Parameters) $5, (Attributes) current_attributes, l);
1650 del.Namespace = current_namespace;
1651 CheckDef (current_container.AddDelegate (del), del.Name, l);
1658 | HANDLES qualified_identifier
1660 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
1662 | HANDLES MYBASE DOT qualified_identifier
1664 // FIXME: this is blatantly wrong and crash-prone
1665 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
1671 | OPEN_PARENS CLOSE_PARENS
1674 static_constructor_declaration
1675 : SHARED SUB NEW opt_empty_parens EOL
1677 current_local_parameters = Parameters.EmptyReadOnlyParameters;
1679 oob_stack.Push (lexer.Location);
1681 Location l = (Location) oob_stack.Pop ();
1682 $$ = new Constructor ((string) "New", Parameters.EmptyReadOnlyParameters, (ConstructorInitializer) null, l);
1686 Constructor c = (Constructor) $1;
1687 c.Block = (Block) end_block();
1688 c.ModFlags = (int) current_modifiers;
1689 c.OptAttributes = current_attributes;
1691 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1692 current_local_parameters = null;
1696 constructor_declaration
1697 : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1699 current_local_parameters = (Parameters) $4;
1701 oob_stack.Push (lexer.Location);
1703 Location l = (Location) oob_stack.Pop ();
1704 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
1709 Constructor c = (Constructor) $1;
1710 c.Block = (Block) end_block();
1711 c.ModFlags = (int) current_modifiers;
1712 c.OptAttributes = current_attributes;
1714 // FIXME: This should happen at grammar level, but doing it
1715 // triggers a lot of conflicts/problems.
1716 c.Initializer = FixConstructorInitializer (ref c.Block.statements);
1718 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1719 current_local_parameters = null;
1724 opt_formal_parameter_list
1727 $$ = Parameters.EmptyReadOnlyParameters;
1729 | formal_parameter_list
1732 //Parameter p = ((Parameters) $1).FixedParameters[0];
1736 formal_parameter_list
1739 ArrayList pars_list = (ArrayList) $1;
1741 Parameter [] pars = new Parameter [pars_list.Count];
1742 pars_list.CopyTo (pars);
1743 $$ = new Parameters (pars, null, lexer.Location);
1745 | fixed_parameters COMMA parameter_array
1747 ArrayList pars_list = (ArrayList) $1;
1749 Parameter [] pars = new Parameter [pars_list.Count];
1750 pars_list.CopyTo (pars);
1752 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
1756 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1763 ArrayList pars = new ArrayList ();
1768 | fixed_parameters COMMA fixed_parameter
1770 ArrayList pars = (ArrayList) $1;
1779 opt_parameter_modifier
1780 identifier opt_rank_specifier opt_type_spec opt_variable_initializer
1782 Parameter.Modifier pm = (Parameter.Modifier)$2;
1783 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
1786 if (opt_parm && ($6 == null))
1787 Report.Error (999, "Optional parameters must have a default value");
1790 if ((pm & Parameter.Modifier.REF) !=0)
1791 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
1793 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
1797 ptype = (Expression) $5;
1800 string t = ((Expression) $5).ToString() + (string) $4;
1801 ptype = DecomposeQI (t, lexer.Location);
1803 $$ = new Parameter (ptype, (string) $3, pm,
1804 (Attributes) $1, (Expression) $6, opt_parm);
1809 : PARAM_ARRAY identifier opt_parens AS type
1811 $$ = new Parameter ((Expression) $5, (string) $2, Parameter.Modifier.PARAMS, null);
1812 // note ("type must be a single-dimension array type");
1818 | OPEN_PARENS CLOSE_PARENS
1821 opt_parameter_modifier
1822 : /* empty */ { $$ = Parameter.Modifier.VAL; }
1823 | parameter_modifiers { $$ = $1; }
1827 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
1828 | parameter_modifier { $$ = $1; }
1832 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
1833 | BYVAL { $$ = Parameter.Modifier.VAL; }
1834 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
1839 | statement_list EOL
1844 | statement_list EOL statement
1848 declaration_statement
1850 if ($1 != null && (Block) $1 != current_block){
1851 current_block.AddStatement ((Statement) $1);
1852 current_block = (Block) $1;
1855 | embedded_statement
1857 Statement s = (Statement) $1;
1859 current_block.AddStatement ((Statement) $1);
1862 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
1864 AddHandler ((Expression) $2, (string) $5);
1866 | RAISEEVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1868 RaiseEvent ((string) $2, (ArrayList) $4);
1875 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
1877 if (!current_block.AddLabel ((string) $1, labeled)){
1878 Location l = lexer.Location;
1879 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
1881 current_block.AddStatement (labeled);
1887 : expression_statement
1888 | selection_statement
1889 | iteration_statement
1896 | continue_statement
1899 | */return_statement
1907 $$ = new Exit ((ExitType)$2, lexer.Location);
1912 : DO { $$ = ExitType.DO; }
1913 | FOR { $$ = ExitType.FOR; }
1914 | WHILE { $$ = ExitType.WHILE; }
1915 | SELECT { $$ = ExitType.SELECT; }
1916 | SUB { $$ = ExitType.SUB; }
1917 | FUNCTION { $$ = ExitType.FUNCTION; }
1918 | PROPERTY { $$ = ExitType.PROPERTY; }
1919 | TRY { $$ = ExitType.TRY; }
1922 : RETURN opt_expression
1924 $$ = new Return ((Expression) $2, lexer.Location);
1936 : FOR EACH identifier IN
1938 oob_stack.Push (lexer.Location);
1944 Block foreach_block = current_block;
1945 Location l = lexer.Location;
1946 LocalVariableReference v = null;
1949 vi = foreach_block.GetVariableInfo ((string) $3);
1951 // Get a reference to this variable.
1952 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
1960 Block foreach_block = current_block;
1961 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
1962 Block prev_block = end_block();
1963 Location l = (Location) oob_stack.Pop ();
1967 f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
1977 if (!UseExtendedSyntax)
1983 if (iterator_container == null){
1984 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
1987 iterator_container.SetYields ();
1988 $$ = new Yield ((Expression) $2, lexer.Location);
1993 if (!UseExtendedSyntax)
1999 if (iterator_container == null){
2000 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2003 iterator_container.SetYields ();
2004 $$ = new YieldBreak (lexer.Location);
2024 tmp_catch_clauses = (ArrayList) $5;
2033 ArrayList s = new ArrayList ();
2035 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2042 // Now s contains the list of specific catch clauses
2043 // and g contains the general one.
2044 Block b = end_block();
2046 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2053 tmp_block = end_block();
2063 ArrayList s = new ArrayList ();
2064 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2066 if (catch_list != null){
2067 foreach (Catch cc in catch_list) {
2075 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2081 : /* empty */ { $$ = null; }
2088 ArrayList l = new ArrayList ();
2093 | catch_clauses catch_clause
2095 ArrayList l = (ArrayList) $1;
2103 : /* empty */ { $$ = null; }
2108 : CATCH opt_catch_args EOL
2110 Expression type = null;
2114 DictionaryEntry cc = (DictionaryEntry) $2;
2115 type = (Expression) cc.Key;
2116 id = (string) cc.Value;
2119 ArrayList one = new ArrayList ();
2120 Location loc = lexer.Location;
2122 one.Add (new VariableDeclaration (id, null, loc));
2126 current_block = new Block (current_block);
2127 Block b = declare_local_variables (type, one, loc);
2133 opt_statement_list {
2134 Expression type = null;
2136 Block b_catch = current_block;
2139 DictionaryEntry cc = (DictionaryEntry) $2;
2140 type = (Expression) cc.Key;
2141 id = (string) cc.Value;
2145 // FIXME: I can change this for an assignment.
2147 while (current_block != (Block) $1)
2148 current_block = current_block.Parent;
2152 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2157 : /* empty */ { $$ = null; }
2162 : identifier AS type
2164 $$ = new DictionaryEntry ($3, $1);
2170 : DO opt_do_construct EOL
2173 oob_stack.Push (lexer.Location);
2176 LOOP opt_do_construct
2178 Expression t_before = (Expression) $2;
2179 Expression t_after = (Expression) $7;
2182 if ((t_before != null) && (t_after != null))
2183 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2185 if ((t_before == null) && (t_after == null))
2186 t = new BoolLiteral (true);
2188 t = (t_before != null) ? t_before : t_after;
2190 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2192 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2193 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2194 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2196 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2201 : /* empty */ { $$ = null; }
2202 | while_or_until boolean_expression
2204 do_type = (DoOptions)$1;
2205 $$ = (Expression) $2;
2210 : WHILE { $$ = DoOptions.WHILE; }
2211 | UNTIL { $$ = DoOptions.UNTIL; }
2218 oob_stack.Push (lexer.Location);
2220 boolean_expression EOL
2224 Location l = (Location) oob_stack.Pop ();
2225 Block b = end_block();
2226 Expression e = (Expression) $3;
2227 $$ = new While ((Expression) e, (Statement) b, l);
2233 : FOR qualified_identifier ASSIGN expression TO expression opt_step EOL
2240 Block statement = end_block();
2241 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2243 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2244 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2245 for_var, (Expression) $6, lexer.Location);
2246 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2247 for_var, (Expression) $7, lexer.Location), lexer.Location);
2249 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2250 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2252 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2257 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2258 | STEP expression { $$ = $2; }
2263 | qualified_identifier
2272 : if_statement_open opt_then if_statement_rest
2276 | if_statement_open THEN embedded_statement
2278 Location l = (Location) oob_stack.Pop ();
2279 $$ = new If ((Expression) tmp_expr, end_block(), l);
2284 : IF boolean_expression
2286 oob_stack.Push (lexer.Location);
2288 tmp_expr = (Expression) $2;
2302 Location l = (Location) oob_stack.Pop ();
2304 $$ = new If ((Expression) tmp_expr, (Statement) end_block(), l);
2311 tmp_block = end_block();
2317 Location l = (Location) oob_stack.Pop ();
2319 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2324 : SELECT opt_case expression EOL
2326 oob_stack.Push (lexer.Location);
2327 switch_stack.Push (current_block);
2332 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2333 current_block = (Block) switch_stack.Pop ();
2338 : /* empty */ { $$ = null; }
2339 | case_sections { $$ = $1; }
2343 : case_sections case_section
2345 ArrayList sections = (ArrayList) $1;
2352 ArrayList sections = new ArrayList ();
2360 : CASE case_clauses EOL
2366 Block topmost = current_block;
2368 while (topmost.Implicit)
2369 topmost = topmost.Parent;
2371 // FIXME: This is a horrible hack which MUST go
2372 topmost.statements.Add (new Break (lexer.Location));
2373 $$ = new SwitchSection ((ArrayList) $2, topmost);
2376 /* FIXME: we should somehow flag an error
2377 (BC30321 'Case' cannot follow a 'Case Else'
2378 in the same 'Select' statement.)
2379 if Case Else is not the last of the Case clauses
2386 Block topmost = current_block;
2388 while (topmost.Implicit)
2389 topmost = topmost.Parent;
2391 // FIXME: This is a horrible hack which MUST go
2392 topmost.statements.Add (new Break (lexer.Location));
2394 ArrayList a = new ArrayList();
2395 a.Add (new SwitchLabel (null, lexer.Location));
2396 $$ = new SwitchSection ((ArrayList) a, topmost);
2403 ArrayList labels = new ArrayList ();
2408 | case_clauses COMMA case_clause
2410 ArrayList labels = (ArrayList) ($1);
2418 : opt_is comparison_operator expression
2421 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
2443 expression_statement
2444 : statement_expression
2451 statement_expression
2452 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2453 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2454 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2457 object_creation_expression
2458 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2460 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2464 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
2468 array_creation_expression
2469 : object_creation_expression array_initializer
2474 if (n.Arguments != null) {
2475 foreach (Argument a in n.Arguments) {
2476 if (a.Expr is EmptyExpression)
2479 dims += (((IntLiteral)a.Expr).AsString() + ",");
2481 dims = "[" + dims.Substring (0, dims.Length - 1) + "]";
2486 Expression atype = n.RequestedType;
2488 if (VariableDeclaration.IndexesSpecified(dims)) {
2489 ArrayList dimlist = VariableDeclaration.ParseIndexList (dims);
2490 dims = VariableDeclaration.StripIndexesFromDims (dims);
2491 //$$ = new ArrayCreation (atype, dimlist, dims, (ArrayList) $2, lexer.Location);
2492 $$ = new ArrayCreation (atype, dimlist, "", (ArrayList) $2, lexer.Location);
2496 //$$ = new ArrayCreation (atype, dims, (ArrayList) $2, lexer.Location);
2497 $$ = new ArrayCreation (atype, dims, (ArrayList) $2, lexer.Location);
2499 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
2504 : object_creation_expression
2505 | array_creation_expression
2508 declaration_statement
2509 : local_variable_declaration
2512 DictionaryEntry de = (DictionaryEntry) $1;
2514 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2518 | local_constant_declaration
2521 DictionaryEntry de = (DictionaryEntry) $1;
2523 $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
2528 local_variable_declaration
2529 : DIM variable_declarators
2531 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
2536 local_constant_declaration
2537 : CONST constant_declarator
2540 $$ = new DictionaryEntry ($1, $2);
2547 : identifier ASSIGN constant_expression
2549 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
2553 variable_declarators
2554 : variable_declarator
2556 ArrayList decl = new ArrayList ();
2560 | variable_declarators COMMA variable_declarator
2562 ArrayList decls = (ArrayList) $1;
2569 : variable_identifier opt_type_decl opt_variable_initializer
2571 string varname = (string)$1;
2573 object varinit = $3;
2576 // Some checking is required for particularly weird declarations
2578 vartype = (Expression) ((Pair) $2).First;
2579 if ($3 != null && $3 is ArrayList)
2580 Report.Error (205, "End of statement expected.");
2582 ArrayList args = (ArrayList) ((Pair) $2).Second;
2583 if (VariableDeclaration.HasExplicitIndexes (args))
2584 Report.Error (638, "Array bounds cannot appear in type specifiers.");
2588 for (int x = 0; x < args.Count; x++)
2594 vartype = (Expression) $2;
2596 Check for a declaration like Dim a(2) or Dim a(2,3)
2597 If this is the case, we must generate an ArrayCreationExpression
2598 and, in case, add the initializer after the array has been created.
2600 if (VariableDeclaration.IsArrayDecl (varname)) {
2601 if (VariableDeclaration.IndexesSpecified(varname)) {
2602 varname = VariableDeclaration.StripDims (varname, ref dims);
2603 ArrayList a_dims = VariableDeclaration.ParseIndexList(dims);
2604 varinit = new ArrayCreation (vartype, a_dims,"", (ArrayList) varinit, lexer.Location);
2607 varname = VariableDeclaration.StripDims (varname, ref dims);
2609 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.GetRank (dims), lexer.Location);
2612 if (vartype is New) {
2613 if (varinit != null) {
2614 Report.Error (30205, lexer.Location, "End of statement expected");
2620 vartype = ((New)vartype).RequestedType;
2623 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
2624 //Console.WriteLine ("varname: {0} - vartype: {1} - init: {2}", varname, vartype, varinit);
2629 : identifier opt_array_name_modifier
2633 $$ = (string)$$ + (string)$2;
2644 $$ = (Expression) $2;
2653 | AS type OPEN_PARENS opt_argument_list CLOSE_PARENS
2655 // Report.Error (30638, "Array bounds cannot appear in type specifiers");
2656 $$ = new Pair ($2, $4);;
2660 New n = new New ((Expression)$3, null, lexer.Location);
2661 $$ = (Expression) n;
2663 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2665 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
2666 $$ = (Expression) n;
2670 opt_array_name_modifier
2671 : /* empty */ { $$ = null; }
2672 | array_type_modifier { $$ = $1; }
2676 : rank_specifiers { $$ = $1; }
2679 opt_variable_initializer
2680 : /* empty */ { $$ = null; }
2681 | ASSIGN variable_initializer { $$ = $2; }
2684 variable_initializer
2697 : OPEN_BRACE CLOSE_BRACE
2699 ArrayList list = new ArrayList ();
2702 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
2704 $$ = (ArrayList) $2;
2708 variable_initializer_list
2709 : variable_initializer
2711 ArrayList list = new ArrayList ();
2715 | variable_initializer_list COMMA variable_initializer
2717 ArrayList list = (ArrayList) $1;
2724 * The following is from Rhys' grammar:
2725 * > Types in local variable declarations must be recognized as
2726 * > expressions to prevent reduce/reduce errors in the grammar.
2727 * > The expressions are converted into types during semantic analysis.
2730 : primary_expression opt_rank_specifier
2732 // FIXME: Do something smart here regarding the composition of the type.
2734 // Ok, the above "primary_expression" is there to get rid of
2735 // both reduce/reduce and shift/reduces in the grammar, it should
2736 // really just be "type_name". If you use type_name, a reduce/reduce
2737 // creeps up. If you use qualified_identifier (which is all we need
2738 // really) two shift/reduces appear.
2741 // So the super-trick is that primary_expression
2742 // can only be either a SimpleName or a MemberAccess.
2743 // The MemberAccess case arises when you have a fully qualified type-name like :
2745 // SimpleName is when you have
2748 Expression expr = (Expression) $1;
2749 if (!(expr is SimpleName || expr is MemberAccess)) {
2750 Error_ExpectingTypeName (lexer.Location, expr);
2754 // So we extract the string corresponding to the SimpleName
2757 if ((string) $2 == "")
2760 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2763 | builtin_types opt_rank_specifier
2765 if ((string) $2 == "")
2768 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2777 | rank_specifiers rank_specifier
2779 $$ = (string) $2 + (string) $1;
2784 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
2786 $$ = "[" + (string) $2 + "]";
2821 | dim_separators COMMA
2823 $$ = (string) $1 + ",";
2828 : integer_literal { $$ = ((IntLiteral)$1).AsString(); }
2829 | dim_specifiers COMMA integer_literal { $$ = $1 + "," + ((IntLiteral)$3).AsString(); }
2841 | qualified_identifier
2843 string name = (string) $1;
2845 $$ = DecomposeQI (name, lexer.Location);
2847 | parenthesized_expression
2849 | invocation_expression
2861 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
2862 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
2863 | NOTHING { $$ = NullLiteral.Null; }
2867 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
2868 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
2869 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
2874 object v = lexer.Value;
2877 $$ = new IntLiteral ((Int32) v);
2879 $$ = new UIntLiteral ((UInt32) v);
2881 $$ = new LongLiteral ((Int64) v);
2882 else if (v is ulong)
2883 $$ = new ULongLiteral ((UInt64) v);
2885 Console.WriteLine ("OOPS. Unexpected result from scanner");
2891 : TRUE { $$ = new BoolLiteral (true); }
2892 | FALSE { $$ = new BoolLiteral (false); }
2895 parenthesized_expression
2896 : OPEN_PARENS expression CLOSE_PARENS
2901 : primary_expression DOT identifier
2903 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2905 | primary_expression DOT NEW
2907 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
2909 | predefined_type DOT identifier
2911 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2919 invocation_expression
2920 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
2923 Location l = lexer.Location;
2924 Report.Error (1, l, "THIS IS CRAZY");
2926 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
2927 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
2929 | GETTYPE OPEN_PARENS expression CLOSE_PARENS
2931 Expression GetTypeExpr = DecomposeQI("System.Type.GetType", lexer.Location);
2932 ArrayList args = new ArrayList();
2933 Argument arg = new Argument ((Expression) $3, Argument.AType.Expression);
2935 $$ = new Invocation (GetTypeExpr, args, lexer.Location);
2940 : MYBASE DOT IDENTIFIER
2942 $$ = new BaseAccess ((string) $3, lexer.Location);
2946 $$ = new BaseAccess ("New", lexer.Location);
2954 The 'argument' rule returns an 'empty' argument
2955 of type NoArg (used for default arguments in invocations)
2956 if no arguments are actually passed.
2958 If there is only one argument and it is o type NoArg,
2959 we return a null (empty) list
2961 ArrayList args = (ArrayList) $1;
2962 if (args.Count == 1 &&
2963 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
2973 ArrayList list = new ArrayList ();
2977 | argument_list COMMA argument
2979 ArrayList list = (ArrayList) $1;
2988 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
2990 | BYREF variable_reference
2992 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
2996 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3001 : expression {/* note ("section 5.4"); */ $$ = $1; }
3005 : primary_expression OPEN_PARENS expression_list CLOSE_PARENS
3007 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
3009 | primary_expression rank_specifiers
3011 // So the super-trick is that primary_expression
3012 // can only be either a SimpleName or a MemberAccess.
3013 // The MemberAccess case arises when you have a fully qualified type-name like :
3015 // SimpleName is when you have
3017 Expression expr = (Expression) $1;
3019 if (!(expr is SimpleName || expr is MemberAccess)) {
3020 Error_ExpectingTypeName (lexer.Location, expr);
3021 $$ = TypeManager.system_object_expr;
3024 // So we extract the string corresponding to the SimpleName
3027 $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
3036 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3041 : conditional_expression { $$ = $1; }
3042 | negation_expression
3043 /*| assignment_expression*/
3054 ArrayList list = new ArrayList ();
3058 | expression_list COMMA expression
3060 ArrayList list = (ArrayList) $1;
3067 : /*empty */ { $$ = null; }
3074 $$ = new This (current_block, lexer.Location);
3078 // FIXME: This is actually somewhat different from Me
3079 $$ = new This (current_block, lexer.Location);
3084 : primary_expression
3085 /*| NOT prefixed_unary_expression
3087 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3089 | cast_expression */
3093 : cast_operator OPEN_PARENS expression CLOSE_PARENS
3095 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3097 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3099 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3104 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3105 | CBYTE { $$ = TypeManager.system_byte_expr; }
3106 | CCHAR { $$ = TypeManager.system_char_expr; }
3107 | CDATE { $$ = TypeManager.system_decimal_expr; } //FIXME
3108 | CDBL { $$ = TypeManager.system_double_expr; }
3109 | CDEC { $$ = TypeManager.system_decimal_expr; }
3110 | CINT { $$ = TypeManager.system_int32_expr; }
3111 | CLNG { $$ = TypeManager.system_int64_expr; }
3112 | COBJ { $$ = TypeManager.system_object_expr; }
3113 | CSHORT { $$ = TypeManager.system_int16_expr; }
3114 | CSNG { $$ = TypeManager.system_single_expr; }
3115 | CSTR { $$ = TypeManager.system_string_expr; }
3119 // The idea to split this out is from Rhys' grammar
3120 // to solve the problem with casts.
3122 prefixed_unary_expression
3124 | PLUS prefixed_unary_expression
3126 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3128 | MINUS prefixed_unary_expression
3130 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3132 | ADDRESSOF prefixed_unary_expression
3134 // FIXME: We should generate an error if AddressOf is NOT used
3135 // during delegate creation
3140 multiplicative_expression
3141 : prefixed_unary_expression
3142 | multiplicative_expression STAR prefixed_unary_expression
3144 $$ = new Binary (Binary.Operator.Multiply,
3145 (Expression) $1, (Expression) $3, lexer.Location);
3147 | multiplicative_expression DIV prefixed_unary_expression
3149 $$ = new Binary (Binary.Operator.Division,
3150 (Expression) $1, (Expression) $3, lexer.Location);
3152 | multiplicative_expression OP_MODULUS prefixed_unary_expression
3154 $$ = new Binary (Binary.Operator.Modulus,
3155 (Expression) $1, (Expression) $3, lexer.Location);
3160 : multiplicative_expression
3161 | additive_expression PLUS multiplicative_expression
3163 $$ = new Binary (Binary.Operator.Addition,
3164 (Expression) $1, (Expression) $3, lexer.Location);
3166 | additive_expression MINUS multiplicative_expression
3168 $$ = new Binary (Binary.Operator.Subtraction,
3169 (Expression) $1, (Expression) $3, lexer.Location);
3171 | additive_expression OP_CONCAT multiplicative_expression
3173 // FIXME: This should only work for String expressions
3174 // We probably need to use something from the runtime
3175 $$ = new Binary (Binary.Operator.Addition,
3176 (Expression) $1, (Expression) $3, lexer.Location);
3180 relational_expression
3181 : additive_expression
3182 | relational_expression OP_LT additive_expression
3184 $$ = new Binary (Binary.Operator.LessThan,
3185 (Expression) $1, (Expression) $3, lexer.Location);
3187 | relational_expression OP_GT additive_expression
3189 $$ = new Binary (Binary.Operator.GreaterThan,
3190 (Expression) $1, (Expression) $3, lexer.Location);
3192 | relational_expression OP_LE additive_expression
3194 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3195 (Expression) $1, (Expression) $3, lexer.Location);
3197 | relational_expression OP_GE additive_expression
3199 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3200 (Expression) $1, (Expression) $3, lexer.Location);
3202 | relational_expression IS unary_expression
3204 $$ = new Binary (Binary.Operator.Equality,
3205 (Expression) $1, (Expression) $3, lexer.Location);
3207 | relational_expression AS type_name
3209 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3214 : relational_expression
3215 | equality_expression ASSIGN relational_expression
3217 $$ = new Binary (Binary.Operator.Equality,
3218 (Expression) $1, (Expression) $3, lexer.Location);
3220 | equality_expression OP_NE relational_expression
3222 $$ = new Binary (Binary.Operator.Inequality,
3223 (Expression) $1, (Expression) $3, lexer.Location);
3228 : equality_expression
3229 | and_expression AND equality_expression
3231 $$ = new Binary (Binary.Operator.BitwiseAnd,
3232 (Expression) $1, (Expression) $3, lexer.Location);
3236 exclusive_or_expression
3238 | exclusive_or_expression OP_XOR and_expression
3240 $$ = new Binary (Binary.Operator.ExclusiveOr,
3241 (Expression) $1, (Expression) $3, lexer.Location);
3245 conditional_and_expression
3246 : exclusive_or_expression
3247 | conditional_and_expression AND exclusive_or_expression
3249 $$ = new Binary (Binary.Operator.LogicalAnd,
3250 (Expression) $1, (Expression) $3, lexer.Location);
3252 | conditional_and_expression ANDALSO exclusive_or_expression
3253 { // FIXME: this is likely to be broken
3254 $$ = new Binary (Binary.Operator.LogicalAnd,
3255 (Expression) $1, (Expression) $3, lexer.Location);
3259 conditional_or_expression
3260 : conditional_and_expression
3261 | conditional_or_expression OR conditional_and_expression
3263 $$ = new Binary (Binary.Operator.LogicalOr,
3264 (Expression) $1, (Expression) $3, lexer.Location);
3266 | conditional_or_expression ORELSE conditional_and_expression
3267 { // FIXME: this is likely to be broken
3268 $$ = new Binary (Binary.Operator.LogicalOr,
3269 (Expression) $1, (Expression) $3, lexer.Location);
3273 conditional_expression
3274 : conditional_or_expression
3277 assignment_expression
3278 : prefixed_unary_expression ASSIGN expression
3280 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3282 | prefixed_unary_expression OP_MULT_ASSIGN expression
3284 Location l = lexer.Location;
3286 $$ = new CompoundAssign (
3287 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3289 | prefixed_unary_expression OP_DIV_ASSIGN expression
3291 Location l = lexer.Location;
3293 $$ = new CompoundAssign (
3294 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3296 | prefixed_unary_expression OP_ADD_ASSIGN expression
3298 Location l = lexer.Location;
3300 $$ = new CompoundAssign (
3301 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3303 | prefixed_unary_expression OP_SUB_ASSIGN expression
3305 Location l = lexer.Location;
3307 $$ = new CompoundAssign (
3308 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3321 : type_name { /* class_type */
3323 This does interfaces, delegates, struct_types, class_types,
3324 parent classes, and more! 4.2
3326 $$ = DecomposeQI ((string) $1, lexer.Location);
3336 ArrayList types = new ArrayList ();
3341 | type_list COMMA type
3343 ArrayList types = (ArrayList) $1;
3351 : namespace_or_type_name
3354 namespace_or_type_name
3355 : qualified_identifier
3359 : type bracketed_rank_specifiers
3361 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3365 bracketed_rank_specifiers
3366 : bracketed_rank_specifier bracketed_opt_rank_specifier
3368 $$ = (string) $2 + (string) $1;
3372 bracketed_rank_specifier
3373 : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
3375 $$ = "[" + (string) $2 + "]";
3379 bracketed_opt_rank_specifier
3384 | bracketed_rank_specifiers
3390 /* Built-in / Integral types */
3392 : OBJECT { $$ = TypeManager.system_object_expr; }
3393 | STRING { $$ = TypeManager.system_string_expr; }
3394 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
3395 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
3396 | SINGLE { $$ = TypeManager.system_single_expr; }
3397 | DOUBLE { $$ = TypeManager.system_double_expr; }
3403 | BYTE { $$ = TypeManager.system_byte_expr; }
3404 | SHORT { $$ = TypeManager.system_int16_expr; }
3405 | LONG { $$ = TypeManager.system_int64_expr; }
3406 | INTEGER { $$ = TypeManager.system_int32_expr; }
3407 | CHAR { $$ = TypeManager.system_char_expr; }
3409 | SBYTE { $$ = TypeManager.system_sbyte_expr; }
3410 | UINT { $$ = TypeManager.system_uint32_expr; }
3411 | ULONG { $$ = TypeManager.system_uint64_expr; }
3412 | USHORT { $$ = TypeManager.system_uint16_expr; }
3413 | CHAR { $$ = TypeManager.system_char_expr; }
3414 | VOID { $$ = TypeManager.system_void_expr; }
3426 public Tokenizer Lexer {
3432 public static Expression DecomposeQI (string name, Location loc)
3436 if (name.IndexOf ('.') == -1){
3437 return new SimpleName (name, loc);
3439 int pos = name.LastIndexOf (".");
3440 string left = name.Substring (0, pos);
3441 string right = name.Substring (pos + 1);
3443 o = DecomposeQI (left, loc);
3445 return new MemberAccess (o, right, loc);
3449 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
3451 Block implicit_block;
3452 ArrayList inits = null;
3455 // We use the `Used' property to check whether statements
3456 // have been added to the current block. If so, we need
3457 // to create another block to contain the new declaration
3458 // otherwise, as an optimization, we use the same block to
3459 // add the declaration.
3461 // FIXME: A further optimization is to check if the statements
3462 // that were added were added as part of the initialization
3463 // below. In which case, no other statements have been executed
3464 // and we might be able to reduce the number of blocks for
3465 // situations like this:
3467 // int j = 1; int k = j + 1;
3470 VariableDeclaration.FixupTypes (variable_declarators);
3472 if (current_block.Used) {
3473 implicit_block = new Block (current_block, true, loc, Location.Null);
3474 implicit_block.AddChildVariableNames (current_block);
3476 implicit_block = current_block;
3478 foreach (VariableDeclaration decl in variable_declarators){
3479 Expression type = decl.type;
3480 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
3481 if (decl.expression_or_array_initializer != null){
3483 inits = new ArrayList ();
3490 return implicit_block;
3492 foreach (VariableDeclaration decl in inits){
3495 Expression type = decl.type;
3497 if ((decl.expression_or_array_initializer is Expression) ||
3498 (decl.expression_or_array_initializer is New)) {
3499 expr = (Expression) decl.expression_or_array_initializer;
3501 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3503 expr = new ArrayCreation (type, "", init, decl.Location);
3506 LocalVariableReference var;
3507 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
3509 assign = new Assign (var, expr, decl.Location);
3511 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
3514 return implicit_block;
3518 Block declare_local_constant (Expression type, VariableDeclaration decl)
3520 Block implicit_block;
3522 if (current_block.Used)
3523 implicit_block = new Block (current_block, true);
3525 implicit_block = current_block;
3527 if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
3528 current_local_parameters, decl.Location))){
3531 return implicit_block;
3535 // A class used to pass around variable declarations and constants
3537 public class VariableDeclaration {
3538 public string identifier;
3539 public object expression_or_array_initializer;
3540 public Location Location;
3541 public Attributes OptAttributes;
3542 public Expression type;
3543 public ArrayList dims;
3545 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
3547 this.identifier = id;
3548 this.expression_or_array_initializer = eoai;
3550 this.OptAttributes = opt_attrs;
3555 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
3559 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
3563 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
3564 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
3568 public static void FixupTypes (ArrayList vars)
3570 int varcount = vars.Count;
3571 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
3573 if (last_var.type == null)
3574 last_var.type = TypeManager.system_object_expr;
3576 Expression cur_type = last_var.type;
3577 int n = varcount - 1;
3580 VariableDeclaration var = (VariableDeclaration) vars[n--];
3581 if (var.type == null)
3582 var.type = cur_type;
3584 cur_type = var.type;
3588 public static bool IndexesSpecified (string varname)
3592 if (varname.IndexOf("[") >= 0) {
3593 char[] ds = {'1','2','3','4','5','6','7','8','9'};
3595 string dimpart = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
3596 if (dimpart.IndexOfAny (ds) >= 0)
3602 public static string StripDims (string varname, ref string d)
3604 string res = varname;
3607 if (varname.IndexOf("[") >= 0) {
3608 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
3609 res = varname.Substring(0, varname.IndexOf("["));
3615 public static string StripDims (string varname)
3619 return (StripDims(varname, ref dres));
3622 public static string StripIndexesFromDims (string dims)
3624 StringBuilder sb = new StringBuilder();
3626 foreach (char c in dims)
3627 if (c == ',' || c == ']' || c == '[')
3630 return sb.ToString();
3633 public static string GetRank (string dims)
3638 for (x = 0; x < dims.Length; x++) {
3639 if (dims[x] == '[' || dims[x] == ']' || dims[x] == ',')
3640 res = res + dims[x];
3645 public static bool HasExplicitIndexes (ArrayList a)
3650 foreach (Expression e in a)
3651 if (!(e is EmptyExpression)) {
3659 public static ArrayList ParseIndexList (string dims)
3661 ArrayList res = new ArrayList();
3662 string d = dims.Substring (1, dims.Length -2);
3663 Array a = d.Split (',');
3665 if (a.GetLength(0) > 32) {
3666 Report.Error (999, "Arrays cannot have more than 32 dimensions");
3669 foreach (string s in a)
3671 res.Add (new IntLiteral ((Int32) Convert.ToInt32(s) + 1));
3673 res.Add (new IntLiteral ((Int32) 0));
3678 public static bool IsArrayDecl (string varname)
3680 return (varname.IndexOf("[") >= 0);
3683 public static void FixupArrayTypes (ArrayList vars)
3685 int varcount = vars.Count;
3688 foreach (VariableDeclaration var in vars) {
3689 if (var.identifier.EndsWith(",")) {
3690 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
3691 var.identifier.LastIndexOf(",")) + "]";
3692 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
3693 var.type = new ComposedCast (var.type, (string) dims, var.Location);
3699 public Property BuildSimpleProperty (Expression p_type, string name,
3700 Field p_fld, int mod_flags,
3701 Attributes attrs, Location loc)
3704 Block get_block, set_block;
3705 Accessor acc_set, acc_get;
3706 StatementExpression a_set;
3711 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
3712 args = new Parameter [1];
3713 args [0] = implicit_value_parameter;
3715 Parameters set_params = new Parameters (args, null, loc);
3716 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
3717 (Expression) new SimpleName("value", loc), loc), loc);
3719 set_block = new Block (current_block, set_params, loc, Location.Null);
3720 set_block.AddStatement ((Statement) a_set);
3721 acc_set = new Accessor (set_block, attrs);
3724 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
3725 get_block = new Block (current_block, null, loc, Location.Null);
3726 get_block.AddStatement ((Statement) a_get);
3727 acc_get = new Accessor (get_block, attrs);
3729 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
3736 current_block = new Block (current_block, current_local_parameters,
3737 lexer.Location, Location.Null);
3744 while (current_block.Implicit)
3745 current_block = current_block.Parent;
3747 res = current_block;
3749 current_block.SetEndLocation (lexer.Location);
3750 current_block = current_block.Parent;
3755 private void AddHandler (Expression evt_definition, string handler_name)
3757 AddHandler (current_block, evt_definition, handler_name);
3760 void CheckAttributeTarget (string a)
3764 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
3768 Location l = lexer.Location;
3769 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
3774 private void AddHandler (Block b, Expression evt_id, string handler_name)
3776 Location loc = lexer.Location;
3777 string evt_target = evt_id.ToString();
3778 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
3779 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
3783 private void RaiseEvent (string evt_name, ArrayList args)
3785 Location loc = lexer.Location;
3787 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
3788 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
3789 current_block.AddStatement (s);
3792 // FIXME: THIS DOES NOT WORK!!!
3793 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
3795 Location loc = lexer.Location;
3796 ArrayList neh_args = new ArrayList();
3797 neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
3799 ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
3801 CompoundAssign ca = new CompoundAssign (
3802 Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
3804 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc));
3809 // This method is used to get at the complete string representation of
3810 // a fully-qualified type name, hiding inside a MemberAccess ;-)
3811 // This is necessary because local_variable_type admits primary_expression
3812 // as the type of the variable. So we do some extra checking
3814 string GetQualifiedIdentifier (Expression expr)
3816 if (expr is SimpleName)
3817 return ((SimpleName)expr).Name;
3818 else if (expr is MemberAccess)
3819 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
3821 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
3825 private void RemoveHandler (Expression evt_definition, string handler_name)
3827 RemoveHandler (current_block, evt_definition, handler_name);
3830 private ConstructorInitializer FixConstructorInitializer (ref ArrayList s)
3832 ConstructorInitializer ci = null;
3835 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
3836 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
3838 if (i.expr is BaseAccess) {
3839 BaseAccess ba = (BaseAccess) i.expr;
3840 if (ba.member == "New" || ba.member == ".ctor") {
3841 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
3845 if (i.expr.ToString() == "Mono.CSharp.This..ctor") {
3846 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
3854 void Error_ExpectingTypeName (Location l, Expression expr)
3856 if (expr is Invocation){
3857 Report.Error (1002, l, "; expected");
3859 Report.Error (-1, l, "Invalid Type definition");
3863 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
3867 private void ReportError9998()
3869 Report.Error (9998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
3872 public override int parse ()
3874 current_namespace = new Namespace (null, RootContext.RootNamespace);
3875 current_container = RootContext.Tree.Types;
3876 current_container.Namespace = current_namespace;
3877 oob_stack = new Stack ();
3878 switch_stack = new Stack ();
3880 UseExtendedSyntax = name.EndsWith(".mbs");
3881 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
3882 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
3883 OptionCompareBinary = InitialOptionCompareBinary;
3885 lexer = new Tokenizer (input, name, defines);
3886 StringBuilder value = new StringBuilder ();
3887 //yacc_verbose_flag=true;
3890 if (yacc_verbose_flag)
3891 yyparse (lexer, new yydebug.yyDebugSimple ());
3897 Console.WriteLine (lexer.location + " : Parsing error in " + lexer.ref_name);
3898 Report.Error (9999, lexer.Location, "");
3899 Console.WriteLine (e);
3902 return Report.Errors;