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 Location member_location;
115 // An out-of-band stack.
119 ArrayList current_rank_specifiers;
127 // Expression stack for nested ifs
131 Stack statement_stack;
133 // A stack for With expressions.
138 static public bool InitialOptionExplicit = false;
139 static public bool InitialOptionStrict = false;
140 static public bool InitialOptionCompareBinary = true;
141 static public ArrayList ImportsList = null;
145 bool OptionCompareBinary;
147 static public bool UseExtendedSyntax; // for ".mbs" files
149 bool implicit_modifiers;
151 public override string[] extensions()
153 string [] list = { ".vb", ".mbs" };
160 %token NONE /* This token is never returned by our lexer */
161 %token ERROR // This is used not by the parser, but by the tokenizer.
165 *These are the MonoBASIC keywords
254 %token NOTINHERITABLE
255 %token NOTOVERRIDABLE
310 %token YIELD // MonoBASIC extension
312 /* MonoBASIC single character operators/punctuation. */
314 %token OPEN_BRACKET "["
315 %token CLOSE_BRACKET "]"
316 %token OPEN_PARENS "("
317 %token OPEN_BRACE "{"
318 %token CLOSE_BRACE "}"
319 %token CLOSE_PARENS ")"
335 %token EXCLAMATION "!"
338 %token LONGTYPECHAR "&"
340 %token SINGLETYPECHAR "!"
341 %token NUMBER_SIGN "#"
342 %token DOLAR_SIGN "$"
344 %token ATTR_ASSIGN ":="
346 /* MonoBASIC multi-character operators. */
351 //%token OP_MODULUS //"mod"
352 %token OP_MULT_ASSIGN "*="
353 %token OP_DIV_ASSIGN "/="
354 %token OP_IDIV_ASSIGN "\\="
355 %token OP_ADD_ASSIGN "+="
356 %token OP_SUB_ASSIGN "-="
357 %token OP_CONCAT_ASSIGN "&="
358 %token OP_EXP_ASSIGN "^="
360 /* VB.NET 2003 new bit-shift operators */
361 %token OP_SHIFT_LEFT "<<"
362 %token OP_SHIFT_RIGHT ">>"
365 %token LITERAL_INTEGER "int literal"
366 %token LITERAL_SINGLE "float literal"
367 %token LITERAL_DOUBLE "double literal"
368 %token LITERAL_DECIMAL "decimal literal"
369 %token LITERAL_CHARACTER "character literal"
370 %token LITERAL_STRING "string literal"
371 %token LITERAL_DATE "datetime literal"
375 /* Add precedence rules to solve dangling else s/r conflict */
384 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
386 %left STAR DIV PERCENT
387 %right BITWISE_NOT CARRET UMINUS
388 %nonassoc OP_INC OP_DEC
390 %left OPEN_BRACKET OPEN_BRACE
395 %start compilation_unit
399 : opt_option_directives
400 opt_imports_directives
409 opt_option_directives
416 | option_directives option_directive
420 : option_explicit_directive
421 | option_strict_directive
422 | option_compare_directive
451 option_explicit_directive
452 : OPTION EXPLICIT on_off EOL
454 if (!UseExtendedSyntax)
455 OptionExplicit = (bool)$3;
458 9999, lexer.Location,
459 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
464 option_strict_directive
465 : OPTION STRICT on_off EOL
467 if (!UseExtendedSyntax)
468 OptionStrict = (bool)$3;
471 9999, lexer.Location,
472 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
476 option_compare_directive
477 : OPTION COMPARE text_or_binary EOL
479 OptionCompareBinary = (bool)$3;
490 | declarations declaration
494 : namespace_declaration
500 if ($1 is Class || $1 is Struct || $1 is Module ){
501 TypeContainer c = (TypeContainer) $1;
502 mod_flags = c.ModFlags;
507 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
509 1527, lexer.Location,
510 "Namespace elements cannot be explicitly " +
511 "declared private or protected in '" + name + "'");
526 : PERCENT { $$ = TypeManager.system_int32_expr; }
527 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
528 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
529 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
530 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
531 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
535 : /* empty */ { $$ = null; }
536 | type_character { $$ = $1; }
542 | qualified_identifier DOT identifier
544 $$ = (($1).ToString ()) + "." + ($3.ToString ());
548 opt_imports_directives
555 | imports_directives imports_directive
559 : IMPORTS imports_terms EOL
564 | imports_terms COMMA imports_terms
568 : qualified_identifier
570 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
572 | qualified_identifier ASSIGN qualified_identifier
574 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
580 | attribute_sections { $$ = $1; }
586 AttributeSection sect = (AttributeSection) $1;
588 if (sect.Target == "assembly")
589 RootContext.AddGlobalAttributeSection (current_container, sect);
591 $$ = new Attributes ((AttributeSection) $1, lexer.Location);
595 FIXME: we should check if extended syntax is enabled;
596 otherwise an exception should be thrown since VB.NET
597 only allows one attribute section
599 | attribute_sections attribute_section
601 Attributes attrs = null;
602 AttributeSection sect = (AttributeSection) $2;
604 if (sect.Target == "assembly")
605 RootContext.AddGlobalAttributeSection (current_container, sect);
608 attrs = (Attributes) $1;
609 attrs.AddAttributeSection (sect);
617 : OP_LT attribute_target_specifier attribute_list OP_GT
619 string target = null;
622 target = (string) $2;
624 $$ = new AttributeSection (target, (ArrayList) $3);
626 | OP_LT attribute_list OP_GT
628 $$ = new AttributeSection (null, (ArrayList) $2);
632 attribute_target_specifier
633 : attribute_target COLON
642 CheckAttributeTarget ((string) $1);
645 | EVENT { $$ = "event"; }
646 | RETURN { $$ = "return"; }
652 ArrayList attrs = new ArrayList ();
658 | attribute_list COMMA attribute
660 ArrayList attrs = (ArrayList) $1;
672 opt_attribute_arguments
674 $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
682 opt_attribute_arguments
683 : /* empty */ { $$ = null; }
684 | OPEN_PARENS attribute_arguments CLOSE_PARENS
691 : opt_positional_argument_list
696 ArrayList args = new ArrayList ();
702 | positional_argument_list COMMA named_argument_list
704 ArrayList args = new ArrayList ();
710 | named_argument_list
712 ArrayList args = new ArrayList ();
721 opt_positional_argument_list
722 : /* empty */ { $$ = null; }
723 | positional_argument_list
726 positional_argument_list
729 ArrayList args = new ArrayList ();
730 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
734 | positional_argument_list COMMA expression
736 ArrayList args = (ArrayList) $1;
737 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
746 ArrayList args = new ArrayList ();
751 | named_argument_list COMMA named_argument
753 ArrayList args = (ArrayList) $1;
761 : identifier ATTR_ASSIGN expression
763 $$ = new DictionaryEntry (
765 new Argument ((Expression) $3, Argument.AType.Expression));
769 namespace_declaration
770 : opt_attributes NAMESPACE qualified_identifier EOL
772 Attributes attrs = (Attributes) $1;
775 foreach (AttributeSection asec in attrs.AttributeSections)
776 if (asec.Target == "assembly")
777 RootContext.AddGlobalAttributeSection (current_container, asec);
780 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
782 opt_imports_directives
786 current_namespace = current_namespace.Parent;
794 current_attributes = (Attributes) $1;
795 current_modifiers = (int) $2;
797 type_spec_declaration
800 type_spec_declaration
803 | interface_declaration
804 | delegate_declaration
810 : CLASS identifier EOL opt_inherits opt_implements
815 name = MakeName ((string) $2);
816 new_class = new Class (current_container, name, current_modifiers,
817 (Attributes) current_attributes, lexer.Location);
819 current_container = new_class;
820 current_container.Namespace = current_namespace;
821 RootContext.Tree.RecordDecl (name, new_class);
823 opt_class_member_declarations
826 Class new_class = (Class) current_container;
827 new_class.Bases = (ArrayList) $4;
829 current_container = current_container.Parent;
830 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
837 : /* empty */ { $$ = null; }
838 | INHERITS type_list EOL { $$ = $2; }
842 : /* empty */ { $$ = null; }
843 | IMPLEMENTS type_list EOL { $$ = $2; }
847 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
848 | modifiers { $$ = $1; current_modifiers = (int) $1; }
858 if ((m1 & m2) != 0) {
859 Location l = lexer.Location;
860 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
862 $$ = (int) (m1 | m2);
867 : PUBLIC { $$ = Modifiers.PUBLIC; }
868 | PROTECTED { $$ = Modifiers.PROTECTED; }
869 | PRIVATE { $$ = Modifiers.PRIVATE; }
870 | SHARED { $$ = Modifiers.STATIC; }
871 | FRIEND { $$ = Modifiers.INTERNAL; }
872 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
873 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
874 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
875 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
876 | OVERLOADS { $$ = Modifiers.NEW; }
877 | SHADOWS { $$ = Modifiers.SHADOWS; }
878 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
879 | READONLY { $$ = Modifiers.READONLY; }
880 | DEFAULT { $$ = Modifiers.DEFAULT; }
881 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
885 : MODULE identifier EOL
889 name = MakeName((string) $2);
890 new_module = new Module(current_container,
892 current_modifiers, // already checks then
893 (Attributes) current_attributes,
895 current_container = new_module;
896 current_container.Namespace = current_namespace;
897 RootContext.Tree.RecordDecl(name, new_module);
899 opt_module_member_declarations
902 Module new_module = (Module)current_container;
904 current_container = current_container.Parent;
905 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
907 TypeManager.AddStandardModule(new_module);
913 opt_module_member_declarations
915 | module_member_declarations
918 module_member_declarations
919 : module_member_declaration
920 | module_member_declarations module_member_declaration
923 module_member_declaration
927 current_attributes = (Attributes) $1;
928 current_modifiers = ((int)$2) | Modifiers.STATIC;
929 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
930 implicit_modifiers = (!explicit_static);
932 module_member_declarator
934 implicit_modifiers = false;
939 module_member_declarator
940 : static_constructor_declaration
943 Method method = (Method) $1;
944 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
947 | withevents_declaration /* This is a field but must be treated specially, see below */
948 | constant_declaration
949 | property_declaration
951 | type_spec_declaration
955 : CONST constant_declarators EOL
957 // Module members are static by default, but constants *can't* be declared static
958 // so we must fix it, if mbas was the one actually responsible for this
959 // instead of triggering an error.
960 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
961 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
963 int mod = (int) current_modifiers;
965 // Structure members are Public by default
966 if ((current_container is Struct) && (mod == 0))
967 mod = Modifiers.PUBLIC;
969 ArrayList consts = (ArrayList) $2;
972 VariableDeclaration.FixupTypes ((ArrayList) $2);
973 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
975 foreach (VariableDeclaration var in (ArrayList) $2){
976 Location l = var.Location;
977 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
978 (Expression)var.expression_or_array_initializer,
979 mod, (Attributes) null, l);
981 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
987 opt_class_member_declarations
989 | class_member_declarations
992 class_member_declarations
993 : class_member_declaration
994 | class_member_declarations class_member_declaration
997 class_member_declaration
1001 current_attributes = (Attributes) $1;
1002 current_modifiers = (int) $2;
1004 class_member_declarator
1010 class_member_declarator
1011 : constructor_declaration
1012 | method_declaration
1014 Method method = (Method) $1;
1015 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1018 | constant_declaration
1019 | property_declaration
1021 | withevents_declaration /* This is a field but must be treated specially, see below */
1022 /*| type_declaration */
1031 | must_override_declaration
1034 must_override_declaration
1035 : must_override_sub_declaration
1036 | must_override_func_declaration
1039 must_override_sub_declaration
1040 : MUSTOVERRIDE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1042 if (current_container is Module)
1043 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1045 if (current_container is Struct)
1046 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1048 current_modifiers |= Modifiers.ABSTRACT;
1050 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1051 (Parameters) $5, null, null, lexer.Location);
1053 if (!(current_container is Class))
1054 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1056 // FIXME ASAP: This will crash the compiler at resolution time
1062 must_override_func_declaration
1063 : MUSTOVERRIDE FUNCTION identifier opt_type_character OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks EOL
1065 Expression ftype = ($8 == null) ? (($4 == null) ? TypeManager.
1066 system_object_expr : (Expression) $4 ) : (Expression) $8;
1068 if (current_container is Module)
1069 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1071 if (current_container is Struct)
1072 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1074 current_modifiers |= Modifiers.ABSTRACT;
1076 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1077 (string) $3,(Parameters) $6, null, null,
1080 if (!(current_container is Class))
1081 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1088 : SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler opt_implement_clause EOL
1090 current_local_parameters = (Parameters) $4;
1093 // Structure members are Public by default
1094 if ((current_container is Struct) && (current_modifiers == 0))
1095 current_modifiers = Modifiers.PUBLIC;
1097 member_location = lexer.Location;
1102 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1103 (Parameters) current_local_parameters, null, (Expression) $7,
1106 method.Block = (Block) end_block();
1109 if ($6 != null) { /* we have an event handler to take care of */
1110 // This wouldn't work: AddHandler ((Expression)$6, (string) $2);
1111 string evt_def = ((MemberAccess)$6).ToString();
1112 int pos = evt_def.LastIndexOf (".");
1113 string evt_target = ((string) $2).Substring (0, pos);
1115 foreach (Property p in current_container.Properties) {
1116 if (p.Name == evt_target) {
1118 // RemoveHandler (p.Set.Block, (Expression)$6, (string) $2);
1119 AddHandler (p.Set.Block, (Expression)$6, (string) $2);
1128 : FUNCTION identifier opt_type_character
1129 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks opt_implement_clause EOL
1131 current_local_parameters = (Parameters) $5;
1132 member_location = lexer.Location;
1135 Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
1137 // Structure members are Public by default
1138 if ((current_container is Struct) && (current_modifiers == 0))
1139 current_modifiers = Modifiers.PUBLIC;
1140 // Add local var declaration
1142 ArrayList retval = new ArrayList ();
1143 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1144 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1149 Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
1151 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1152 (Parameters) current_local_parameters, null,
1153 (Expression) $8, member_location);
1154 method.Block = end_block();
1160 : STRUCTURE identifier EOL
1161 opt_implement_clause
1164 string full_struct_name = MakeName ((string) $2);
1166 // Module members are static by default, but structures *can't* be declared static
1167 // so we must fix it, if mbas was the one actually responsible for this
1168 // instead of triggering an error.
1169 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1170 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1172 new_struct = new Struct (current_container, full_struct_name,
1173 (int) current_modifiers,
1174 (Attributes) current_attributes, lexer.Location);
1175 current_container = new_struct;
1176 current_container.Namespace = current_namespace;
1177 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1179 opt_struct_member_declarations
1181 Struct new_struct = (Struct) current_container;
1184 new_struct.Bases = (ArrayList) $4;
1186 current_container = current_container.Parent;
1187 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1193 opt_struct_member_declarations
1195 | struct_member_declarations
1198 struct_member_declarations
1199 : struct_member_declaration
1200 | struct_member_declarations struct_member_declaration
1203 struct_member_declaration
1205 struct_member_declarator
1207 struct_member_declarator
1209 //| constant_declaration
1210 | method_declaration
1211 | property_declaration
1213 | constructor_declaration
1217 * This is only included so we can flag error 575:
1218 * destructors only allowed on class types
1220 //| destructor_declaration
1224 : EVENT identifier AS type EOL
1226 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1228 Event e = new Event ((Expression) $4, var.identifier,
1229 null, current_modifiers, null, null,
1230 current_attributes, lexer.Location);
1232 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1235 // | EVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1237 // throw new NotSupportedException();
1242 : ENUM identifier opt_type_spec EOL
1243 opt_enum_member_declarations
1245 Location enum_location = lexer.Location;
1246 string full_name = MakeName ((string) $2);
1247 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1248 ArrayList enum_members = (ArrayList) $5;
1250 // Module members are static by default, but enums *can't* be declared static
1251 // so we must fix it if mbas was the one actually responsible for this
1252 // instead of triggering an error.
1253 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1254 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1256 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1257 (int) current_modifiers, full_name,
1258 (Attributes) current_attributes, enum_location);
1260 foreach (VariableDeclaration ev in enum_members) {
1261 Location loc = (Location) ev.Location;
1263 CheckDef (e.AddEnumMember (ev.identifier,
1264 (Expression) ev.expression_or_array_initializer,
1265 loc, ev.OptAttributes), ev.identifier, loc);
1268 e.Namespace = current_namespace;
1270 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1271 RootContext.Tree.RecordDecl (full_name, e);
1277 opt_enum_member_declarations
1278 : /* empty */ { $$ = new ArrayList (); }
1279 | enum_member_declarations { $$ = $1; }
1282 enum_member_declarations
1283 : enum_member_declaration
1285 ArrayList l = new ArrayList ();
1290 | enum_member_declarations enum_member_declaration
1292 ArrayList l = (ArrayList) $1;
1300 enum_member_declaration
1301 : opt_attributes identifier EOL
1303 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1305 | opt_attributes identifier
1307 $$ = lexer.Location;
1309 ASSIGN expression EOL
1311 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1315 interface_declaration
1316 : INTERFACE identifier EOL
1318 Interface new_interface;
1319 string full_interface_name = MakeName ((string) $2);
1321 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1322 (Attributes) current_attributes, lexer.Location);
1323 if (current_interface != null) {
1324 Location l = lexer.Location;
1325 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1327 current_interface = new_interface;
1328 new_interface.Namespace = current_namespace;
1329 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1334 Interface new_interface = (Interface) current_interface;
1337 new_interface.Bases = (ArrayList) $5;
1339 current_interface = null;
1340 CheckDef (current_container.AddInterface (new_interface),
1341 new_interface.Name, new_interface.Location);
1348 : /* empty */ { $$ = null; }
1353 : INHERITS interface_type_list { $$ = $2; }
1359 ArrayList interfaces = new ArrayList ();
1361 interfaces.Add ($1);
1364 | interface_type_list COMMA interface_type
1366 ArrayList interfaces = (ArrayList) $1;
1367 interfaces.Add ($3);
1373 : opt_interface_member_declarations
1376 opt_interface_member_declarations
1378 | interface_member_declarations
1381 interface_member_declarations
1382 : interface_member_declaration
1383 | interface_member_declarations interface_member_declaration
1386 interface_member_declaration
1387 : interface_method_declaration
1389 InterfaceMethod m = (InterfaceMethod) $1;
1391 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1393 | interface_property_declaration
1395 InterfaceProperty p = (InterfaceProperty) $1;
1397 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1399 | interface_event_declaration
1401 InterfaceEvent e = (InterfaceEvent) $1;
1403 CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1408 : /* empty */ { $$ = false; }
1409 | NEW { $$ = true; }
1412 interface_method_declaration
1414 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1416 $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
1417 (Parameters) $4, current_attributes, lexer.Location);
1419 | FUNCTION identifier opt_type_character
1420 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
1422 if ($3 != null && $3 != $8)
1423 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
1425 $$ = new InterfaceMethod (
1426 (Expression) $8, (string) $2, false, (Parameters) $5,
1427 current_attributes, lexer.Location);
1429 | FUNCTION identifier type_character
1430 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1432 $$ = new InterfaceMethod (
1433 (Expression) $3, (string) $2, false, (Parameters) $5,
1434 current_attributes, lexer.Location);
1438 interface_property_declaration
1439 : opt_modifiers PROPERTY identifier
1441 opt_formal_parameter_list
1442 CLOSE_PARENS opt_type_spec EOL
1444 // FIXME we MUST pass property parameters
1445 $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
1446 true, true, current_attributes,
1451 interface_event_declaration
1452 : opt_attributes opt_new EVENT type identifier EOL
1454 $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
1459 property_declaration
1460 : opt_modifiers PROPERTY identifier opt_property_parameters AS type opt_implement_clause EOL
1462 get_implicit_value_parameter_type = (Expression) $6;
1463 get_implicit_value_parameter_name = (string) $3;
1465 current_modifiers = (int) $1;
1467 current_local_parameters = (Parameters) $4;
1468 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1469 get_parameters = current_local_parameters.Copy (lexer.Location);
1470 set_parameters = current_local_parameters.Copy (lexer.Location);
1474 get_parameters = Parameters.EmptyReadOnlyParameters;
1475 set_parameters = new Parameters (null, null ,lexer.Location);
1477 lexer.PropertyParsing = true;
1479 $$ = lexer.Location;
1481 accessor_declarations
1484 lexer.PropertyParsing = false;
1487 Pair pair = (Pair) $10;
1488 Accessor get_block = (Accessor) pair.First;
1489 Accessor set_block = (Accessor) pair.Second;
1491 Location loc = lexer.Location;
1493 // Structure members are Public by default
1494 if ((current_container is Struct) && (current_modifiers == 0))
1495 current_modifiers = Modifiers.PUBLIC;
1497 prop = new Property ((Expression) $6, (string) $3, current_modifiers, get_block, set_block,
1498 current_attributes, loc, set_implicit_value_parameter_name,
1499 get_parameters, set_parameters, (Expression) $7);
1501 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1502 get_implicit_value_parameter_type = null;
1503 set_implicit_value_parameter_type = null;
1504 get_parameters = null;
1505 set_parameters = null;
1506 current_local_parameters = null;
1510 opt_property_parameters
1513 $$ = Parameters.EmptyReadOnlyParameters;
1515 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1521 opt_implement_clause
1526 | IMPLEMENTS qualified_identifier
1528 $$ = DecomposeQI ((string)$2, lexer.Location);
1532 accessor_declarations
1533 : get_accessor_declaration opt_set_accessor_declaration
1535 $$ = new Pair ($1, $2);
1537 | set_accessor_declaration opt_get_accessor_declaration
1539 $$ = new Pair ($2, $1);
1543 opt_get_accessor_declaration
1544 : /* empty */ { $$ = null; }
1545 | get_accessor_declaration
1548 opt_set_accessor_declaration
1549 : /* empty */ { $$ = null; }
1550 | set_accessor_declaration
1553 get_accessor_declaration
1554 : opt_attributes GET EOL
1556 current_local_parameters = get_parameters;
1558 lexer.PropertyParsing = false;
1561 // Add local var declaration
1563 ArrayList retval = new ArrayList ();
1564 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1565 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1571 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1572 current_local_parameters = null;
1573 lexer.PropertyParsing = true;
1577 set_accessor_declaration
1578 : opt_attributes SET opt_set_parameter EOL
1580 Parameter implicit_value_parameter = new Parameter (
1581 set_implicit_value_parameter_type,
1582 set_implicit_value_parameter_name,
1583 Parameter.Modifier.NONE, null);
1585 current_local_parameters = set_parameters;
1586 current_local_parameters.AppendParameter (implicit_value_parameter);
1589 lexer.PropertyParsing = false;
1594 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1595 current_local_parameters = null;
1596 lexer.PropertyParsing = true;
1603 set_implicit_value_parameter_type = (Expression) TypeManager.system_object_expr;
1604 set_implicit_value_parameter_name = "Value";
1606 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_spec CLOSE_PARENS
1608 /* FIXME: possible syntax error which must be caught
1609 Set ( As <type>) is currently (and wrongly so) legal
1611 Parameter.Modifier pm = (Parameter.Modifier)$2;
1612 if ((pm | Parameter.Modifier.VAL) != 0)
1613 Report.Error (31065,
1615 "Set cannot have a paremeter modifier other than 'ByVal'");
1617 set_implicit_value_parameter_type = (Expression) $4;
1619 set_implicit_value_parameter_name = (string) $3;
1621 set_implicit_value_parameter_name = "Value";
1627 variable_declarators EOL
1629 int mod = (int) current_modifiers;
1632 VariableDeclaration.FixupTypes ((ArrayList) $2);
1633 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1635 if (current_container is Module)
1636 mod = mod | Modifiers.STATIC;
1638 // Structure members are Public by default
1639 if ((current_container is Struct) && (mod == 0))
1640 mod = Modifiers.PUBLIC;
1642 foreach (VariableDeclaration var in (ArrayList) $2){
1643 Location l = var.Location;
1644 Field field = new Field (var.type, mod, var.identifier,
1645 var.expression_or_array_initializer,
1646 (Attributes) null, l);
1648 CheckDef (current_container.AddField (field), field.Name, l);
1653 withevents_declaration
1654 : WITHEVENTS variable_declarators EOL
1656 /* WithEvents Fields must be resolved into properties
1657 with a bit of magic behind the scenes */
1659 VariableDeclaration.FixupTypes ((ArrayList) $2);
1661 foreach (VariableDeclaration var in (ArrayList) $2) {
1662 // 1 - We create a private field
1663 Location l = var.Location;
1665 if ((current_modifiers & Modifiers.STATIC) > 0)
1666 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
1668 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
1669 var.expression_or_array_initializer,
1670 (Attributes) null, l);
1672 CheckDef (current_container.AddField (field), field.Name, l);
1674 // 2 - Public property
1676 prop = BuildSimpleProperty (var.type, (string) var.identifier,
1677 field, (int) current_modifiers,
1678 (Attributes) current_attributes, l);
1680 CheckDef (current_container.AddProperty (prop), prop.Name, l);
1690 delegate_declaration
1692 identifier OPEN_PARENS
1693 opt_formal_parameter_list
1697 Location l = lexer.Location;
1698 // Module members are static by default, but delegates *can't* be declared static
1699 // so we must fix it, if mbas was the one actually responsible for this
1700 // instead of triggering an error.
1701 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1702 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1704 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container, TypeManager.system_void_expr,
1705 (int) current_modifiers,
1706 MakeName ((string) $3), (Parameters) $5,
1707 (Attributes) current_attributes, l);
1709 del.Namespace = current_namespace;
1710 CheckDef (current_container.AddDelegate (del), del.Name, l);
1713 identifier OPEN_PARENS
1714 opt_formal_parameter_list
1715 CLOSE_PARENS AS type
1717 Location l = lexer.Location;
1718 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
1720 (Expression) $8, (int) current_modifiers, MakeName ((string) $3),
1721 (Parameters) $5, (Attributes) current_attributes, l);
1723 del.Namespace = current_namespace;
1724 CheckDef (current_container.AddDelegate (del), del.Name, l);
1731 | HANDLES qualified_identifier
1733 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
1735 | HANDLES MYBASE DOT qualified_identifier
1737 // FIXME: this is blatantly wrong and crash-prone
1738 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
1744 | OPEN_PARENS CLOSE_PARENS
1747 static_constructor_declaration
1748 : SHARED SUB NEW opt_empty_parens EOL
1750 current_local_parameters = Parameters.EmptyReadOnlyParameters;
1752 oob_stack.Push (lexer.Location);
1754 Location l = (Location) oob_stack.Pop ();
1755 $$ = new Constructor ((string) "New", Parameters.EmptyReadOnlyParameters, (ConstructorInitializer) null, l);
1759 Constructor c = (Constructor) $1;
1760 c.Block = (Block) end_block();
1761 c.ModFlags = (int) current_modifiers;
1762 c.OptAttributes = current_attributes;
1764 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1765 current_local_parameters = null;
1769 constructor_declaration
1770 : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1772 current_local_parameters = (Parameters) $4;
1774 oob_stack.Push (lexer.Location);
1776 Location l = (Location) oob_stack.Pop ();
1777 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
1782 Constructor c = (Constructor) $1;
1783 c.Block = (Block) end_block();
1784 c.ModFlags = (int) current_modifiers;
1785 c.OptAttributes = current_attributes;
1787 // FIXME: This should happen at grammar level, but doing it
1788 // triggers a lot of conflicts/problems.
1789 c.Initializer = FixConstructorInitializer (ref c.Block.statements);
1791 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1792 current_local_parameters = null;
1797 opt_formal_parameter_list
1800 $$ = Parameters.EmptyReadOnlyParameters;
1802 | formal_parameter_list
1805 //Parameter p = ((Parameters) $1).FixedParameters[0];
1809 formal_parameter_list
1812 ArrayList pars_list = (ArrayList) $1;
1814 Parameter [] pars = new Parameter [pars_list.Count];
1815 pars_list.CopyTo (pars);
1816 $$ = new Parameters (pars, null, lexer.Location);
1818 | fixed_parameters COMMA parameter_array
1820 ArrayList pars_list = (ArrayList) $1;
1822 Parameter [] pars = new Parameter [pars_list.Count];
1823 pars_list.CopyTo (pars);
1825 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
1829 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1836 ArrayList pars = new ArrayList ();
1841 | fixed_parameters COMMA fixed_parameter
1843 ArrayList pars = (ArrayList) $1;
1852 opt_parameter_modifier
1853 identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
1855 Parameter.Modifier pm = (Parameter.Modifier)$2;
1856 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
1859 if (opt_parm && ($7 == null))
1860 Report.Error (999, "Optional parameters must have a default value");
1863 if ((pm & Parameter.Modifier.REF) !=0)
1864 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
1866 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
1869 if ($4 != null && $6 != null && $4 != $6)
1870 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
1872 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
1874 string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
1875 ptype = DecomposeQI (t, lexer.Location);
1877 $$ = new Parameter (ptype, (string) $3, pm,
1878 (Attributes) $1, (Expression) $7, opt_parm);
1883 : PARAM_ARRAY identifier opt_parens AS type
1885 string s_patype = ((Expression) $5).ToString();
1889 Expression patype = DecomposeQI (s_patype, Location.Null);
1890 $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
1891 // note ("type must be a single-dimension array type");
1898 | OPEN_PARENS CLOSE_PARENS
1902 opt_parameter_modifier
1903 : /* empty */ { $$ = Parameter.Modifier.VAL; }
1904 | parameter_modifiers { $$ = $1; }
1908 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
1909 | parameter_modifier { $$ = $1; }
1913 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
1914 | BYVAL { $$ = Parameter.Modifier.VAL; }
1915 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
1920 | statement_list end_of_stmt
1925 | statement_list end_of_stmt statement
1929 declaration_statement
1931 if ($1 != null && (Block) $1 != current_block){
1932 current_block.AddStatement ((Statement) $1);
1933 current_block = (Block) $1;
1936 | embedded_statement
1938 Statement s = (Statement) $1;
1940 current_block.AddStatement ((Statement) $1);
1943 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
1945 AddHandler ((Expression) $2, (string) $5);
1947 | RAISEEVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1949 RaiseEvent ((string) $2, (ArrayList) $4);
1951 /* | array_handling_statement */
1952 /* | empty_statement */
1955 Statement s = (Statement) $1;
1957 current_block.AddStatement ((Statement) $1);
1962 : identifier COLON end_of_stmt
1964 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
1966 if (!current_block.AddLabel ((string) $1, labeled)){
1967 Location l = lexer.Location;
1968 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
1970 current_block.AddStatement (labeled);
1976 : expression_statement
1977 | selection_statement
1978 | iteration_statement
1981 | array_handling_statement
1987 $$ = new EmptyStatement ();
1993 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
1995 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
1996 Expression e = (Expression) $2;
2003 Block b = end_block();
2010 array_handling_statement
2016 : REDIM opt_preserve redim_clauses
2018 ArrayList list = (ArrayList) $3;
2019 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2026 : /* empty */ { $$ = false; }
2027 | PRESERVE { $$ = true; }
2033 ArrayList clauses = new ArrayList ();
2038 | redim_clauses COMMA redim_clause
2040 ArrayList clauses = (ArrayList) ($1);
2048 : invocation_expression
2050 Invocation i = (Invocation) $1;
2051 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2057 : ERASE erase_clauses
2059 ArrayList list = (ArrayList) $2;
2060 foreach(Expression e in list)
2062 Erase r = new Erase (e, lexer.Location);
2071 ArrayList clauses = new ArrayList ();
2076 | erase_clauses COMMA erase_clause
2078 ArrayList clauses = (ArrayList) ($1);
2086 : primary_expression
2091 | continue_statement
2092 | */return_statement
2102 $$ = new Goto (current_block, (string) $2, lexer.Location);
2107 : THROW opt_expression
2109 $$ = new Throw ((Expression) $2, lexer.Location);
2116 $$ = new Exit ((ExitType)$2, lexer.Location);
2121 : DO { $$ = ExitType.DO; }
2122 | FOR { $$ = ExitType.FOR; }
2123 | WHILE { $$ = ExitType.WHILE; }
2124 | SELECT { $$ = ExitType.SELECT; }
2125 | SUB { $$ = ExitType.SUB; }
2126 | FUNCTION { $$ = ExitType.FUNCTION; }
2127 | PROPERTY { $$ = ExitType.PROPERTY; }
2128 | TRY { $$ = ExitType.TRY; }
2131 : RETURN opt_expression
2133 $$ = new Return ((Expression) $2, lexer.Location);
2145 : FOR EACH identifier IN
2147 oob_stack.Push (lexer.Location);
2149 expression end_of_stmt
2153 Block foreach_block = current_block;
2154 Location l = lexer.Location;
2155 LocalVariableReference v = null;
2158 vi = foreach_block.GetVariableInfo ((string) $3);
2160 // Get a reference to this variable.
2161 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2164 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2171 Block foreach_block = current_block;
2172 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2173 Block prev_block = end_block();
2174 Location l = (Location) oob_stack.Pop ();
2178 f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
2188 if (!UseExtendedSyntax)
2194 if (iterator_container == null){
2195 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2198 iterator_container.SetYields ();
2199 $$ = new Yield ((Expression) $2, lexer.Location);
2204 if (!UseExtendedSyntax)
2210 if (iterator_container == null){
2211 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2214 iterator_container.SetYields ();
2215 $$ = new YieldBreak (lexer.Location);
2235 tmp_catch_clauses = (ArrayList) $5;
2244 ArrayList s = new ArrayList ();
2246 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2253 // Now s contains the list of specific catch clauses
2254 // and g contains the general one.
2255 Block b = end_block();
2257 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2264 tmp_block = end_block();
2274 ArrayList s = new ArrayList ();
2275 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2277 if (catch_list != null){
2278 foreach (Catch cc in catch_list) {
2286 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2292 : /* empty */ { $$ = null; }
2299 ArrayList l = new ArrayList ();
2304 | catch_clauses catch_clause
2306 ArrayList l = (ArrayList) $1;
2314 : /* empty */ { $$ = null; }
2319 : CATCH opt_catch_args end_of_stmt
2321 Expression type = null;
2325 DictionaryEntry cc = (DictionaryEntry) $2;
2326 type = (Expression) cc.Key;
2327 id = (string) cc.Value;
2330 ArrayList one = new ArrayList ();
2331 Location loc = lexer.Location;
2333 one.Add (new VariableDeclaration (id, type, loc));
2337 current_block = new Block (current_block);
2338 Block b = declare_local_variables (type, one, loc);
2344 opt_statement_list {
2345 Expression type = null;
2347 Block b_catch = current_block;
2350 DictionaryEntry cc = (DictionaryEntry) $2;
2351 type = (Expression) cc.Key;
2352 id = (string) cc.Value;
2356 // FIXME: I can change this for an assignment.
2358 while (current_block != (Block) $1)
2359 current_block = current_block.Parent;
2363 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2368 : /* empty */ { $$ = null; }
2373 : identifier AS type
2375 $$ = new DictionaryEntry ($3, $1);
2381 : DO opt_do_construct end_of_stmt
2384 oob_stack.Push (lexer.Location);
2387 LOOP opt_do_construct
2389 Expression t_before = (Expression) $2;
2390 Expression t_after = (Expression) $7;
2393 if ((t_before != null) && (t_after != null))
2394 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2396 if ((t_before == null) && (t_after == null))
2397 t = new BoolLiteral (true);
2399 t = (t_before != null) ? t_before : t_after;
2401 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2403 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2404 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2405 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2407 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2412 : /* empty */ { $$ = null; }
2413 | while_or_until boolean_expression
2415 do_type = (DoOptions)$1;
2416 $$ = (Expression) $2;
2421 : WHILE { $$ = DoOptions.WHILE; }
2422 | UNTIL { $$ = DoOptions.UNTIL; }
2429 oob_stack.Push (lexer.Location);
2431 boolean_expression end_of_stmt
2435 Location l = (Location) oob_stack.Pop ();
2436 Block b = end_block();
2437 Expression e = (Expression) $3;
2438 $$ = new While ((Expression) e, (Statement) b, l);
2444 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2451 Block statement = end_block();
2452 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2454 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2455 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2456 for_var, (Expression) $6, lexer.Location);
2457 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2458 for_var, (Expression) $7, lexer.Location), lexer.Location);
2460 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2461 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2463 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2468 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2469 | STEP expression { $$ = $2; }
2478 : if_statement_open opt_then if_statement_rest
2482 | if_statement_open THEN pre_embedded_statement
2484 Location l = (Location) oob_stack.Pop ();
2485 tmp_expr = (Expression)expr_stack.Pop();
2486 $$ = new If ((Expression) tmp_expr, end_block(), l);
2490 pre_embedded_statement
2491 : embedded_statement
2493 Statement s = (Statement) $1;
2495 current_block.AddStatement ((Statement) $1);
2500 : IF boolean_expression
2502 oob_stack.Push (lexer.Location);
2504 tmp_expr = (Expression) $2;
2505 expr_stack.Push(tmp_expr);
2519 Location l = (Location) oob_stack.Pop ();
2520 Expression expr = (Expression)expr_stack.Pop();
2521 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2527 Block bl = end_block();
2528 tmp_blocks.Push(bl);
2534 Location l = (Location) oob_stack.Pop ();
2535 tmp_expr = (Expression)expr_stack.Pop();
2536 tmp_block = (Block) tmp_blocks.Pop();
2537 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2541 ELSEIF boolean_expression opt_then
2543 tmp_expr = (Expression) $4;
2544 expr_stack.Push(tmp_expr);
2545 tmp_block = end_block();
2546 tmp_blocks.Push(tmp_block);
2549 else_if_statement_rest
2551 Statement stmt = (Statement) statement_stack.Pop();
2552 Block bl = (Block) tmp_blocks.Pop();
2553 Expression expr = (Expression)expr_stack.Pop();
2554 Location l = (Location) oob_stack.Pop ();
2555 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
2560 else_if_statement_rest
2565 Location l = (Location) oob_stack.Pop ();
2567 Expression expr = (Expression)expr_stack.Pop();
2568 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
2569 statement_stack.Push(stmt);
2575 Block bl = end_block();
2576 tmp_blocks.Push(bl);
2582 Location l = (Location) oob_stack.Pop ();
2584 Expression expr = (Expression)expr_stack.Pop();
2585 Block bl = (Block)tmp_blocks.Pop();
2586 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
2587 statement_stack.Push(stmt);
2591 ELSEIF boolean_expression opt_then
2593 expr_stack.Push((Expression) $4);
2594 Block bl = end_block();
2595 tmp_blocks.Push(bl);
2598 else_if_statement_rest
2600 Location l = (Location) oob_stack.Pop ();
2602 Statement tmp_stmt = (Statement)statement_stack.Pop();
2603 Block bl = (Block) tmp_blocks.Pop();
2604 Expression expr = (Expression)expr_stack.Pop();
2605 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
2606 statement_stack.Push(stmt);
2611 : SELECT opt_case expression end_of_stmt
2613 oob_stack.Push (lexer.Location);
2614 switch_stack.Push (current_block);
2619 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2620 current_block = (Block) switch_stack.Pop ();
2625 : /* empty */ { $$ = null; }
2626 | case_sections { $$ = $1; }
2630 : case_sections case_section
2632 ArrayList sections = (ArrayList) $1;
2639 ArrayList sections = new ArrayList ();
2653 : CASE case_clauses ends
2659 //Block topmost = current_block;
2660 Block topmost = end_block();
2662 while (topmost.Implicit)
2663 topmost = topmost.Parent;
2665 // FIXME: This is a horrible hack which MUST go
2666 topmost.statements.Add (new Break (lexer.Location));
2667 $$ = new SwitchSection ((ArrayList) $2, topmost);
2670 /* FIXME: we should somehow flag an error
2671 (BC30321 'Case' cannot follow a 'Case Else'
2672 in the same 'Select' statement.)
2673 if Case Else is not the last of the Case clauses
2680 //Block topmost = current_block;
2681 Block topmost = end_block();
2683 while (topmost.Implicit)
2684 topmost = topmost.Parent;
2686 // FIXME: This is a horrible hack which MUST go
2687 topmost.statements.Add (new Break (lexer.Location));
2689 ArrayList a = new ArrayList();
2690 a.Add (new SwitchLabel (null, lexer.Location));
2691 $$ = new SwitchSection ((ArrayList) a, topmost);
2698 ArrayList labels = new ArrayList ();
2703 | case_clauses COMMA case_clause
2705 ArrayList labels = (ArrayList) ($1);
2713 : opt_is comparison_operator expression
2716 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
2738 expression_statement
2739 : statement_expression
2746 statement_expression
2747 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2748 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2749 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2752 object_creation_expression
2753 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2755 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2759 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
2763 array_creation_expression
2764 : object_creation_expression array_initializer
2767 ArrayList dims = new ArrayList();
2769 if (n.Arguments != null) {
2770 foreach (Argument a in n.Arguments) {
2775 Expression atype = n.RequestedType;
2777 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
2778 VariableDeclaration.VBFixIndexList (ref dims);
2779 $$ = new ArrayCreation (atype, dims, "", (ArrayList) $2, lexer.Location);
2783 string rank = VariableDeclaration.BuildRank (dims);
2784 $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
2786 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
2791 : object_creation_expression
2792 | array_creation_expression
2795 declaration_statement
2796 : local_variable_declaration
2799 DictionaryEntry de = (DictionaryEntry) $1;
2801 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2805 | local_constant_declaration
2808 DictionaryEntry de = (DictionaryEntry) $1;
2810 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
2815 local_variable_declaration
2816 : DIM variable_declarators
2818 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
2823 local_constant_declaration
2824 : CONST constant_declarators
2827 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
2833 constant_declarators
2834 : constant_declarator
2836 ArrayList decl = new ArrayList ();
2842 | constant_declarators COMMA constant_declarator
2844 ArrayList decls = (ArrayList) $1;
2853 : variable_name opt_type_decl opt_variable_initializer
2855 VarName vname = (VarName) $1;
2856 string varname = (string) vname.Name;
2857 current_rank_specifiers = (ArrayList) vname.Rank;
2858 object varinit = $3;
2859 ArrayList a_dims = null;
2861 if (varinit == null)
2863 30438, lexer.Location, "Constant should have a value"
2866 if (vname.Type != null && $2 != null)
2868 30302, lexer.Location,
2869 "Type character cannot be used with explicit type declaration" );
2871 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
2873 if (current_rank_specifiers != null)
2875 Report.Error (30424, lexer.Location, "Constant doesn't support array");
2879 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
2883 variable_declarators
2884 : variable_declarator
2886 ArrayList decl = new ArrayList ();
2887 decl.AddRange ((ArrayList) $1);
2890 | variable_declarators COMMA variable_declarator
2892 ArrayList decls = (ArrayList) $1;
2893 decls.AddRange ((ArrayList) $3);
2899 : variable_names opt_type_decl opt_variable_initializer
2901 ArrayList names = (ArrayList) $1;
2902 object varinit = $3;
2903 ArrayList VarDeclarations = new ArrayList();
2905 ArrayList a_dims = null;
2907 if ((names.Count > 1) && (varinit != null))
2909 30671, lexer.Location,
2910 "Multiple variables with single type can not have " +
2911 "a explicit initialization" );
2914 foreach (VarName vname in names)
2916 string varname = (string) vname.Name;
2917 current_rank_specifiers = (ArrayList) vname.Rank;
2921 if(vname.Type != null && $2 != null)
2923 30302, lexer.Location,
2924 "Type character cannot be used with explicit type declaration" );
2926 // Some checking is required for particularly weird declarations
2927 // like Dim a As Integer(,)
2929 vartype = (Expression) ((Pair) $2).First;
2931 if ($3 != null && $3 is ArrayList)
2932 Report.Error (205, "End of statement expected.");
2934 ArrayList args = (ArrayList) ((Pair) $2).Second;
2935 if (VariableDeclaration.IndexesSpecifiedInRank (args))
2936 Report.Error (638, "Array bounds cannot appear in type specifiers.");
2938 string s_vartype = vartype.ToString();
2941 for (int x = 0; x < args.Count; x++)
2945 vartype = DecomposeQI(s_vartype, Location.Null);
2948 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
2950 // if the variable is an array with explicit bound
2951 // and having explicit initialization throw exception
2952 if (current_rank_specifiers != null && varinit != null)
2954 bool broken = false;
2955 foreach (ArrayList exprs in current_rank_specifiers)
2957 foreach (Expression expr in exprs)
2959 if (!((Expression)expr is EmptyExpression ))
2962 30672, lexer.Location,
2963 "Array declared with explicit bound " +
2964 " can not have explicit initialization");
2975 Check for a declaration like Dim a(2) or Dim a(2,3)
2976 If this is the case, we must generate an ArrayCreationExpression
2977 and, in case, add the initializer after the array has been created.
2979 if (VariableDeclaration.IsArrayDecl (this)) {
2980 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
2981 a_dims = (ArrayList) current_rank_specifiers;
2982 VariableDeclaration.VBFixIndexLists (ref a_dims);
2983 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
2985 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
2988 if (vartype is New) {
2989 if (varinit != null) {
2990 Report.Error (30205, lexer.Location, "End of statement expected");
2996 vartype = ((New)vartype).RequestedType;
2999 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3001 $$ = VarDeclarations;
3008 ArrayList list = new ArrayList ();
3012 | variable_names COMMA variable_name
3014 ArrayList list = (ArrayList) $1;
3021 : identifier opt_type_character opt_array_name_modifier
3023 $$ = new VarName ($1, $2, $3);
3034 $$ = (Expression) $2;
3040 | AS type rank_specifiers
3042 $$ = TypeManager.system_object_expr;
3051 | AS type OPEN_PARENS opt_argument_list CLOSE_PARENS
3053 $$ = new Pair ($2, $4);
3057 New n = new New ((Expression)$3, null, lexer.Location);
3058 $$ = (Expression) n;
3060 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3062 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3063 $$ = (Expression) n;
3067 opt_array_name_modifier
3068 : /* empty */ { $$ = null; }
3069 | array_type_modifier { $$ = $1; }
3073 : rank_specifiers { $$ = $1; }
3076 opt_variable_initializer
3077 : /* empty */ { $$ = null; }
3078 | ASSIGN variable_initializer { $$ = $2; }
3081 variable_initializer
3094 : OPEN_BRACE CLOSE_BRACE
3096 ArrayList list = new ArrayList ();
3099 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3101 $$ = (ArrayList) $2;
3105 variable_initializer_list
3106 : variable_initializer
3108 ArrayList list = new ArrayList ();
3112 | variable_initializer_list COMMA variable_initializer
3114 ArrayList list = (ArrayList) $1;
3135 ArrayList rs = new ArrayList();
3139 | rank_specifiers rank_specifier
3141 ArrayList rs = (ArrayList) $1;
3148 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
3157 ArrayList ds = new ArrayList();
3158 ds.Add (new EmptyExpression());
3163 ArrayList ds = (ArrayList) $1;
3164 ds.Add (new EmptyExpression());
3176 ArrayList ds = new ArrayList();
3177 ds.Add (new EmptyExpression());
3180 | dim_separators COMMA
3182 ArrayList ds = (ArrayList) $1;
3183 ds.Add (new EmptyExpression());
3191 ArrayList ds = new ArrayList();
3192 ds.Add ((Expression) $1);
3195 | dim_specifiers COMMA expression
3197 ArrayList ds = (ArrayList) $1;
3198 ds.Add ((Expression) $3);
3210 | qualified_identifier
3212 string name = (string) $1;
3214 $$ = DecomposeQI (name, lexer.Location);
3216 | parenthesized_expression
3218 | invocation_expression
3230 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3231 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3232 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3233 | NOTHING { $$ = NullLiteral.Null; }
3237 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3238 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3239 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3244 object v = lexer.Value;
3247 $$ = new IntLiteral ((Int32)v);
3248 else if (v is short)
3249 $$ = new ShortLiteral ((Int16)v);
3251 $$ = new LongLiteral ((Int64)v);
3253 Console.WriteLine ("OOPS. Unexpected result from scanner");
3259 : TRUE { $$ = new BoolLiteral (true); }
3260 | FALSE { $$ = new BoolLiteral (false); }
3263 parenthesized_expression
3264 : OPEN_PARENS expression CLOSE_PARENS
3269 : primary_expression DOT identifier
3272 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3275 if (with_stack.Count > 0) {
3276 Expression e = (Expression) with_stack.Peek();
3277 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3285 | primary_expression DOT NEW
3287 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3289 | predefined_type DOT identifier
3292 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3295 if (with_stack.Count > 0) {
3296 Expression e = (Expression) with_stack.Peek();
3297 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3311 invocation_expression
3312 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3315 Location l = lexer.Location;
3316 Report.Error (1, l, "THIS IS CRAZY");
3318 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3319 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3324 : MYBASE DOT IDENTIFIER
3326 $$ = new BaseAccess ((string) $3, lexer.Location);
3330 $$ = new BaseAccess ("New", lexer.Location);
3338 The 'argument' rule returns an 'empty' argument
3339 of type NoArg (used for default arguments in invocations)
3340 if no arguments are actually passed.
3342 If there is only one argument and it is o type NoArg,
3343 we return a null (empty) list
3345 ArrayList args = (ArrayList) $1;
3346 if (args.Count == 1 &&
3347 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3357 ArrayList list = new ArrayList ();
3361 | argument_list COMMA argument
3363 ArrayList list = (ArrayList) $1;
3372 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3374 | BYREF variable_reference
3376 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3380 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3385 : expression {/* note ("section 5.4"); */ $$ = $1; }
3391 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3396 : conditional_expression { $$ = $1; }
3397 | negation_expression
3398 /*| assignment_expression*/
3409 $$ = new This (current_block, lexer.Location);
3413 // FIXME: This is actually somewhat different from Me
3414 // because it is for accessing static (classifier) methods/properties/fields
3415 $$ = new This (current_block, lexer.Location);
3420 : primary_expression
3421 /*| NOT prefixed_unary_expression
3423 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3425 | cast_expression */
3429 : cast_operator OPEN_PARENS expression CLOSE_PARENS
3431 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3433 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3435 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3440 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3441 | CBYTE { $$ = TypeManager.system_byte_expr; }
3442 | CCHAR { $$ = TypeManager.system_char_expr; }
3443 | CDATE { $$ = TypeManager.system_date_expr; }
3444 | CDBL { $$ = TypeManager.system_double_expr; }
3445 | CDEC { $$ = TypeManager.system_decimal_expr; }
3446 | CINT { $$ = TypeManager.system_int32_expr; }
3447 | CLNG { $$ = TypeManager.system_int64_expr; }
3448 | COBJ { $$ = TypeManager.system_object_expr; }
3449 | CSHORT { $$ = TypeManager.system_int16_expr; }
3450 | CSNG { $$ = TypeManager.system_single_expr; }
3451 | CSTR { $$ = TypeManager.system_string_expr; }
3455 // The idea to split this out is from Rhys' grammar
3456 // to solve the problem with casts.
3458 prefixed_unary_expression
3460 | PLUS prefixed_unary_expression
3462 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3464 | MINUS prefixed_unary_expression
3466 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3468 | ADDRESSOF prefixed_unary_expression
3470 // FIXME: We should generate an error if AddressOf is NOT used
3471 // during delegate creation
3476 multiplicative_expression
3477 : prefixed_unary_expression
3478 | multiplicative_expression STAR prefixed_unary_expression
3480 $$ = new Binary (Binary.Operator.Multiply,
3481 (Expression) $1, (Expression) $3, lexer.Location);
3483 | multiplicative_expression DIV prefixed_unary_expression
3485 $$ = new Binary (Binary.Operator.Division,
3486 (Expression) $1, (Expression) $3, lexer.Location);
3488 | multiplicative_expression OP_IDIV prefixed_unary_expression
3490 $$ = new Binary (Binary.Operator.Division,
3491 (Expression) $1, (Expression) $3, lexer.Location);
3493 | multiplicative_expression MOD prefixed_unary_expression
3495 $$ = new Binary (Binary.Operator.Modulus,
3496 (Expression) $1, (Expression) $3, lexer.Location);
3501 : multiplicative_expression
3502 | additive_expression PLUS multiplicative_expression
3504 $$ = new Binary (Binary.Operator.Addition,
3505 (Expression) $1, (Expression) $3, lexer.Location);
3507 | additive_expression MINUS multiplicative_expression
3509 $$ = new Binary (Binary.Operator.Subtraction,
3510 (Expression) $1, (Expression) $3, lexer.Location);
3512 | additive_expression OP_CONCAT multiplicative_expression
3514 // FIXME: This should only work for String expressions
3515 // We probably need to use something from the runtime
3516 $$ = new Binary (Binary.Operator.Addition,
3517 (Expression) $1, (Expression) $3, lexer.Location);
3521 relational_expression
3522 : additive_expression
3523 | relational_expression OP_LT additive_expression
3525 $$ = new Binary (Binary.Operator.LessThan,
3526 (Expression) $1, (Expression) $3, lexer.Location);
3528 | relational_expression OP_GT additive_expression
3530 $$ = new Binary (Binary.Operator.GreaterThan,
3531 (Expression) $1, (Expression) $3, lexer.Location);
3533 | relational_expression OP_LE additive_expression
3535 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3536 (Expression) $1, (Expression) $3, lexer.Location);
3538 | relational_expression OP_GE additive_expression
3540 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3541 (Expression) $1, (Expression) $3, lexer.Location);
3543 | relational_expression IS unary_expression
3545 $$ = new Binary (Binary.Operator.Equality,
3546 (Expression) $1, (Expression) $3, lexer.Location);
3548 | relational_expression AS type_name
3550 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3555 : relational_expression
3556 | equality_expression ASSIGN relational_expression
3558 $$ = new Binary (Binary.Operator.Equality,
3559 (Expression) $1, (Expression) $3, lexer.Location);
3561 | equality_expression OP_NE relational_expression
3563 $$ = new Binary (Binary.Operator.Inequality,
3564 (Expression) $1, (Expression) $3, lexer.Location);
3569 : equality_expression
3570 | and_expression AND equality_expression
3572 $$ = new Binary (Binary.Operator.BitwiseAnd,
3573 (Expression) $1, (Expression) $3, lexer.Location);
3577 exclusive_or_expression
3579 | exclusive_or_expression OP_XOR and_expression
3581 $$ = new Binary (Binary.Operator.ExclusiveOr,
3582 (Expression) $1, (Expression) $3, lexer.Location);
3586 conditional_and_expression
3587 : exclusive_or_expression
3588 | conditional_and_expression AND exclusive_or_expression
3590 $$ = new Binary (Binary.Operator.LogicalAnd,
3591 (Expression) $1, (Expression) $3, lexer.Location);
3593 | conditional_and_expression ANDALSO exclusive_or_expression
3594 { // FIXME: this is likely to be broken
3595 $$ = new Binary (Binary.Operator.LogicalAnd,
3596 (Expression) $1, (Expression) $3, lexer.Location);
3600 conditional_or_expression
3601 : conditional_and_expression
3602 | conditional_or_expression OR conditional_and_expression
3604 $$ = new Binary (Binary.Operator.LogicalOr,
3605 (Expression) $1, (Expression) $3, lexer.Location);
3607 | conditional_or_expression ORELSE conditional_and_expression
3608 { // FIXME: this is likely to be broken
3609 $$ = new Binary (Binary.Operator.LogicalOr,
3610 (Expression) $1, (Expression) $3, lexer.Location);
3614 conditional_expression
3615 : conditional_or_expression
3618 assignment_expression
3619 : prefixed_unary_expression ASSIGN expression
3621 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3623 | prefixed_unary_expression OP_MULT_ASSIGN expression
3625 Location l = lexer.Location;
3627 $$ = new CompoundAssign (
3628 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3630 | prefixed_unary_expression OP_DIV_ASSIGN expression
3632 Location l = lexer.Location;
3634 $$ = new CompoundAssign (
3635 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3637 | prefixed_unary_expression OP_IDIV_ASSIGN expression
3639 Location l = lexer.Location;
3641 $$ = new CompoundAssign (
3642 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3644 | prefixed_unary_expression OP_ADD_ASSIGN expression
3646 Location l = lexer.Location;
3648 $$ = new CompoundAssign (
3649 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3651 | prefixed_unary_expression OP_SUB_ASSIGN expression
3653 Location l = lexer.Location;
3655 $$ = new CompoundAssign (
3656 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3658 | prefixed_unary_expression OP_CONCAT_ASSIGN expression
3660 Location l = lexer.Location;
3662 $$ = new CompoundAssign (
3663 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3667 /*constant_expression
3677 : type_name { /* class_type */
3679 This does interfaces, delegates, struct_types, class_types,
3680 parent classes, and more! 4.2
3682 $$ = DecomposeQI ((string) $1, lexer.Location);
3692 ArrayList types = new ArrayList ();
3697 | type_list COMMA type
3699 ArrayList types = (ArrayList) $1;
3707 : namespace_or_type_name
3710 namespace_or_type_name
3711 : qualified_identifier
3714 /* Built-in / Integral types */
3716 : OBJECT { $$ = TypeManager.system_object_expr; }
3717 | STRING { $$ = TypeManager.system_string_expr; }
3718 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
3719 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
3720 | SINGLE { $$ = TypeManager.system_single_expr; }
3721 | DOUBLE { $$ = TypeManager.system_double_expr; }
3722 | DATE { $$ = TypeManager.system_date_expr; }
3728 | BYTE { $$ = TypeManager.system_byte_expr; }
3729 | SHORT { $$ = TypeManager.system_int16_expr; }
3730 | LONG { $$ = TypeManager.system_int64_expr; }
3731 | INTEGER { $$ = TypeManager.system_int32_expr; }
3732 | CHAR { $$ = TypeManager.system_char_expr; }
3748 public Tokenizer Lexer {
3754 public static Expression DecomposeQI (string name, Location loc)
3758 if (name.IndexOf ('.') == -1){
3759 return new SimpleName (name, loc);
3761 int pos = name.LastIndexOf (".");
3762 string left = name.Substring (0, pos);
3763 string right = name.Substring (pos + 1);
3765 o = DecomposeQI (left, loc);
3767 return new MemberAccess (o, right, loc);
3771 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
3773 Block implicit_block;
3774 ArrayList inits = null;
3777 // We use the `Used' property to check whether statements
3778 // have been added to the current block. If so, we need
3779 // to create another block to contain the new declaration
3780 // otherwise, as an optimization, we use the same block to
3781 // add the declaration.
3783 // FIXME: A further optimization is to check if the statements
3784 // that were added were added as part of the initialization
3785 // below. In which case, no other statements have been executed
3786 // and we might be able to reduce the number of blocks for
3787 // situations like this:
3789 // int j = 1; int k = j + 1;
3792 VariableDeclaration.FixupTypes (variable_declarators);
3794 if (current_block.Used) {
3795 implicit_block = new Block (current_block, true, loc, Location.Null);
3796 implicit_block.AddChildVariableNames (current_block);
3798 implicit_block = current_block;
3800 foreach (VariableDeclaration decl in variable_declarators){
3801 Expression type = decl.type;
3802 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
3803 if (decl.expression_or_array_initializer != null){
3805 inits = new ArrayList ();
3812 return implicit_block;
3814 foreach (VariableDeclaration decl in inits){
3817 Expression type = decl.type;
3819 if ((decl.expression_or_array_initializer is Expression) ||
3820 (decl.expression_or_array_initializer is New)) {
3821 expr = (Expression) decl.expression_or_array_initializer;
3823 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3825 expr = new ArrayCreation (type, "", init, decl.Location);
3828 LocalVariableReference var;
3829 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
3831 assign = new Assign (var, expr, decl.Location);
3833 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
3836 return implicit_block;
3839 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
3841 Block implicit_block;
3842 VariableDeclaration.FixupTypes (variable_declarators);
3844 if (current_block.Used)
3845 implicit_block = new Block (current_block, true);
3847 implicit_block = current_block;
3849 foreach (VariableDeclaration decl in variable_declarators){
3850 Expression type = decl.type;
3851 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
3852 current_local_parameters, decl.Location);
3855 return implicit_block;
3863 public VarName (object n, object t, object r)
3873 // A class used to pass around variable declarations and constants
3875 public class VariableDeclaration {
3876 public string identifier;
3877 public object expression_or_array_initializer;
3878 public Location Location;
3879 public Attributes OptAttributes;
3880 public Expression type;
3881 public ArrayList dims;
3883 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
3885 this.identifier = id;
3886 this.expression_or_array_initializer = eoai;
3888 this.OptAttributes = opt_attrs;
3893 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
3897 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
3901 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
3902 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
3906 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
3908 // FIXME : This is broken: only the first rank is parsed
3909 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
3912 public static void FixupTypes (ArrayList vars)
3914 int varcount = vars.Count;
3915 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
3917 if (last_var.type == null)
3918 last_var.type = TypeManager.system_object_expr;
3920 Expression cur_type = last_var.type;
3921 int n = varcount - 1;
3924 VariableDeclaration var = (VariableDeclaration) vars[n--];
3925 if (var.type == null)
3926 var.type = cur_type;
3928 cur_type = var.type;
3932 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
3936 if (IndexList != null) {
3937 foreach (Expression e in IndexList)
3938 if (!(e is EmptyExpression)) {
3947 public static bool IndexesSpecified (ArrayList ranks)
3951 if (ranks != null) {
3952 foreach (ArrayList IndexList in ranks) {
3953 if (IndexesSpecifiedInRank (IndexList)) {
3962 public static string StripDims (string varname, ref string d)
3964 string res = varname;
3967 if (varname.IndexOf("[") >= 0) {
3968 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
3969 res = varname.Substring(0, varname.IndexOf("["));
3975 public static string StripDims (string varname)
3979 return (StripDims(varname, ref dres));
3982 public static string StripIndexesFromDims (string dims)
3984 StringBuilder sb = new StringBuilder();
3986 foreach (char c in dims)
3987 if (c == ',' || c == ']' || c == '[')
3990 return sb.ToString();
3993 public static string BuildRank (ArrayList rank)
3998 for (int x = 0; x < (rank.Count -1 ); x++)
4005 public static string BuildRanks (Parser t)
4009 foreach (ArrayList rank in t.current_rank_specifiers)
4010 res += BuildRank (rank);
4015 public static void VBFixIndexList (ref ArrayList IndexList)
4017 if (IndexList != null) {
4018 for (int x = 0; x < IndexList.Count; x++) {
4019 Expression e = (Expression) IndexList[x];
4020 if (!(e is EmptyExpression)) {
4021 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4027 public static bool IsArrayDecl (Parser t)
4029 // return (varname.IndexOf("[") >= 0);
4030 return (t.current_rank_specifiers != null);
4033 public static void VBFixIndexLists (ref ArrayList ranks)
4035 if (ranks != null) {
4036 for (int x = 0; x < ranks.Count; x++) {
4037 ArrayList IndexList = (ArrayList) ranks[x];
4038 VBFixIndexList (ref IndexList);
4043 public static void FixupArrayTypes (ArrayList vars)
4045 int varcount = vars.Count;
4048 foreach (VariableDeclaration var in vars) {
4049 if (var.identifier.EndsWith(",")) {
4050 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4051 var.identifier.LastIndexOf(",")) + "]";
4052 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4053 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4060 public Property BuildSimpleProperty (Expression p_type, string name,
4061 Field p_fld, int mod_flags,
4062 Attributes attrs, Location loc)
4065 Block get_block, set_block;
4066 Accessor acc_set, acc_get;
4067 StatementExpression a_set;
4072 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4073 args = new Parameter [1];
4074 args [0] = implicit_value_parameter;
4076 Parameters set_params = new Parameters (args, null, loc);
4077 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4078 (Expression) new SimpleName("value", loc), loc), loc);
4080 set_block = new Block (current_block, set_params, loc, Location.Null);
4081 set_block.AddStatement ((Statement) a_set);
4082 acc_set = new Accessor (set_block, attrs);
4085 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4086 get_block = new Block (current_block, null, loc, Location.Null);
4087 get_block.AddStatement ((Statement) a_get);
4088 acc_get = new Accessor (get_block, attrs);
4090 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4097 current_block = new Block (current_block, current_local_parameters,
4098 lexer.Location, Location.Null);
4105 while (current_block.Implicit)
4106 current_block = current_block.Parent;
4108 res = current_block;
4110 current_block.SetEndLocation (lexer.Location);
4111 current_block = current_block.Parent;
4116 private void AddHandler (Expression evt_definition, string handler_name)
4118 AddHandler (current_block, evt_definition, handler_name);
4121 void CheckAttributeTarget (string a)
4125 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4129 Location l = lexer.Location;
4130 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4135 private void AddHandler (Block b, Expression evt_id, string handler_name)
4137 Location loc = lexer.Location;
4138 string evt_target = evt_id.ToString();
4139 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4140 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4144 private void RaiseEvent (string evt_name, ArrayList args)
4146 Location loc = lexer.Location;
4148 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4149 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4150 current_block.AddStatement (s);
4153 // FIXME: THIS DOES NOT WORK!!!
4154 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4156 Location loc = lexer.Location;
4157 ArrayList neh_args = new ArrayList();
4158 neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
4160 ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
4162 CompoundAssign ca = new CompoundAssign (
4163 Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
4165 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc));
4170 // This method is used to get at the complete string representation of
4171 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4172 // This is necessary because local_variable_type admits primary_expression
4173 // as the type of the variable. So we do some extra checking
4175 string GetQualifiedIdentifier (Expression expr)
4177 if (expr is SimpleName)
4178 return ((SimpleName)expr).Name;
4179 else if (expr is MemberAccess)
4180 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4182 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4186 private void RemoveHandler (Expression evt_definition, string handler_name)
4188 RemoveHandler (current_block, evt_definition, handler_name);
4191 private ConstructorInitializer FixConstructorInitializer (ref ArrayList s)
4193 ConstructorInitializer ci = null;
4196 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4197 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4199 if (i.expr is BaseAccess) {
4200 BaseAccess ba = (BaseAccess) i.expr;
4201 if (ba.member == "New" || ba.member == ".ctor") {
4202 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4206 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4207 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4215 void Error_ExpectingTypeName (Location l, Expression expr)
4217 if (expr is Invocation){
4218 Report.Error (1002, l, "; expected");
4220 Report.Error (-1, l, "Invalid Type definition");
4224 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4228 private void ReportError9998()
4230 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4233 protected override int parse ()
4235 RootContext.InitializeImports(ImportsList);
4236 current_namespace = new Namespace (null, RootContext.RootNamespace);
4237 current_container = RootContext.Tree.Types;
4238 current_container.Namespace = current_namespace;
4239 oob_stack = new Stack ();
4240 switch_stack = new Stack ();
4241 expr_stack = new Stack ();
4242 tmp_blocks = new Stack();
4243 with_stack = new Stack();
4244 statement_stack = new Stack();
4246 UseExtendedSyntax = name.EndsWith(".mbs");
4247 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4248 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4249 OptionCompareBinary = InitialOptionCompareBinary;
4251 lexer = new Tokenizer (input, name, defines);
4252 StringBuilder value = new StringBuilder ();
4254 if (yacc_verbose_flag)
4255 yyparse (lexer, new yydebug.yyDebugSimple ());
4258 } catch (Exception e) {
4259 Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.ref_name + "\n" + e.ToString());
4262 RootContext.VerifyImports();
4264 return Report.Errors;