3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
5 // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
6 // Anirban Bhattacharjee (banirban@novell.com)
8 // Licensed under the terms of the GNU GPL
10 // Copyright (C) 2001 A Rafael D Teixeira
14 namespace Mono.MonoBASIC
18 using System.Reflection;
19 using System.Collections;
23 public class MBASException : ApplicationException
28 public MBASException(int code, Location loc, string text) : base(text)
36 /// The MonoBASIC Parser
39 public class Parser : GenericParser
44 /// Current block is used to add statements as we find
50 /// Tmp block is used to store block endings in if/select's
55 /// Tmp block is used to store tmp copies of expressions
60 /// Tmp catch is used to store catch clauses in try..catch..finally
62 ArrayList tmp_catch_clauses;
65 /// Current interface is used by the various declaration
66 /// productions in the interface declaration to "add"
67 /// the interfaces as we find them.
69 Interface current_interface;
72 /// This is used by the unary_expression code to resolve
73 /// a name against a parameter.
75 Parameters current_local_parameters;
78 /// This are used when parsing parameters in property
81 Parameters set_parameters;
82 Parameters get_parameters;
85 /// This is used by the sub_header parser to store modifiers
86 /// to be passed to sub/constructor
88 int current_modifiers;
91 /// This is used by the sub_header parser to store attributes
92 /// to be passed to sub/constructor
94 Attributes current_attributes;
97 /// Using during property parsing to describe the implicit
98 /// value parameter that is passed to the "set" accessor
101 string get_implicit_value_parameter_name;
104 // Using during property parsing to describe the implicit
105 // value parameter that is passed to the "set" and "get"accesor
106 // methods (properties and indexers).
108 Expression get_implicit_value_parameter_type;
111 /// Using during property parsing to describe the implicit
112 /// value parameter that is passed to the "set" accessor
115 string set_implicit_value_parameter_name;
118 // Using during property parsing to describe the implicit
119 // value parameter that is passed to the "set" and "get"accesor
120 // methods (properties and indexers).
122 Expression set_implicit_value_parameter_type;
124 Location member_location;
126 // An out-of-band stack.
130 ArrayList current_rank_specifiers;
138 // Expression stack for nested ifs
142 Stack statement_stack;
144 // A stack for With expressions.
149 static public bool InitialOptionExplicit = false;
150 static public bool InitialOptionStrict = false;
151 static public bool InitialOptionCompareBinary = true;
152 static public ArrayList ImportsList = null;
156 bool OptionCompareBinary;
158 static public bool UseExtendedSyntax; // for ".mbs" files
160 bool implicit_modifiers;
162 public override string[] extensions()
164 string [] list = { ".vb", ".mbs" };
168 bool in_external_source = false;
169 int in_marked_region = 0;
171 TokenizerController tokenizerController;
172 IfElseStateMachine ifElseStateMachine;
175 public class IfElseStateMachine {
199 public static Hashtable errStrings = new Hashtable();
202 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
204 static IfElseStateMachine()
206 // FIXME: Fix both the error nos and the error strings.
207 // Currently the error numbers and the error strings are
208 // just placeholders for getting the state-machine going.
210 errStrings.Add(0, "");
211 errStrings.Add(30012, "#If must end with a matching #End If");
212 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
213 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
214 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
215 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
217 errTable[(int)State.START, (int)Token.IF] = 0;
218 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
219 errTable[(int)State.START, (int)Token.ELSE] = 30028;
220 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
221 errTable[(int)State.START, (int)Token.EOF] = 0;
223 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
224 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
225 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
226 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
227 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
229 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
230 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
231 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
232 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
233 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
235 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
236 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
237 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
238 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
239 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
241 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
242 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
243 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
244 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
245 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
248 public IfElseStateMachine()
252 stateStack = new Stack();
253 stateStack.Push(state);
256 // The parameter here need not be qualified with IfElseStateMachine
257 // But it hits a bug in mcs. So temporarily scoping it so that builds
260 public void HandleToken(IfElseStateMachine.Token tok)
262 err = (int) errTable[(int)state, (int)tok];
265 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
267 if(tok == Token.IF) {
268 stateStack.Push(state);
271 else if(tok == Token.ENDIF) {
272 state = (State)stateStack.Pop();
284 public string ErrString {
286 return (string) errStrings[err];
292 public class TokenizerController {
296 public bool CanAcceptTokens;
297 public bool CanSelectBlock;
305 public TokenizerController(Tokenizer lexer)
308 stateStack = new Stack();
310 currentState.CanAcceptTokens = true;
311 currentState.CanSelectBlock = true;
313 stateStack.Push(currentState);
318 return (State)stateStack.Peek();
322 public bool IsAcceptingTokens {
324 return currentState.CanAcceptTokens;
328 public void PositionCursorAtNextPreProcessorDirective()
330 lexer.PositionCursorAtNextPreProcessorDirective();
333 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
335 if(tok == IfElseStateMachine.Token.ENDIF) {
336 currentState = (State)stateStack.Pop();
338 if(currentState.CanAcceptTokens)
341 PositionCursorAtNextPreProcessorDirective();
346 if(tok == IfElseStateMachine.Token.IF) {
347 stateStack.Push(currentState);
349 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
350 currentState.CanSelectBlock = true;
353 if(parentState.CanAcceptTokens &&
354 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
356 currentState.CanAcceptTokens = true;
357 currentState.CanSelectBlock = false;
361 currentState.CanAcceptTokens = false;
362 PositionCursorAtNextPreProcessorDirective();
368 bool allow_global_attribs = true;
370 bool expecting_global_attribs = false;
371 bool expecting_local_attribs = false;
373 bool local_attrib_section_added = false;
377 %token NONE /* This token is never returned by our lexer */
378 %token ERROR // This is used not by the parser, but by the tokenizer.
382 *These are the MonoBASIC keywords
474 %token NOTINHERITABLE
475 %token NOTOVERRIDABLE
531 %token YIELD // MonoBASIC extension
535 /* MonoBASIC single character operators/punctuation. */
537 %token OPEN_BRACKET "["
538 %token CLOSE_BRACKET "]"
539 %token OPEN_PARENS "("
540 %token OPEN_BRACE "{"
541 %token CLOSE_BRACE "}"
542 %token CLOSE_PARENS ")"
556 %token OP_IDIV "\\" //FIXME: This should be "\"
558 %token EXCLAMATION "!"
561 %token LONGTYPECHAR "&"
563 %token SINGLETYPECHAR "!"
564 %token NUMBER_SIGN "#"
565 %token DOLAR_SIGN "$"
567 %token ATTR_ASSIGN ":="
569 /* MonoBASIC multi-character operators. */
574 //%token OP_MODULUS //"mod"
576 /* VB.NET 2003 new bit-shift operators */
577 %token OP_SHIFT_LEFT "<<"
578 %token OP_SHIFT_RIGHT ">>"
581 %token LITERAL_INTEGER "int literal"
582 %token LITERAL_SINGLE "float literal"
583 %token LITERAL_DOUBLE "double literal"
584 %token LITERAL_DECIMAL "decimal literal"
585 %token LITERAL_CHARACTER "character literal"
586 %token LITERAL_STRING "string literal"
587 %token LITERAL_DATE "datetime literal"
591 /* Add precedence rules to solve dangling else s/r conflict */
600 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
602 %left STAR DIV PERCENT
603 %right BITWISE_NOT CARRET UMINUS
604 %nonassoc OP_INC OP_DEC
606 %left OPEN_BRACKET OPEN_BRACE
611 %start compilation_unit
615 : logical_end_of_line
621 | logical_end_of_line pp_directive
625 : logical_end_of_line
626 opt_option_directives
627 opt_imports_directives
634 opt_option_directives
635 opt_imports_directives
643 opt_option_directives
650 | option_directives option_directive
654 : option_explicit_directive
655 | option_strict_directive
656 | option_compare_directive
685 option_explicit_directive
686 : OPTION EXPLICIT on_off logical_end_of_line
688 if (!UseExtendedSyntax)
689 OptionExplicit = (bool)$3;
692 9999, lexer.Location,
693 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
698 option_strict_directive
699 : OPTION STRICT on_off logical_end_of_line
701 if (!UseExtendedSyntax)
702 OptionStrict = (bool)$3;
705 9999, lexer.Location,
706 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
710 option_compare_directive
711 : OPTION COMPARE text_or_binary logical_end_of_line
713 OptionCompareBinary = (bool)$3;
724 | declarations declaration
728 : declaration_qualifiers
730 // FIXME: Need to check declaration qualifiers for multi-file compilation
731 // FIXME: Qualifiers cannot be applied to namespaces
732 allow_global_attribs = false;
734 namespace_declaration
735 |declaration_qualifiers
737 // FIXME: Need to check declaration qualifiers for multi-file compilation
738 allow_global_attribs = false;
740 type_spec_declaration
745 if ($3 is Class || $3 is Struct || $3 is Module ){
746 TypeContainer c = (TypeContainer) $3;
747 mod_flags = c.ModFlags;
752 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
754 1527, lexer.Location,
755 "Namespace elements cannot be explicitly " +
756 "declared private or protected in '" + name + "'");
771 : PERCENT { $$ = TypeManager.system_int32_expr; }
772 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
773 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
774 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
775 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
776 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
780 : /* empty */ { $$ = null; }
781 | type_character { $$ = $1; }
787 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
789 $$ = (($1).ToString ()) + "." + ($3.ToString ());
793 opt_imports_directives
800 | imports_directives imports_directive
804 : IMPORTS imports_terms logical_end_of_line
809 | imports_terms COMMA imports_term
813 : namespace_or_type_name
815 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
817 | identifier ASSIGN namespace_or_type_name
819 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
824 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
825 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
826 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
834 local_attrib_section_added = false;
843 expecting_local_attribs = false;
844 expecting_global_attribs = false;
848 if (expecting_local_attribs) {
849 local_attrib_section_added = true;
850 allow_global_attribs = false;
852 $$ = new Attributes ((ArrayList) $1);
855 if (expecting_global_attribs)
856 CodeGen.AddGlobalAttributes ((ArrayList) $1);
858 expecting_local_attribs = false;
859 expecting_global_attribs = false;
869 ArrayList attrs = (ArrayList) $3;
871 if (expecting_local_attribs) {
872 if (local_attrib_section_added) {
873 expecting_local_attribs = false;
874 expecting_global_attribs = false;
875 Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
880 $$ = new Attributes (attrs);
882 ((Attributes) $1).Add (attrs);
884 local_attrib_section_added = true;
885 allow_global_attribs = false;
888 if (expecting_global_attribs)
889 CodeGen.AddGlobalAttributes ((ArrayList) $3);
892 expecting_local_attribs = false;
893 expecting_global_attribs = false;
898 : OP_LT attribute_list OP_GT opt_end_of_stmt
902 if (expecting_global_attribs && !(bool) $4) {
903 Report.Error (30205, lexer.Location, "End of statement expected");
907 if (expecting_local_attribs) {
909 Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
920 : /* empty */ { $$ = false; }
921 | end_of_stmt { $$ = true; }
927 ArrayList attrs = null;
929 attrs = new ArrayList ();
934 | attribute_list COMMA attribute
936 ArrayList attrs = null;
939 attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
948 : namespace_or_type_name
952 opt_attribute_arguments
956 if (expecting_global_attribs)
957 Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
959 expecting_local_attribs = true;
960 $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
963 | attribute_target_specifier
968 namespace_or_type_name
972 opt_attribute_arguments
976 string attribute_target = (string) $1;
977 if (attribute_target != "assembly" && attribute_target != "module") {
978 Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
981 if (!allow_global_attribs) {
982 Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
986 if (expecting_local_attribs) {
987 Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
991 expecting_global_attribs = true;
992 $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
996 attribute_target_specifier
997 : ASSEMBLY { $$ = "assembly"; }
998 | MODULE { $$ = "module"; }
999 | namespace_or_type_name
1003 opt_attribute_arguments
1004 : /* empty */ { $$ = null; }
1005 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
1011 opt_attribute_arguments_list
1013 | attribute_arguments_list
1016 attribute_arguments_list
1017 : positional_argument_list
1019 ArrayList args = new ArrayList ();
1024 | positional_argument_list COMMA named_argument_list
1026 ArrayList args = new ArrayList ();
1032 | named_argument_list
1034 ArrayList args = new ArrayList ();
1042 positional_argument_list
1043 : constant_expression
1045 ArrayList args = new ArrayList ();
1046 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
1050 | positional_argument_list COMMA constant_expression
1052 ArrayList args = (ArrayList) $1;
1053 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
1062 ArrayList args = new ArrayList ();
1067 | named_argument_list COMMA named_argument
1069 ArrayList args = (ArrayList) $1;
1077 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
1079 $$ = new DictionaryEntry (
1081 new Argument ((Expression) $3, Argument.AType.Expression));
1085 namespace_declaration
1086 : NAMESPACE qualified_identifier logical_end_of_line
1088 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2);
1091 END NAMESPACE logical_end_of_line
1093 current_namespace = current_namespace.Parent;
1097 declaration_qualifiers
1101 current_attributes = (Attributes) $1;
1102 current_modifiers = (int) $2;
1106 type_spec_declaration
1108 | module_declaration
1109 | interface_declaration
1110 | delegate_declaration
1111 | struct_declaration
1116 : CLASS identifier logical_end_of_line opt_inherits opt_implements
1118 // Module members are static by default, but Class *can't* be declared static
1119 // so we must fix it, if mbas was the one actually responsible for this
1120 // instead of triggering an error.
1121 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1122 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1127 name = MakeName ((string) $2);
1128 new_class = new Class (current_container, name, current_modifiers,
1129 (Attributes) current_attributes, lexer.Location);
1131 current_container = new_class;
1132 current_container.Namespace = current_namespace;
1133 RootContext.Tree.RecordDecl (name, new_class);
1135 opt_class_member_declarations
1136 END CLASS logical_end_of_line
1138 Class new_class = (Class) current_container;
1140 ArrayList bases = (ArrayList) $4;
1142 ArrayList ifaces = (ArrayList) $5;
1143 if (ifaces != null){
1145 bases.AddRange(ifaces);
1149 new_class.Bases = bases;
1151 current_container = current_container.Parent;
1152 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1159 : /* empty */ { $$ = null; }
1160 | INHERITS type_list logical_end_of_line { $$ = $2; }
1164 : /* empty */ { $$ = null; }
1165 | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
1169 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1170 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1175 | modifiers modifier
1180 if ((m1 & m2) != 0) {
1181 Location l = lexer.Location;
1182 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1184 $$ = (int) (m1 | m2);
1189 : PUBLIC { $$ = Modifiers.PUBLIC; }
1190 | PROTECTED { $$ = Modifiers.PROTECTED; }
1191 | PRIVATE { $$ = Modifiers.PRIVATE; }
1192 | SHARED { $$ = Modifiers.STATIC; }
1193 | FRIEND { $$ = Modifiers.INTERNAL; }
1194 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1195 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1196 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1197 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1198 | OVERLOADS { $$ = Modifiers.NEW; }
1199 | SHADOWS { $$ = Modifiers.SHADOWS; }
1200 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1201 | READONLY { $$ = Modifiers.READONLY; }
1202 | DEFAULT { $$ = Modifiers.DEFAULT; }
1203 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1207 : MODULE identifier logical_end_of_line
1211 name = MakeName((string) $2);
1212 new_module = new Module(current_container,
1214 current_modifiers, // already checks then
1215 (Attributes) current_attributes,
1217 current_container = new_module;
1218 current_container.Namespace = current_namespace;
1219 RootContext.Tree.RecordDecl(name, new_module);
1221 opt_module_member_declarations
1222 END MODULE logical_end_of_line
1224 Module new_module = (Module)current_container;
1226 current_container = current_container.Parent;
1227 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1229 TypeManager.AddStandardModule(new_module);
1235 opt_module_member_declarations
1237 | module_member_declarations
1240 module_member_declarations
1241 : module_member_declaration
1242 | module_member_declarations module_member_declaration
1245 module_member_declaration
1249 current_attributes = (Attributes) $1;
1250 current_modifiers = ((int)$2) | Modifiers.STATIC;
1251 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1252 implicit_modifiers = (!explicit_static);
1254 module_member_declarator
1256 implicit_modifiers = false;
1261 module_member_declarator
1262 : constructor_declaration
1263 | method_declaration
1265 Method method = (Method) $1;
1266 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1269 | withevents_declaration /* This is a field but must be treated specially, see below */
1270 | constant_declaration
1271 | property_declaration
1273 | type_spec_declaration
1276 constant_declaration
1277 : CONST constant_declarators logical_end_of_line
1279 // Module members are static by default, but constants *can't* be declared static
1280 // so we must fix it, if mbas was the one actually responsible for this
1281 // instead of triggering an error.
1282 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1283 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1285 int mod = (int) current_modifiers;
1287 // Structure members are Public by default
1288 if ((current_container is Struct) && (mod == 0))
1289 mod = Modifiers.PUBLIC;
1291 ArrayList consts = (ArrayList) $2;
1292 if(consts.Count > 0)
1294 VariableDeclaration.FixupTypes ((ArrayList) $2);
1295 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1297 foreach (VariableDeclaration var in (ArrayList) $2){
1298 Location l = var.Location;
1299 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1300 (Expression)var.expression_or_array_initializer,
1301 mod, (Attributes) null, l);
1303 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1309 opt_class_member_declarations
1311 | class_member_declarations
1314 class_member_declarations
1315 : class_member_declaration
1316 | class_member_declarations class_member_declaration
1319 class_member_declaration
1323 current_attributes = (Attributes) $1;
1324 current_modifiers = (int) $2;
1326 class_member_declarator
1332 class_member_declarator
1333 : constructor_declaration
1334 | method_declaration
1336 Method method = (Method) $1;
1337 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1340 | constant_declaration
1341 | property_declaration
1343 | withevents_declaration /* This is a field but must be treated specially, see below */
1344 | type_spec_declaration
1351 | must_override_declaration
1354 must_override_declaration
1355 : must_override_sub_declaration
1356 | must_override_func_declaration
1359 must_override_sub_declaration
1360 : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
1362 if (current_container is Module)
1363 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1365 if (current_container is Struct)
1366 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1368 current_modifiers |= Modifiers.ABSTRACT;
1370 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1371 (Parameters) $4, null, (ArrayList) $5, lexer.Location);
1373 if (!(current_container is Class))
1374 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1381 must_override_func_declaration
1382 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1384 Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.
1385 system_object_expr : (Expression) $4 ) : (Expression) $6;
1387 if (current_container is Module)
1388 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1390 if (current_container is Struct)
1391 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1393 current_modifiers |= Modifiers.ABSTRACT;
1395 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1396 (string) $3,(Parameters) $5, null, (ArrayList) $7,
1399 if (!(current_container is Class))
1400 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1407 : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1409 current_local_parameters = (Parameters) $3;
1412 // Structure members are Public by default
1413 if ((current_container is Struct) && (current_modifiers == 0))
1414 current_modifiers = Modifiers.PUBLIC;
1416 member_location = lexer.Location;
1419 END SUB logical_end_of_line
1421 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1422 (Parameters) current_local_parameters, (Attributes) current_attributes,
1423 (ArrayList) $5, member_location);
1425 method.Block = (Block) end_block();
1429 // we have an event handler to take care of
1431 Expression handles_exp = (Expression) $4;
1432 Location loc = lexer.Location;
1434 if (handles_exp is MemberAccess) {
1435 string evt_def = ((MemberAccess)$4).ToString();
1436 int pos = evt_def.LastIndexOf (".");
1437 string evt_target = evt_def.Substring (0, pos);
1440 if (current_container.Properties != null) {
1441 foreach (Property p in current_container.Properties) {
1442 if (p.Name == evt_target) {
1445 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1446 DecomposeQI((string) $2, loc),
1449 current_container.AddEventHandler (addhnd);
1457 Report.Error(30506, lexer.Location,
1458 evt_target + " is not declared with WithEvents");
1460 } else if (handles_exp is BaseAccess) {
1461 string evt_id = ((BaseAccess) $4).member;
1462 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1463 DecomposeQI((string) $2, loc),
1466 current_container.AddEventHandler (addhnd);
1474 : FUNCTION identifier opt_type_character
1475 opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1477 current_local_parameters = (Parameters) $4;
1478 member_location = lexer.Location;
1481 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1483 // Structure members are Public by default
1484 if ((current_container is Struct) && (current_modifiers == 0))
1485 current_modifiers = Modifiers.PUBLIC;
1486 // Add local var declaration
1488 ArrayList retval = new ArrayList ();
1489 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1490 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1493 END FUNCTION logical_end_of_line
1495 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1497 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1498 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1499 (ArrayList) $6, member_location);
1500 method.Block = end_block();
1506 : STRUCTURE identifier logical_end_of_line
1507 opt_implement_clause
1510 string full_struct_name = MakeName ((string) $2);
1512 // Module members are static by default, but structures *can't* be declared static
1513 // so we must fix it, if mbas was the one actually responsible for this
1514 // instead of triggering an error.
1515 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1516 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1518 new_struct = new Struct (current_container, full_struct_name,
1519 (int) current_modifiers,
1520 (Attributes) current_attributes, lexer.Location);
1521 current_container = new_struct;
1522 current_container.Namespace = current_namespace;
1523 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1525 opt_struct_member_declarations
1527 Struct new_struct = (Struct) current_container;
1530 new_struct.Bases = (ArrayList) $4;
1532 current_container = current_container.Parent;
1533 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1536 END STRUCTURE logical_end_of_line
1539 opt_struct_member_declarations
1541 | struct_member_declarations
1544 struct_member_declarations
1545 : struct_member_declaration
1546 | struct_member_declarations struct_member_declaration
1549 struct_member_declaration
1551 struct_member_declarator
1554 struct_member_declarator
1556 | constant_declaration
1557 | constructor_declaration
1558 | method_declaration
1560 Method method = (Method) $1;
1561 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1563 | property_declaration
1565 | type_spec_declaration
1568 * This is only included so we can flag error 575:
1569 * destructors only allowed on class types
1571 //| destructor_declaration
1575 : EVENT identifier AS type opt_implement_clause logical_end_of_line
1577 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1579 Event e = new Event ((Expression) $4, var.identifier,
1580 null, current_modifiers, null, null,
1581 current_attributes, (ArrayList) $5,
1584 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1586 | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1588 string delName = null;
1591 delName = (string) $2;
1592 delName = delName + "EventHandler";
1593 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1594 (current_container, TypeManager.system_void_expr,
1595 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1596 (Attributes) current_attributes, lexer.Location);
1598 del.Namespace = current_namespace;
1599 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1601 ArrayList impls = (ArrayList) $4;
1602 if (impls.Count > 1) {
1603 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1604 "' can not be implemented with Event '" +
1605 (string) $2 + "', since it's delegate type does not match " +
1606 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1607 Report.Error (31407, lexer.Location, expstr);
1609 Expression impl = (Expression) impls[0];
1610 delName = impl.ToString();
1611 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1612 delName = delName + "EventHandler";
1615 Event e = new Event (DecomposeQI (delName, lexer.Location),
1617 null, current_modifiers, null, null,
1618 current_attributes, (ArrayList) $4,
1621 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1626 : ENUM identifier opt_type_spec logical_end_of_line
1627 opt_enum_member_declarations
1629 Location enum_location = lexer.Location;
1630 string full_name = MakeName ((string) $2);
1631 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1632 ArrayList enum_members = (ArrayList) $5;
1634 if (enum_members.Count == 0)
1635 Report.Error (30280, enum_location,
1636 "Enum can not have empty member list");
1638 // Module members are static by default, but enums *can't* be declared static
1639 // so we must fix it if mbas was the one actually responsible for this
1640 // instead of triggering an error.
1641 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1642 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1644 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1645 (int) current_modifiers, full_name,
1646 (Attributes) current_attributes, enum_location);
1648 foreach (VariableDeclaration ev in enum_members) {
1649 Location loc = (Location) ev.Location;
1651 CheckDef (e.AddEnumMember (ev.identifier,
1652 (Expression) ev.expression_or_array_initializer,
1653 loc, ev.OptAttributes), ev.identifier, loc);
1656 e.Namespace = current_namespace;
1658 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1659 RootContext.Tree.RecordDecl (full_name, e);
1662 END ENUM logical_end_of_line
1665 opt_enum_member_declarations
1666 : /* empty */ { $$ = new ArrayList (); }
1667 | enum_member_declarations { $$ = $1; }
1670 enum_member_declarations
1671 : enum_member_declaration
1673 ArrayList l = new ArrayList ();
1678 | enum_member_declarations enum_member_declaration
1680 ArrayList l = (ArrayList) $1;
1688 enum_member_declaration
1689 : opt_attributes identifier logical_end_of_line
1691 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1693 | opt_attributes identifier
1695 $$ = lexer.Location;
1697 ASSIGN expression logical_end_of_line
1699 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1703 interface_declaration
1704 : INTERFACE identifier logical_end_of_line
1706 Interface new_interface;
1707 string full_interface_name = MakeName ((string) $2);
1709 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1710 (Attributes) current_attributes, lexer.Location);
1711 if (current_interface != null) {
1712 Location l = lexer.Location;
1713 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1715 current_interface = new_interface;
1716 new_interface.Namespace = current_namespace;
1717 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1722 Interface new_interface = (Interface) current_interface;
1725 new_interface.Bases = (ArrayList) $5;
1727 current_interface = null;
1728 CheckDef (current_container.AddInterface (new_interface),
1729 new_interface.Name, new_interface.Location);
1732 END INTERFACE logical_end_of_line
1736 : /* empty */ { $$ = null; }
1742 | interface_bases interface_base
1744 ArrayList bases = (ArrayList) $1;
1745 bases.AddRange ((ArrayList) $2);
1751 : INHERITS type_list logical_end_of_line { $$ = $2; }
1755 : opt_interface_member_declarations
1758 opt_interface_member_declarations
1760 | interface_member_declarations
1763 interface_member_declarations
1764 : interface_member_declaration
1765 | interface_member_declarations interface_member_declaration
1768 interface_member_declaration
1772 current_attributes = (Attributes) $1;
1773 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
1775 interface_member_declarator
1781 interface_member_declarator
1782 : interface_method_declaration
1784 Method m = (Method) $1;
1785 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1787 | interface_property_declaration
1788 | interface_event_declaration
1791 interface_method_declaration
1792 : SUB identifier opt_params logical_end_of_line
1794 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1795 (Parameters) $3, current_attributes, null, lexer.Location);
1799 | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
1801 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.
1802 system_object_expr : (Expression) $3 ) : (Expression) $5;
1804 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1805 (string) $2,(Parameters) $4, current_attributes, null,
1812 interface_property_declaration
1813 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1815 Expression ftype = ($5 == null) ? (($3 == null) ?
1816 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1818 current_local_parameters = (Parameters) $4;
1819 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1820 get_parameters = current_local_parameters.Copy (lexer.Location);
1821 set_parameters = current_local_parameters.Copy (lexer.Location);
1823 Parameter implicit_value_parameter = new Parameter (
1824 ftype, "Value", Parameter.Modifier.NONE, null);
1826 set_parameters.AppendParameter (implicit_value_parameter);
1830 get_parameters = Parameters.EmptyReadOnlyParameters;
1831 set_parameters = new Parameters (null, null ,lexer.Location);
1833 Parameter implicit_value_parameter = new Parameter (
1834 ftype, "Value", Parameter.Modifier.NONE, null);
1836 set_parameters.AppendParameter (implicit_value_parameter);
1838 lexer.PropertyParsing = true;
1840 Accessor get_block = new Accessor (null, null);
1841 Accessor set_block = new Accessor (null, null);
1843 Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
1844 get_block, set_block, current_attributes, lexer.Location,
1845 null, get_parameters, set_parameters, null);
1847 CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
1849 get_implicit_value_parameter_type = null;
1850 set_implicit_value_parameter_type = null;
1851 get_parameters = null;
1852 set_parameters = null;
1853 current_local_parameters = null;
1857 interface_event_declaration
1858 : EVENT identifier AS type logical_end_of_line
1860 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1862 Event e = new Event ((Expression) $4, var.identifier,
1863 null, current_modifiers, null, null,
1864 current_attributes, lexer.Location);
1866 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1869 | EVENT identifier opt_params logical_end_of_line
1871 string delName = (string) $2;
1872 delName = delName + "EventHandler";
1873 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
1874 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1875 (current_container, TypeManager.system_void_expr,
1876 (int) delModifiers, MakeName(delName), (Parameters) $3,
1877 (Attributes) current_attributes, lexer.Location);
1879 del.Namespace = current_namespace;
1880 CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
1882 Event e = new Event (DecomposeQI (delName, lexer.Location),
1884 null, current_modifiers, null, null,
1885 current_attributes, lexer.Location);
1887 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1891 property_declaration
1892 : abstract_propery_declaration
1893 | non_abstract_propery_declaration
1896 abstract_propery_declaration
1897 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1899 Expression ftype = ($6 == null) ? (($4 == null) ?
1900 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
1902 if (current_container is Module)
1903 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1905 if (current_container is Struct)
1906 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1908 current_modifiers |= Modifiers.ABSTRACT;
1910 current_local_parameters = (Parameters) $5;
1911 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1912 get_parameters = current_local_parameters.Copy (lexer.Location);
1913 set_parameters = current_local_parameters.Copy (lexer.Location);
1915 Parameter implicit_value_parameter = new Parameter (
1916 ftype, "Value", Parameter.Modifier.NONE, null);
1918 set_parameters.AppendParameter (implicit_value_parameter);
1922 get_parameters = Parameters.EmptyReadOnlyParameters;
1923 set_parameters = new Parameters (null, null ,lexer.Location);
1925 Parameter implicit_value_parameter = new Parameter (
1926 ftype, "Value", Parameter.Modifier.NONE, null);
1928 set_parameters.AppendParameter (implicit_value_parameter);
1930 lexer.PropertyParsing = true;
1932 Accessor get_block = new Accessor (null, null);
1933 Accessor set_block = new Accessor (null, null);
1935 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1936 get_block, set_block, current_attributes, lexer.Location,
1937 null, get_parameters, set_parameters, null);
1939 if (!(current_container is Class))
1940 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1942 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1944 get_implicit_value_parameter_type = null;
1945 set_implicit_value_parameter_type = null;
1946 get_parameters = null;
1947 set_parameters = null;
1948 current_local_parameters = null;
1953 non_abstract_propery_declaration
1954 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
1956 get_implicit_value_parameter_type =
1957 ($5 == null) ? (($3 == null) ?
1958 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1959 get_implicit_value_parameter_name = (string) $2;
1961 current_local_parameters = (Parameters) $4;
1962 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1963 get_parameters = current_local_parameters.Copy (lexer.Location);
1964 set_parameters = current_local_parameters.Copy (lexer.Location);
1968 get_parameters = Parameters.EmptyReadOnlyParameters;
1969 set_parameters = new Parameters (null, null ,lexer.Location);
1971 lexer.PropertyParsing = true;
1973 $$ = lexer.Location;
1975 accessor_declarations
1976 END PROPERTY logical_end_of_line
1978 lexer.PropertyParsing = false;
1981 Pair pair = (Pair) $9;
1983 Accessor get_block = null;
1984 Accessor set_block = null;
1986 if (pair.First != null){
1987 get_block = (Accessor) pair.First;
1990 if (pair.Second != null) {
1991 set_block = (Accessor) pair.Second;
1994 Location loc = lexer.Location;
1996 // Structure members are Public by default
1997 if ((current_container is Struct) && (current_modifiers == 0))
1998 current_modifiers = Modifiers.PUBLIC;
2000 prop = new Property ((Expression) get_implicit_value_parameter_type,
2001 (string) $2, current_modifiers, get_block, set_block,
2002 current_attributes, loc, set_implicit_value_parameter_name,
2003 get_parameters, set_parameters, (ArrayList) $6);
2005 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
2006 get_implicit_value_parameter_type = null;
2007 set_implicit_value_parameter_type = null;
2008 get_parameters = null;
2009 set_parameters = null;
2010 current_local_parameters = null;
2014 opt_property_parameters
2017 $$ = Parameters.EmptyReadOnlyParameters;
2019 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2025 opt_implement_clause
2030 | IMPLEMENTS implement_clause_list
2036 implement_clause_list
2037 : qualified_identifier
2039 ArrayList impl_list = new ArrayList ();
2040 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
2043 | implement_clause_list COMMA qualified_identifier
2045 ArrayList impl_list = (ArrayList) $1;
2046 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
2052 accessor_declarations
2053 : get_accessor_declaration opt_set_accessor_declaration
2055 $$ = new Pair ($1, $2);
2057 | set_accessor_declaration opt_get_accessor_declaration
2059 $$ = new Pair ($2, $1);
2063 opt_get_accessor_declaration
2064 : /* empty */ { $$ = null; }
2065 | get_accessor_declaration
2068 opt_set_accessor_declaration
2069 : /* empty */ { $$ = null; }
2070 | set_accessor_declaration
2073 get_accessor_declaration
2074 : opt_attributes GET logical_end_of_line
2076 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
2077 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
2079 current_local_parameters = get_parameters;
2081 lexer.PropertyParsing = false;
2084 // Add local var declaration
2086 ArrayList retval = new ArrayList ();
2087 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
2088 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
2091 END GET logical_end_of_line
2093 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2094 current_local_parameters = null;
2095 lexer.PropertyParsing = true;
2099 set_accessor_declaration
2100 : opt_attributes SET opt_set_parameter logical_end_of_line
2102 if ((current_modifiers & Modifiers.READONLY) != 0)
2103 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
2105 Parameter implicit_value_parameter = new Parameter (
2106 set_implicit_value_parameter_type,
2107 set_implicit_value_parameter_name,
2108 Parameter.Modifier.NONE, null);
2110 current_local_parameters = set_parameters;
2111 current_local_parameters.AppendParameter (implicit_value_parameter);
2114 lexer.PropertyParsing = false;
2117 END SET logical_end_of_line
2119 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2120 current_local_parameters = null;
2121 lexer.PropertyParsing = true;
2128 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2129 set_implicit_value_parameter_name = "Value";
2131 |OPEN_PARENS CLOSE_PARENS
2133 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2134 set_implicit_value_parameter_name = "Value";
2136 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2138 Parameter.Modifier pm = (Parameter.Modifier)$2;
2139 if ((pm | Parameter.Modifier.VAL) != 0)
2140 Report.Error (31065,
2142 "Set cannot have a paremeter modifier other than 'ByVal'");
2144 set_implicit_value_parameter_type = (Expression) $4;
2146 if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
2147 Report.Error (31064,
2149 "Set value parameter type can not be different from property type");
2152 set_implicit_value_parameter_name = (string) $3;
2154 set_implicit_value_parameter_name = "Value";
2160 variable_declarators logical_end_of_line
2162 int mod = (int) current_modifiers;
2164 VariableDeclaration.FixupTypes ((ArrayList) $2);
2165 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2167 if (current_container is Module)
2168 mod = mod | Modifiers.STATIC;
2170 // Structure members are Public by default
2171 if ((current_container is Struct) && (mod == 0))
2172 mod = Modifiers.PUBLIC;
2174 if ((mod & Modifiers.Accessibility) == 0)
2175 mod |= Modifiers.PRIVATE;
2177 foreach (VariableDeclaration var in (ArrayList) $2){
2178 Location l = var.Location;
2179 Field field = new Field (var.type, mod, var.identifier,
2180 var.expression_or_array_initializer,
2181 (Attributes) null, l);
2183 CheckDef (current_container.AddField (field), field.Name, l);
2188 withevents_declaration
2189 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2191 // Module members are static by default, but delegates *can't* be declared static
2192 // so we must fix it, if mbas was the one actually responsible for this
2193 // instead of triggering an error.
2194 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2195 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2197 /* WithEvents Fields must be resolved into properties
2198 with a bit of magic behind the scenes */
2200 VariableDeclaration.FixupTypes ((ArrayList) $3);
2202 foreach (VariableDeclaration var in (ArrayList) $3) {
2203 // 1 - We create a private field
2204 Location l = var.Location;
2206 if ((current_modifiers & Modifiers.STATIC) > 0)
2207 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2209 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2210 var.expression_or_array_initializer,
2211 (Attributes) null, l);
2213 CheckDef (current_container.AddField (field), field.Name, l);
2215 // 2 - Public property
2217 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2218 field, (int) current_modifiers,
2219 (Attributes) current_attributes, l);
2221 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2231 delegate_declaration
2233 identifier OPEN_PARENS
2234 opt_formal_parameter_list
2238 Location l = lexer.Location;
2239 // Module members are static by default, but delegates *can't* be declared static
2240 // so we must fix it, if mbas was the one actually responsible for this
2241 // instead of triggering an error.
2242 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2243 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2245 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2246 TypeManager.system_void_expr,
2247 (int) current_modifiers,
2248 MakeName ((string) $3), (Parameters) $5,
2249 (Attributes) current_attributes, l);
2251 del.Namespace = current_namespace;
2252 CheckDef (current_container.AddDelegate (del), del.Name, l);
2255 identifier OPEN_PARENS
2256 opt_formal_parameter_list
2257 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2259 Location l = lexer.Location;
2261 // Module members are static by default, but delegates *can't* be declared static
2262 // so we must fix it, if mbas was the one actually responsible for this
2263 // instead of triggering an error.
2264 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2265 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2267 Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2269 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2271 ftype, (int) current_modifiers, MakeName ((string) $3),
2272 (Parameters) $5, (Attributes) current_attributes, l);
2274 del.Namespace = current_namespace;
2275 CheckDef (current_container.AddDelegate (del), del.Name, l);
2280 : /* empty */ { $$ = null; }
2281 | HANDLES evt_handler { $$ = $2; }
2285 : qualified_identifier
2287 $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);
2293 | ME DOT qualified_identifier
2295 $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);
2297 /*| MYBASE DOT qualified_identifier
2299 // FIXME: this is blatantly wrong and crash-prone
2300 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2304 constructor_declaration
2305 : SUB NEW opt_params logical_end_of_line
2307 current_local_parameters = (Parameters) $3;
2309 oob_stack.Push (lexer.Location);
2311 Location l = (Location) oob_stack.Pop ();
2312 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2317 Constructor c = (Constructor) $1;
2318 c.Block = (Block) end_block();
2319 c.ModFlags = (int) current_modifiers;
2320 c.OptAttributes = current_attributes;
2322 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2324 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2325 current_local_parameters = null;
2327 END SUB logical_end_of_line
2330 opt_formal_parameter_list
2333 $$ = Parameters.EmptyReadOnlyParameters;
2335 | formal_parameter_list
2338 //Parameter p = ((Parameters) $1).FixedParameters[0];
2342 formal_parameter_list
2345 ArrayList pars_list = (ArrayList) $1;
2346 Parameter [] pars = null;
2347 Parameter array_parameter = null;
2348 int non_array_count = pars_list.Count;
2349 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2350 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2351 non_array_count = pars_list.Count - 1;
2353 foreach (Parameter par in pars_list)
2354 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2355 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2356 non_array_count = 0;
2357 array_parameter = null;
2360 if (non_array_count > 0) {
2361 pars = new Parameter [non_array_count];
2362 pars_list.CopyTo (0, pars, 0, non_array_count);
2364 $$ = new Parameters (pars, array_parameter, lexer.Location);
2371 ArrayList pars = new ArrayList ();
2376 | parameters COMMA parameter
2378 ArrayList pars = (ArrayList) $1;
2387 opt_parameter_modifier
2388 identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2390 Parameter.Modifier pm = (Parameter.Modifier)$2;
2391 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2394 if (opt_parm && ($7 == null))
2395 Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
2397 if (!opt_parm && ($7 != null))
2398 Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
2400 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2401 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2402 Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
2405 if ((pm & Parameter.Modifier.REF) !=0)
2406 pm |= Parameter.Modifier.ISBYREF;
2408 if ($4 != null && $6 != null && $4 != $6)
2409 Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2411 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2413 string t = ptype.ToString ();
2414 if (t.IndexOf('[') >= 0)
2415 Report.Error (31087, lexer.Location, "Array types specified in too many places");
2417 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
2419 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2420 Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
2421 $$ = new Parameter (ptype, (string) $3, pm,
2422 (Attributes) $1, (Expression) $7, opt_parm);
2426 opt_parameter_modifier
2427 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2428 | parameter_modifiers { $$ = $1; }
2432 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2433 | parameter_modifier { $$ = $1; }
2437 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2438 | BYVAL { $$ = Parameter.Modifier.VAL; }
2439 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2440 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2445 | statement_list end_of_stmt
2450 | statement_list end_of_stmt statement
2454 : declaration_statement
2456 if ($1 != null && (Block) $1 != current_block){
2457 current_block.AddStatement ((Statement) $1);
2458 current_block = (Block) $1;
2461 | embedded_statement
2463 Statement s = (Statement) $1;
2465 current_block.AddStatement ((Statement) $1);
2468 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2470 AddHandler ((Expression) $2, (Expression) $5);
2472 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2474 RemoveHandler ((Expression) $2, (Expression) $5);
2476 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2478 RaiseEvent ((string) $2, (ArrayList) $3);
2480 /* | array_handling_statement */
2481 /* | empty_statement */
2484 Statement s = (Statement) $1;
2486 current_block.AddStatement ((Statement) $1);
2490 opt_raise_event_args
2491 : /* empty */ { $$ = null; }
2492 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2509 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2511 if (!current_block.AddLabel ((string) $1, labeled)){
2512 Location l = lexer.Location;
2513 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2515 current_block.AddStatement (labeled);
2519 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2521 if (!current_block.AddLabel ((string) $1, labeled)){
2522 Location l = lexer.Location;
2523 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2525 current_block.AddStatement (labeled);
2531 : expression_statement
2532 | selection_statement
2533 | iteration_statement
2535 | synclock_statement
2537 | array_handling_statement
2543 $$ = new EmptyStatement ();
2549 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2551 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2552 Expression e = (Expression) $2;
2559 Block b = end_block();
2566 array_handling_statement
2572 : REDIM opt_preserve redim_clauses
2574 ArrayList list = (ArrayList) $3;
2575 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2582 : /* empty */ { $$ = false; }
2583 | PRESERVE { $$ = true; }
2589 ArrayList clauses = new ArrayList ();
2594 | redim_clauses COMMA redim_clause
2596 ArrayList clauses = (ArrayList) ($1);
2604 : invocation_expression
2606 Invocation i = (Invocation) $1;
2607 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2613 : ERASE erase_clauses
2615 ArrayList list = (ArrayList) $2;
2616 foreach(Expression e in list)
2618 Erase r = new Erase (e, lexer.Location);
2627 ArrayList clauses = new ArrayList ();
2632 | erase_clauses COMMA erase_clause
2634 ArrayList clauses = (ArrayList) ($1);
2642 : primary_expression
2647 | continue_statement
2648 | */return_statement
2658 $$ = new Goto (current_block, (string) $2, lexer.Location);
2663 : THROW opt_expression
2665 $$ = new Throw ((Expression) $2, lexer.Location);
2672 $$ = new Exit ((ExitType)$2, lexer.Location);
2677 : DO { $$ = ExitType.DO; }
2678 | FOR { $$ = ExitType.FOR; }
2679 | WHILE { $$ = ExitType.WHILE; }
2680 | SELECT { $$ = ExitType.SELECT; }
2681 | SUB { $$ = ExitType.SUB; }
2682 | FUNCTION { $$ = ExitType.FUNCTION; }
2683 | PROPERTY { $$ = ExitType.PROPERTY; }
2684 | TRY { $$ = ExitType.TRY; }
2687 : RETURN opt_expression
2689 $$ = new Return ((Expression) $2, lexer.Location);
2701 : FOR EACH identifier opt_type_spec IN
2703 oob_stack.Push (lexer.Location);
2705 expression end_of_stmt
2707 Location l = lexer.Location;
2708 LocalVariableReference v = null;
2714 VariableDeclaration decl = new VariableDeclaration ((string) $3,
2715 (Expression) $4, null, lexer.Location, null);
2717 vi = current_block.AddVariable (
2718 (Expression) $4, decl.identifier, current_local_parameters, decl.Location);
2721 if (decl.expression_or_array_initializer is Expression)
2722 expr = (Expression) decl.expression_or_array_initializer;
2723 else if (decl.expression_or_array_initializer == null)
2727 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
2728 expr = new ArrayCreation ((Expression) $4, "", init, decl.Location);
2731 v = new LocalVariableReference (current_block, decl.identifier, l);
2735 Assign a = new Assign (v, expr, decl.Location);
2736 current_block.AddStatement (new StatementExpression (a, lexer.Location));
2741 vi = current_block.GetVariableInfo ((string) $3);
2744 // Get a reference to this variable.
2745 v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
2748 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2757 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2758 Block foreach_block = end_block();
2759 Location l = (Location) oob_stack.Pop ();
2763 f = new Foreach (null, v, (Expression) $7, foreach_block, l);
2767 current_block.AddStatement (f);
2778 if (!UseExtendedSyntax)
2784 if (iterator_container == null){
2785 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2788 iterator_container.SetYields ();
2789 $$ = new Yield ((Expression) $2, lexer.Location);
2794 if (!UseExtendedSyntax)
2800 if (iterator_container == null){
2801 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2804 iterator_container.SetYields ();
2805 $$ = new YieldBreak (lexer.Location);
2811 : SYNCLOCK expression end_of_stmt
2818 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2835 tmp_catch_clauses = (ArrayList) $5;
2844 ArrayList s = new ArrayList ();
2846 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2853 // Now s contains the list of specific catch clauses
2854 // and g contains the general one.
2855 Block b = end_block();
2857 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2864 tmp_block = end_block();
2874 ArrayList s = new ArrayList ();
2875 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2877 if (catch_list != null){
2878 foreach (Catch cc in catch_list) {
2886 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2892 : /* empty */ { $$ = null; }
2899 ArrayList l = new ArrayList ();
2904 | catch_clauses catch_clause
2906 ArrayList l = (ArrayList) $1;
2914 : /* empty */ { $$ = null; }
2919 : /* empty */ { $$ = null; }
2920 | WHEN boolean_expression { $$ = $2; }
2924 : CATCH opt_catch_args opt_when end_of_stmt
2926 Expression type = null;
2930 DictionaryEntry cc = (DictionaryEntry) $2;
2931 type = (Expression) cc.Key;
2932 id = (string) cc.Value;
2935 ArrayList one = new ArrayList ();
2936 Location loc = lexer.Location;
2938 one.Add (new VariableDeclaration (id, type, loc));
2941 current_block = new Block (current_block);
2942 Block b = declare_local_variables (type, one, loc);
2947 opt_statement_list {
2948 Expression type = null;
2950 Block b_catch = current_block;
2953 DictionaryEntry cc = (DictionaryEntry) $2;
2954 type = (Expression) cc.Key;
2955 id = (string) cc.Value;
2959 // FIXME: I can change this for an assignment.
2961 while (current_block != (Block) $1)
2962 current_block = current_block.Parent;
2965 $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, lexer.Location);
2970 : /* empty */ { $$ = null; }
2975 : identifier AS type
2977 $$ = new DictionaryEntry ($3, $1);
2983 : DO opt_do_construct end_of_stmt
2986 oob_stack.Push (lexer.Location);
2989 LOOP opt_do_construct
2991 Expression t_before = (Expression) $2;
2992 Expression t_after = (Expression) $7;
2995 if ((t_before != null) && (t_after != null))
2996 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2998 if ((t_before == null) && (t_after == null))
2999 t = new BoolLiteral (true);
3001 t = (t_before != null) ? t_before : t_after;
3003 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
3005 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
3006 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
3007 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
3009 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
3014 : /* empty */ { $$ = null; }
3015 | while_or_until boolean_expression
3017 do_type = (DoOptions)$1;
3018 $$ = (Expression) $2;
3023 : WHILE { $$ = DoOptions.WHILE; }
3024 | UNTIL { $$ = DoOptions.UNTIL; }
3031 oob_stack.Push (lexer.Location);
3033 boolean_expression end_of_stmt
3037 Location l = (Location) oob_stack.Pop ();
3038 Block b = end_block();
3039 Expression e = (Expression) $3;
3040 $$ = new While ((Expression) e, (Statement) b, l);
3045 : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
3050 ArrayList VarDeclaration = new ArrayList ();
3051 VarDeclaration.Add (new VariableDeclaration ((string) $2,
3052 (Expression) $3, null, lexer.Location, null));
3054 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
3055 Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3058 oob_stack.Push (lexer.Location);
3064 Block inner_statement = end_block();
3065 Location l = (Location) oob_stack.Pop ();
3066 Expression for_var = (Expression) DecomposeQI ((string)$2, l);
3068 Expression assign_expr = new Assign (for_var, (Expression) $5, l);
3069 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
3070 for_var, (Expression) $7, l);
3071 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
3072 for_var, (Expression) $8, l), l);
3074 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
3075 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
3077 For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
3080 current_block.AddStatement (f);
3089 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
3090 | STEP expression { $$ = $2; }
3099 : if_statement_open opt_then if_statement_rest
3103 | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
3107 Location l = (Location) oob_stack.Pop ();
3108 tmp_expr = (Expression)expr_stack.Pop();
3109 $$ = new If ((Expression) tmp_expr, end_block(), l);
3113 Location l = (Location) oob_stack.Pop ();
3114 tmp_expr = (Expression)expr_stack.Pop();
3115 tmp_block = (Block) tmp_blocks.Pop ();
3116 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3119 | if_statement_open THEN else_pre_embedded_statement
3121 Location l = (Location) oob_stack.Pop ();
3122 tmp_expr = (Expression)expr_stack.Pop();
3123 tmp_block = (Block) tmp_blocks.Pop ();
3124 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3128 pre_embedded_statement
3129 : embedded_statement
3131 Statement s = (Statement) $1;
3133 current_block.AddStatement ((Statement) $1);
3137 opt_else_pre_embedded_statement
3139 | else_pre_embedded_statement
3142 else_pre_embedded_statement
3145 Block bl = end_block();
3146 tmp_blocks.Push(bl);
3150 | ELSE embedded_statement
3152 Block bl = end_block();
3153 tmp_blocks.Push(bl);
3156 Statement s = (Statement) $2;
3157 current_block.AddStatement ((Statement) $2);
3162 : IF boolean_expression
3164 oob_stack.Push (lexer.Location);
3166 tmp_expr = (Expression) $2;
3167 expr_stack.Push(tmp_expr);
3181 Location l = (Location) oob_stack.Pop ();
3182 Expression expr = (Expression)expr_stack.Pop();
3183 $$ = new If ((Expression) expr, (Statement) end_block(), l);
3189 Block bl = end_block();
3190 tmp_blocks.Push(bl);
3196 Location l = (Location) oob_stack.Pop ();
3197 tmp_expr = (Expression)expr_stack.Pop();
3198 tmp_block = (Block) tmp_blocks.Pop();
3199 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
3203 ELSEIF boolean_expression opt_then
3205 tmp_expr = (Expression) $4;
3206 expr_stack.Push(tmp_expr);
3207 tmp_block = end_block();
3208 tmp_blocks.Push(tmp_block);
3211 else_if_statement_rest
3213 Statement stmt = (Statement) statement_stack.Pop();
3214 Block bl = (Block) tmp_blocks.Pop();
3215 Expression expr = (Expression)expr_stack.Pop();
3216 Location l = (Location) oob_stack.Pop ();
3217 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3222 else_if_statement_rest
3227 Location l = (Location) oob_stack.Pop ();
3229 Expression expr = (Expression)expr_stack.Pop();
3230 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3231 statement_stack.Push(stmt);
3237 Block bl = end_block();
3238 tmp_blocks.Push(bl);
3244 Location l = (Location) oob_stack.Pop ();
3246 Expression expr = (Expression)expr_stack.Pop();
3247 Block bl = (Block)tmp_blocks.Pop();
3248 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3249 statement_stack.Push(stmt);
3253 ELSEIF boolean_expression opt_then
3255 expr_stack.Push((Expression) $4);
3256 Block bl = end_block();
3257 tmp_blocks.Push(bl);
3260 else_if_statement_rest
3262 Location l = (Location) oob_stack.Pop ();
3264 Statement tmp_stmt = (Statement)statement_stack.Pop();
3265 Block bl = (Block) tmp_blocks.Pop();
3266 Expression expr = (Expression)expr_stack.Pop();
3267 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3268 statement_stack.Push(stmt);
3273 : SELECT opt_case expression end_of_stmt
3275 oob_stack.Push (lexer.Location);
3276 switch_stack.Push (current_block);
3281 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3282 current_block = (Block) switch_stack.Pop ();
3287 : /* empty */ { $$ = null; }
3288 | case_sections { $$ = $1; }
3292 : case_sections case_section
3294 ArrayList sections = (ArrayList) $1;
3301 ArrayList sections = new ArrayList ();
3315 : CASE case_clauses ends
3321 //Block topmost = current_block;
3322 Block topmost = end_block();
3324 while (topmost.Implicit)
3325 topmost = topmost.Parent;
3327 // FIXME: This is a horrible hack which MUST go
3328 topmost.statements.Add (new Break (lexer.Location));
3329 $$ = new SwitchSection ((ArrayList) $2, topmost);
3332 /* FIXME: we should somehow flag an error
3333 (BC30321 'Case' cannot follow a 'Case Else'
3334 in the same 'Select' statement.)
3335 if Case Else is not the last of the Case clauses
3342 //Block topmost = current_block;
3343 Block topmost = end_block();
3345 while (topmost.Implicit)
3346 topmost = topmost.Parent;
3348 // FIXME: This is a horrible hack which MUST go
3349 topmost.statements.Add (new Break (lexer.Location));
3351 ArrayList a = new ArrayList();
3352 a.Add (new SwitchLabel (null, lexer.Location));
3353 $$ = new SwitchSection ((ArrayList) a, topmost);
3360 ArrayList labels = new ArrayList ();
3365 | case_clauses COMMA case_clause
3367 ArrayList labels = (ArrayList) ($1);
3375 : opt_is comparison_operator expression
3378 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3400 expression_statement
3401 : statement_expression
3408 statement_expression
3409 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3410 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3411 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3414 object_creation_expression
3415 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3417 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3421 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3425 array_creation_expression
3426 : object_creation_expression opt_rank_specifiers array_initializer
3429 ArrayList dims = new ArrayList();
3431 if (n.Arguments != null) {
3432 foreach (Argument a in n.Arguments) {
3437 Expression atype = n.RequestedType;
3440 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
3442 ArrayList init = (ArrayList) $3;
3443 if (init.Count == 0)
3446 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3447 VariableDeclaration.VBFixIndexList (ref dims);
3448 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3452 string rank = VariableDeclaration.BuildRank (dims);
3453 $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location);
3455 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3460 : object_creation_expression
3461 | array_creation_expression
3464 declaration_statement
3465 : local_variable_declaration
3468 DictionaryEntry de = (DictionaryEntry) $1;
3470 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3473 | local_constant_declaration
3476 DictionaryEntry de = (DictionaryEntry) $1;
3478 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3483 local_variable_declaration
3484 : DIM variable_declarators
3486 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3491 local_constant_declaration
3492 : CONST constant_declarators
3495 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3501 constant_declarators
3502 : constant_declarator
3504 ArrayList decl = new ArrayList ();
3510 | constant_declarators COMMA constant_declarator
3512 ArrayList decls = (ArrayList) $1;
3521 : variable_name opt_type_decl opt_variable_initializer
3523 VarName vname = (VarName) $1;
3524 string varname = (string) vname.Name;
3525 current_rank_specifiers = (ArrayList) vname.Rank;
3526 object varinit = $3;
3527 ArrayList a_dims = null;
3529 if (varinit == null)
3531 30438, lexer.Location, "Constant should have a value"
3534 if (vname.Type != null && $2 != null)
3536 30302, lexer.Location,
3537 "Type character cannot be used with explicit type declaration" );
3539 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3541 if (current_rank_specifiers != null)
3543 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3547 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3551 variable_declarators
3552 : variable_declarator
3554 ArrayList decl = new ArrayList ();
3555 decl.AddRange ((ArrayList) $1);
3558 | variable_declarators COMMA variable_declarator
3560 ArrayList decls = (ArrayList) $1;
3561 decls.AddRange ((ArrayList) $3);
3567 : variable_names opt_type_decl opt_variable_initializer
3569 ArrayList names = (ArrayList) $1;
3570 object varinit = $3;
3571 ArrayList VarDeclarations = new ArrayList();
3573 ArrayList a_dims = null;
3575 if ((names.Count > 1) && (varinit != null))
3577 30671, lexer.Location,
3578 "Multiple variables with single type can not have " +
3579 "a explicit initialization" );
3582 foreach (VarName vname in names)
3584 string varname = (string) vname.Name;
3585 current_rank_specifiers = (ArrayList) vname.Rank;
3589 if(vname.Type != null && $2 != null)
3591 30302, lexer.Location,
3592 "Type character cannot be used with explicit type declaration" );
3594 // Some checking is required for particularly weird declarations
3595 // like Dim a As Integer(,)
3597 vartype = (Expression) ((Pair) $2).First;
3599 /*if ($3 != null && $3 is ArrayList)
3600 Report.Error (205, "End of statement expected.");*/
3602 ArrayList args = (ArrayList) ((Pair) $2).Second;
3603 if (current_rank_specifiers != null)
3604 Report.Error (31087, lexer.Location,
3605 "Array types specified in too many places");
3607 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3608 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3610 current_rank_specifiers = new ArrayList ();
3611 current_rank_specifiers.Add (args);
3614 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3616 // if the variable is an array with explicit bound
3617 // and having explicit initialization throw exception
3618 if (current_rank_specifiers != null && varinit != null)
3620 bool broken = false;
3621 foreach (ArrayList exprs in current_rank_specifiers)
3623 foreach (Expression expr in exprs)
3625 if (!((Expression)expr is EmptyExpression ))
3628 30672, lexer.Location,
3629 "Array declared with explicit bound " +
3630 " can not have explicit initialization");
3641 Check for a declaration like Dim a(2) or Dim a(2,3)
3642 If this is the case, we must generate an ArrayCreationExpression
3643 and, in case, add the initializer after the array has been created.
3645 if (VariableDeclaration.IsArrayDecl (this)) {
3646 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3647 a_dims = (ArrayList) current_rank_specifiers;
3648 VariableDeclaration.VBFixIndexLists (ref a_dims);
3649 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3651 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
3654 if (vartype is New) {
3655 if (varinit != null) {
3656 Report.Error (30205, lexer.Location, "End of statement expected");
3662 vartype = ((New)vartype).RequestedType;
3665 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3667 $$ = VarDeclarations;
3674 ArrayList list = new ArrayList ();
3678 | variable_names COMMA variable_name
3680 ArrayList list = (ArrayList) $1;
3687 : identifier opt_type_character opt_array_name_modifier
3689 $$ = new VarName ($1, $2, $3);
3700 $$ = (Expression) $2;
3706 | AS type rank_specifiers
3708 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
3713 : opt_type_with_ranks
3719 New n = new New ((Expression)$3, null, lexer.Location);
3720 $$ = (Expression) n;
3722 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3724 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3725 $$ = (Expression) n;
3727 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3729 ArrayList args = new ArrayList();
3730 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3733 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3734 $$ = (Expression) n;
3738 opt_array_name_modifier
3739 : /* empty */ { $$ = null; }
3740 | array_type_modifier { $$ = $1; }
3744 : rank_specifiers { $$ = $1; }
3747 opt_variable_initializer
3748 : /* empty */ { $$ = null; }
3749 | ASSIGN variable_initializer { $$ = $2; }
3752 variable_initializer
3765 : OPEN_BRACE CLOSE_BRACE
3767 ArrayList list = new ArrayList ();
3770 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3772 $$ = (ArrayList) $2;
3776 variable_initializer_list
3777 : variable_initializer
3779 ArrayList list = new ArrayList ();
3783 | variable_initializer_list COMMA variable_initializer
3785 ArrayList list = (ArrayList) $1;
3806 ArrayList rs = new ArrayList();
3810 | rank_specifiers rank_specifier
3812 ArrayList rs = (ArrayList) $1;
3819 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
3828 ArrayList ds = new ArrayList();
3829 ds.Add (new EmptyExpression());
3834 ArrayList ds = new ArrayList();
3835 ds.Add ((Expression) $1);
3838 | opt_dim_specifiers COMMA expression
3840 ArrayList ds = (ArrayList) $1;
3841 ds.Add ((Expression) $3);
3844 | opt_dim_specifiers COMMA
3846 ArrayList ds = (ArrayList) $1;
3847 ds.Add (new EmptyExpression());
3857 | parenthesized_expression
3860 | qualified_identifier
3862 string name = (string) $1;
3863 $$ = DecomposeQI (name, lexer.Location);
3865 | get_type_expression
3867 | invocation_expression
3877 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3878 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3879 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3880 | NOTHING { $$ = NullLiteral.Null; }
3884 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3885 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3886 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3891 object v = lexer.Value;
3894 $$ = new IntLiteral ((Int32)v);
3895 else if (v is short)
3896 $$ = new ShortLiteral ((Int16)v);
3898 $$ = new LongLiteral ((Int64)v);
3900 Console.WriteLine ("OOPS. Unexpected result from scanner");
3906 : TRUE { $$ = new BoolLiteral (true); }
3907 | FALSE { $$ = new BoolLiteral (false); }
3910 parenthesized_expression
3911 : OPEN_PARENS expression CLOSE_PARENS
3916 : primary_expression DOT identifier
3919 string id_name = (string)$3;
3920 if (id_name.ToUpper() == "NEW")
3922 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3926 if (with_stack.Count > 0) {
3927 Expression e = (Expression) with_stack.Peek();
3928 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3936 /* | primary_expression DOT NEW
3938 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3940 | predefined_type DOT identifier
3943 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3946 if (with_stack.Count > 0) {
3947 Expression e = (Expression) with_stack.Peek();
3948 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3962 invocation_expression
3963 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3966 Location l = lexer.Location;
3967 Report.Error (1, l, "THIS IS CRAZY");
3969 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3970 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3972 | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3975 Location l = lexer.Location;
3976 Report.Error (1, l, "THIS IS CRAZY");
3978 $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
3979 // Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
3984 : MYBASE DOT IDENTIFIER
3986 string id_name = (string) $3;
3987 if (id_name.ToUpper() == "NEW")
3989 $$ = new BaseAccess (id_name, lexer.Location);
3993 $$ = new BaseAccess ("New", lexer.Location);
4001 The 'argument' rule returns an 'empty' argument
4002 of type NoArg (used for default arguments in invocations)
4003 if no arguments are actually passed.
4005 If there is only one argument and it is o type NoArg,
4006 we return a null (empty) list
4008 ArrayList args = (ArrayList) $1;
4009 if (args.Count == 1 &&
4010 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
4020 ArrayList list = new ArrayList ();
4024 | argument_list COMMA argument
4026 ArrayList list = (ArrayList) $1;
4035 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
4037 | BYREF variable_reference
4039 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
4043 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
4045 | ADDRESSOF expression
4047 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
4052 : expression {/* note ("section 5.4"); */ $$ = $1; }
4057 : conditional_xor_expression { $$ = $1; }
4058 /*| assignment_expression*/
4069 $$ = new This (current_block, lexer.Location);
4073 // FIXME: This is actually somewhat different from Me
4074 // because it is for accessing static (classifier) methods/properties/fields
4075 $$ = new This (current_block, lexer.Location);
4080 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
4084 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
4086 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
4088 | cast_operator OPEN_PARENS expression CLOSE_PARENS
4090 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
4095 : CBOOL { $$ = TypeManager.system_boolean_expr; }
4096 | CBYTE { $$ = TypeManager.system_byte_expr; }
4097 | CCHAR { $$ = TypeManager.system_char_expr; }
4098 | CDATE { $$ = TypeManager.system_date_expr; }
4099 | CDBL { $$ = TypeManager.system_double_expr; }
4100 | CDEC { $$ = TypeManager.system_decimal_expr; }
4101 | CINT { $$ = TypeManager.system_int32_expr; }
4102 | CLNG { $$ = TypeManager.system_int64_expr; }
4103 | COBJ { $$ = TypeManager.system_object_expr; }
4104 | CSHORT { $$ = TypeManager.system_int16_expr; }
4105 | CSNG { $$ = TypeManager.system_single_expr; }
4106 | CSTR { $$ = TypeManager.system_string_expr; }
4110 : GETTYPE OPEN_PARENS type CLOSE_PARENS
4112 $$ = new TypeOf ((Expression) $3, lexer.Location);
4116 exponentiation_expression
4117 : primary_expression
4118 | exponentiation_expression OP_EXP primary_expression
4124 prefixed_unary_expression
4125 : exponentiation_expression
4126 | PLUS prefixed_unary_expression
4128 //FIXME: Is this rule correctly defined ?
4129 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
4131 | MINUS prefixed_unary_expression
4133 //FIXME: Is this rule correctly defined ?
4134 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
4138 multiplicative_expression
4139 : prefixed_unary_expression
4140 | multiplicative_expression STAR prefixed_unary_expression
4142 $$ = new Binary (Binary.Operator.Multiply,
4143 (Expression) $1, (Expression) $3, lexer.Location);
4145 | multiplicative_expression DIV prefixed_unary_expression
4147 $$ = new Binary (Binary.Operator.Division,
4148 (Expression) $1, (Expression) $3, lexer.Location);
4152 integer_division_expression
4153 : multiplicative_expression
4154 | integer_division_expression OP_IDIV multiplicative_expression
4156 //FIXME: Is this right ?
4157 $$ = new Binary (Binary.Operator.Division,
4158 (Expression) $1, (Expression) $3, lexer.Location);
4163 : integer_division_expression
4164 | mod_expression MOD integer_division_expression
4166 $$ = new Binary (Binary.Operator.Modulus,
4167 (Expression) $1, (Expression) $3, lexer.Location);
4173 | additive_expression PLUS mod_expression
4175 $$ = new Binary (Binary.Operator.Addition,
4176 (Expression) $1, (Expression) $3, lexer.Location);
4178 | additive_expression MINUS mod_expression
4180 $$ = new Binary (Binary.Operator.Subtraction,
4181 (Expression) $1, (Expression) $3, lexer.Location);
4186 : additive_expression
4187 | concat_expression OP_CONCAT additive_expression
4189 // FIXME: This should only work for String expressions
4190 // We probably need to use something from the runtime
4191 $$ = new Binary (Binary.Operator.Addition,
4192 (Expression) $1, (Expression) $3, lexer.Location);
4198 | shift_expression OP_SHIFT_LEFT concat_expression
4202 | shift_expression OP_SHIFT_RIGHT concat_expression
4208 relational_expression
4210 | relational_expression ASSIGN shift_expression
4212 $$ = new Binary (Binary.Operator.Equality,
4213 (Expression) $1, (Expression) $3, lexer.Location);
4215 | relational_expression OP_NE shift_expression
4217 $$ = new Binary (Binary.Operator.Inequality,
4218 (Expression) $1, (Expression) $3, lexer.Location);
4220 | relational_expression OP_LT shift_expression
4222 $$ = new Binary (Binary.Operator.LessThan,
4223 (Expression) $1, (Expression) $3, lexer.Location);
4225 | relational_expression OP_GT shift_expression
4227 $$ = new Binary (Binary.Operator.GreaterThan,
4228 (Expression) $1, (Expression) $3, lexer.Location);
4230 | relational_expression OP_LE shift_expression
4232 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4233 (Expression) $1, (Expression) $3, lexer.Location);
4235 | relational_expression OP_GE shift_expression
4237 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4238 (Expression) $1, (Expression) $3, lexer.Location);
4240 | relational_expression IS shift_expression
4242 //FIXME: Should be a different op for reference equality but allows tests to use Is
4243 $$ = new Binary (Binary.Operator.Equality,
4244 (Expression) $1, (Expression) $3, lexer.Location);
4246 | TYPEOF shift_expression IS type
4248 //FIXME: Is this rule correctly defined ?
4249 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4254 : relational_expression
4255 | NOT negation_expression
4257 //FIXME: Is this rule correctly defined ?
4258 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4262 conditional_and_expression
4263 : negation_expression
4264 | conditional_and_expression AND negation_expression
4266 $$ = new Binary (Binary.Operator.LogicalAnd,
4267 (Expression) $1, (Expression) $3, lexer.Location);
4269 | conditional_and_expression ANDALSO negation_expression
4270 { // FIXME: this is likely to be broken
4271 $$ = new Binary (Binary.Operator.LogicalAnd,
4272 (Expression) $1, (Expression) $3, lexer.Location);
4276 conditional_or_expression
4277 : conditional_and_expression
4278 | conditional_or_expression OR conditional_and_expression
4280 $$ = new Binary (Binary.Operator.LogicalOr,
4281 (Expression) $1, (Expression) $3, lexer.Location);
4283 | conditional_or_expression ORELSE conditional_and_expression
4284 { // FIXME: this is likely to be broken
4285 $$ = new Binary (Binary.Operator.LogicalOr,
4286 (Expression) $1, (Expression) $3, lexer.Location);
4290 conditional_xor_expression
4291 : conditional_or_expression
4292 | conditional_xor_expression XOR conditional_or_expression
4294 $$ = new Binary (Binary.Operator.ExclusiveOr,
4295 (Expression) $1, (Expression) $3, lexer.Location);
4299 assignment_expression
4300 : prefixed_unary_expression ASSIGN expression
4302 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4304 | prefixed_unary_expression STAR ASSIGN expression
4306 Location l = lexer.Location;
4308 $$ = new CompoundAssign (
4309 Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
4311 | prefixed_unary_expression DIV ASSIGN expression
4313 Location l = lexer.Location;
4315 $$ = new CompoundAssign (
4316 Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
4318 | prefixed_unary_expression PLUS ASSIGN expression
4320 Location l = lexer.Location;
4322 $$ = new CompoundAssign (
4323 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4325 | prefixed_unary_expression MINUS ASSIGN expression
4327 Location l = lexer.Location;
4329 $$ = new CompoundAssign (
4330 Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
4332 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
4334 Location l = lexer.Location;
4336 $$ = new CompoundAssign (
4337 Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
4339 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
4341 Location l = lexer.Location;
4343 $$ = new CompoundAssign (
4344 Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
4346 | prefixed_unary_expression OP_CONCAT ASSIGN expression
4348 Location l = lexer.Location;
4350 // FIXME should be strings only
4351 $$ = new CompoundAssign (
4352 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4354 | prefixed_unary_expression OP_EXP ASSIGN expression
4356 Location l = lexer.Location;
4358 /* TODO: $$ = new CompoundAssign (
4359 Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
4361 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4363 ArrayList args = new ArrayList();
4364 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4367 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4368 n.isDelegate = true;
4369 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4382 : namespace_or_type_name
4384 $$ = DecomposeQI ((string) $1, lexer.Location);
4393 ArrayList types = new ArrayList ();
4398 | type_list COMMA type
4400 ArrayList types = (ArrayList) $1;
4407 namespace_or_type_name
4408 : qualified_identifier
4412 : OBJECT { $$ = TypeManager.system_object_expr; }
4418 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4419 | DATE { $$ = TypeManager.system_date_expr; }
4420 | CHAR { $$ = TypeManager.system_char_expr; }
4421 | STRING { $$ = TypeManager.system_string_expr; }
4427 | floating_point_type
4428 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4433 | BYTE { $$ = TypeManager.system_byte_expr; }
4434 | SHORT { $$ = TypeManager.system_int16_expr; }
4435 | INTEGER { $$ = TypeManager.system_int32_expr; }
4436 | LONG { $$ = TypeManager.system_int64_expr; }
4440 : SINGLE { $$ = TypeManager.system_single_expr; }
4441 | DOUBLE { $$ = TypeManager.system_double_expr; }
4445 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4447 if(tokenizerController.IsAcceptingTokens)
4449 if(in_external_source)
4450 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4452 in_external_source = true;
4454 lexer.EffectiveSource = (string) $4;
4455 lexer.EffectiveLine = (int) $6;
4459 | HASH IDENTIFIER LITERAL_STRING EOL
4461 if(tokenizerController.IsAcceptingTokens)
4463 string id = ($2 as string);
4465 if(!($2 as string).ToLower().Equals("region"))
4466 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4473 | HASH END IDENTIFIER EOL
4475 if(tokenizerController.IsAcceptingTokens)
4477 if( ($3 as string).ToLower().Equals("externalsource")) {
4478 if(!in_external_source)
4479 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4481 in_external_source = false;
4482 lexer.EffectiveSource = lexer.Source;
4483 lexer.EffectiveLine = lexer.Line;
4486 else if(($3 as string).ToLower().Equals("region")) {
4487 if(in_marked_region > 0)
4490 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4493 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4497 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4499 if(tokenizerController.IsAcceptingTokens)
4506 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4509 ifElseStateMachine.HandleToken(tok);
4511 catch(ApplicationException) {
4512 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4515 boolean_literal opt_then EOL
4517 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4521 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4523 ifElseStateMachine.HandleToken(tok);
4525 catch(ApplicationException) {
4526 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4529 boolean_literal opt_then EOL
4531 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4535 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4537 ifElseStateMachine.HandleToken(tok);
4539 catch(ApplicationException) {
4540 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4545 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4549 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4551 ifElseStateMachine.HandleToken(tok);
4553 catch(ApplicationException) {
4554 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4559 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4563 if(tokenizerController.IsAcceptingTokens)
4564 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4566 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4576 public Tokenizer Lexer {
4582 public static Expression DecomposeQI (string name, Location loc)
4586 if (name.IndexOf ('.') == -1){
4587 return new SimpleName (name, loc);
4589 int pos = name.LastIndexOf (".");
4590 string left = name.Substring (0, pos);
4591 string right = name.Substring (pos + 1);
4593 o = DecomposeQI (left, loc);
4595 return new MemberAccess (o, right, loc);
4599 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4601 Block implicit_block;
4602 ArrayList inits = null;
4605 // We use the `Used' property to check whether statements
4606 // have been added to the current block. If so, we need
4607 // to create another block to contain the new declaration
4608 // otherwise, as an optimization, we use the same block to
4609 // add the declaration.
4611 // FIXME: A further optimization is to check if the statements
4612 // that were added were added as part of the initialization
4613 // below. In which case, no other statements have been executed
4614 // and we might be able to reduce the number of blocks for
4615 // situations like this:
4617 // int j = 1; int k = j + 1;
4620 VariableDeclaration.FixupTypes (variable_declarators);
4622 if (current_block.Used) {
4623 implicit_block = new Block (current_block, true, loc, Location.Null);
4624 implicit_block.AddChildVariableNames (current_block);
4626 implicit_block = current_block;
4628 foreach (VariableDeclaration decl in variable_declarators){
4629 Expression type = decl.type;
4630 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4631 if (decl.expression_or_array_initializer != null){
4633 inits = new ArrayList ();
4640 return implicit_block;
4642 foreach (VariableDeclaration decl in inits){
4645 Expression type = decl.type;
4647 if ((decl.expression_or_array_initializer is Expression) ||
4648 (decl.expression_or_array_initializer is New)) {
4649 expr = (Expression) decl.expression_or_array_initializer;
4651 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4653 expr = new ArrayCreation (type, "", init, decl.Location);
4656 LocalVariableReference var;
4657 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4659 assign = new Assign (var, expr, decl.Location);
4661 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4664 return implicit_block;
4667 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4669 Block implicit_block;
4670 VariableDeclaration.FixupTypes (variable_declarators);
4672 if (current_block.Used)
4673 implicit_block = new Block (current_block, true);
4675 implicit_block = current_block;
4677 foreach (VariableDeclaration decl in variable_declarators){
4678 Expression type = decl.type;
4679 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4680 current_local_parameters, decl.Location);
4683 return implicit_block;
4691 public VarName (object n, object t, object r)
4701 // A class used to pass around variable declarations and constants
4703 public class VariableDeclaration {
4704 public string identifier;
4705 public object expression_or_array_initializer;
4706 public Location Location;
4707 public Attributes OptAttributes;
4708 public Expression type;
4709 public ArrayList dims;
4711 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4713 this.identifier = id;
4714 this.expression_or_array_initializer = eoai;
4716 this.OptAttributes = opt_attrs;
4721 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4725 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4729 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4730 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4734 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4736 // FIXME : This is broken: only the first rank is parsed
4737 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4740 public static void FixupTypes (ArrayList vars)
4742 int varcount = vars.Count;
4743 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4745 if (last_var.type == null)
4746 last_var.type = TypeManager.system_object_expr;
4748 Expression cur_type = last_var.type;
4749 int n = varcount - 1;
4752 VariableDeclaration var = (VariableDeclaration) vars[n--];
4753 if (var.type == null)
4754 var.type = cur_type;
4756 cur_type = var.type;
4760 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4764 if (IndexList != null) {
4765 foreach (Expression e in IndexList)
4766 if (!(e is EmptyExpression)) {
4775 public static bool IndexesSpecified (ArrayList ranks)
4779 if (ranks != null) {
4780 foreach (ArrayList IndexList in ranks) {
4781 if (IndexesSpecifiedInRank (IndexList)) {
4790 public static string StripDims (string varname, ref string d)
4792 string res = varname;
4795 if (varname.IndexOf("[") >= 0) {
4796 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4797 res = varname.Substring(0, varname.IndexOf("["));
4803 public static string StripDims (string varname)
4807 return (StripDims(varname, ref dres));
4810 public static string StripIndexesFromDims (string dims)
4812 StringBuilder sb = new StringBuilder();
4814 foreach (char c in dims)
4815 if (c == ',' || c == ']' || c == '[')
4818 return sb.ToString();
4821 public static string BuildRank (ArrayList rank)
4824 return BuildRank(rank, out allEmpty);
4827 public static string BuildRank (ArrayList rank, out bool allEmpty)
4834 foreach (object e in rank) {
4835 if (!(e is EmptyExpression))
4846 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
4850 bool allEmpty = true;
4851 foreach (ArrayList rank in rank_specifiers) {
4853 res = BuildRank (rank, out tmp) + res;
4857 if (!allEmpty && mustBeEmpty)
4858 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
4863 public static void VBFixIndexList (ref ArrayList IndexList)
4865 if (IndexList != null) {
4866 for (int x = 0; x < IndexList.Count; x++) {
4867 Expression e = (Expression) IndexList[x];
4868 if (!(e is EmptyExpression)) {
4869 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4875 public static bool IsArrayDecl (Parser t)
4877 // return (varname.IndexOf("[") >= 0);
4878 return (t.current_rank_specifiers != null);
4881 public static void VBFixIndexLists (ref ArrayList ranks)
4883 if (ranks != null) {
4884 for (int x = 0; x < ranks.Count; x++) {
4885 ArrayList IndexList = (ArrayList) ranks[x];
4886 VBFixIndexList (ref IndexList);
4891 public static void FixupArrayTypes (ArrayList vars)
4893 int varcount = vars.Count;
4896 foreach (VariableDeclaration var in vars) {
4897 if (var.identifier.EndsWith(",")) {
4898 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4899 var.identifier.LastIndexOf(",")) + "]";
4900 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4901 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4908 public Property BuildSimpleProperty (Expression p_type, string name,
4909 Field p_fld, int mod_flags,
4910 Attributes attrs, Location loc)
4913 Block get_block, set_block;
4914 Accessor acc_set, acc_get;
4915 StatementExpression a_set;
4920 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4921 args = new Parameter [1];
4922 args [0] = implicit_value_parameter;
4924 Parameters set_params = new Parameters (args, null, loc);
4925 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4926 (Expression) new SimpleName("value", loc), loc), loc);
4928 set_block = new Block (current_block, set_params, loc, Location.Null);
4929 set_block.AddStatement ((Statement) a_set);
4930 acc_set = new Accessor (set_block, attrs);
4933 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4934 get_block = new Block (current_block, null, loc, Location.Null);
4935 get_block.AddStatement ((Statement) a_get);
4936 acc_get = new Accessor (get_block, attrs);
4938 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4945 current_block = new Block (current_block, current_local_parameters,
4946 lexer.Location, Location.Null);
4953 while (current_block.Implicit)
4954 current_block = current_block.Parent;
4956 res = current_block;
4958 current_block.SetEndLocation (lexer.Location);
4959 current_block = current_block.Parent;
4964 private void AddHandler (Expression evt_definition, Expression handler_exp)
4966 AddHandler (current_block, evt_definition, handler_exp);
4969 void CheckAttributeTarget (string a)
4973 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4977 Location l = lexer.Location;
4978 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4983 private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
4985 Expression evt_target;
4986 Location loc = lexer.Location;
4988 Statement addhnd = (Statement) new AddHandler (evt_id,
4992 b.AddStatement (addhnd);
4995 private void RaiseEvent (string evt_name, ArrayList args)
4997 Location loc = lexer.Location;
4999 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
5000 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
5001 current_block.AddStatement (s);
5004 private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
5006 Expression evt_target;
5007 Location loc = lexer.Location;
5009 Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
5012 b.AddStatement (rmhnd);
5016 // This method is used to get at the complete string representation of
5017 // a fully-qualified type name, hiding inside a MemberAccess ;-)
5018 // This is necessary because local_variable_type admits primary_expression
5019 // as the type of the variable. So we do some extra checking
5021 string GetQualifiedIdentifier (Expression expr)
5023 if (expr is SimpleName)
5024 return ((SimpleName)expr).Name;
5025 else if (expr is MemberAccess)
5026 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
5028 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
5032 private void RemoveHandler (Expression evt_definition, Expression handler_exp)
5034 RemoveHandler (current_block, evt_definition, handler_exp);
5037 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
5039 ConstructorInitializer ci = null;
5042 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
5043 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
5045 if (i.expr is BaseAccess) {
5046 BaseAccess ba = (BaseAccess) i.expr;
5047 if (ba.member == "New" || ba.member == ".ctor") {
5048 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
5052 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
5053 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
5061 void Error_ExpectingTypeName (Location l, Expression expr)
5063 if (expr is Invocation){
5064 Report.Error (1002, l, "; expected");
5066 Report.Error (-1, l, "Invalid Type definition");
5070 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
5074 private void ReportError9998()
5076 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
5079 protected override int parse ()
5081 RootContext.InitializeImports(ImportsList);
5082 current_namespace = new Namespace (null, RootContext.RootNamespace);
5083 current_container = RootContext.Tree.Types;
5084 current_container.Namespace = current_namespace;
5085 oob_stack = new Stack ();
5086 switch_stack = new Stack ();
5087 expr_stack = new Stack ();
5088 tmp_blocks = new Stack();
5089 with_stack = new Stack();
5090 statement_stack = new Stack();
5092 UseExtendedSyntax = name.EndsWith(".mbs");
5093 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
5094 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
5095 OptionCompareBinary = InitialOptionCompareBinary;
5097 lexer = new Tokenizer (input, name, defines);
5099 ifElseStateMachine = new IfElseStateMachine();
5100 tokenizerController = new TokenizerController(lexer);
5102 StringBuilder value = new StringBuilder ();
5104 if (yacc_verbose_flag)
5105 yyparse (lexer, new yydebug.yyDebugSimple ());
5111 catch(MBASException e) {
5112 Report.Error(e.code, e.loc, e.Message);
5114 catch (Exception e) {
5115 if (Report.Stacktrace)
5116 Console.WriteLine(e);
5117 Report.Error (29999, lexer.Location, "Parsing error");
5120 RootContext.VerifyImports();
5122 return Report.Errors;
5128 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
5130 catch(ApplicationException) {
5131 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5134 if(in_external_source)
5135 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
5137 if(in_marked_region > 0)
5138 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
5141 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
5144 tokenizerController.PositionTokenizerCursor(tok, expr);
5146 catch(ApplicationException) {
5147 tok = IfElseStateMachine.Token.EOF;
5149 ifElseStateMachine.HandleToken(tok);
5151 catch(ApplicationException) {
5152 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);