3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
5 // Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
6 // Anirban Bhattacharjee (banirban@novell.com)
7 // Jambunathan K (kjambunathan@novell.com)
9 // Licensed under the terms of the GNU GPL
11 // Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
12 // Copyright (C) 2003, 2004 Novell
16 namespace Mono.MonoBASIC
20 using System.Reflection;
21 using System.Collections;
25 public class MBASException : ApplicationException
30 public MBASException(int code, Location loc, string text) : base(text)
38 /// The MonoBASIC Parser
41 public class Parser : GenericParser
46 /// Current block is used to add statements as we find
52 /// Tmp block is used to store block endings in if/select's
57 /// Tmp block is used to store tmp copies of expressions
62 /// Tmp catch is used to store catch clauses in try..catch..finally
64 ArrayList tmp_catch_clauses;
67 /// Current interface is used by the various declaration
68 /// productions in the interface declaration to "add"
69 /// the interfaces as we find them.
71 Interface current_interface;
74 /// This is used by the unary_expression code to resolve
75 /// a name against a parameter.
77 Parameters current_local_parameters;
80 /// This are used when parsing parameters in property
83 Parameters set_parameters;
84 Parameters get_parameters;
87 /// This is used by the sub_header parser to store modifiers
88 /// to be passed to sub/constructor
90 int current_modifiers;
93 /// This is used by the sub_header parser to store attributes
94 /// to be passed to sub/constructor
96 Attributes current_attributes;
99 /// Using during property parsing to describe the implicit
100 /// value parameter that is passed to the "set" accessor
103 string get_implicit_value_parameter_name;
106 // Using during property parsing to describe the implicit
107 // value parameter that is passed to the "set" and "get"accesor
108 // methods (properties and indexers).
110 Expression get_implicit_value_parameter_type;
113 /// Using during property parsing to describe the implicit
114 /// value parameter that is passed to the "set" accessor
117 string set_implicit_value_parameter_name;
120 // Using during property parsing to describe the implicit
121 // value parameter that is passed to the "set" and "get"accesor
122 // methods (properties and indexers).
124 Expression set_implicit_value_parameter_type;
126 Location member_location;
128 // An out-of-band stack.
132 ArrayList current_rank_specifiers;
140 // Expression stack for nested ifs
144 Stack statement_stack;
146 // A stack for With expressions.
151 static public bool InitialOptionExplicit = false;
152 static public bool InitialOptionStrict = false;
153 static public bool InitialOptionCompareBinary = true;
154 static public ArrayList ImportsList = null;
158 bool OptionCompareBinary;
160 static public bool UseExtendedSyntax; // for ".mbs" files
162 bool implicit_modifiers;
164 public override string[] extensions()
166 string [] list = { ".vb", ".mbs" };
170 bool in_external_source = false;
171 int in_marked_region = 0;
173 TokenizerController tokenizerController;
174 IfElseStateMachine ifElseStateMachine;
177 public class IfElseStateMachine {
201 public static Hashtable errStrings = new Hashtable();
204 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
206 static IfElseStateMachine()
208 // FIXME: Fix both the error nos and the error strings.
209 // Currently the error numbers and the error strings are
210 // just placeholders for getting the state-machine going.
212 errStrings.Add(0, "");
213 errStrings.Add(30012, "#If must end with a matching #End If");
214 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
215 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
216 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
217 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
219 errTable[(int)State.START, (int)Token.IF] = 0;
220 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
221 errTable[(int)State.START, (int)Token.ELSE] = 30028;
222 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
223 errTable[(int)State.START, (int)Token.EOF] = 0;
225 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
226 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
227 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
228 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
229 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
231 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
232 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
233 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
234 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
235 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
237 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
238 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
239 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
240 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
241 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
243 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
244 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
245 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
246 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
247 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
250 public IfElseStateMachine()
254 stateStack = new Stack();
255 stateStack.Push(state);
258 // The parameter here need not be qualified with IfElseStateMachine
259 // But it hits a bug in mcs. So temporarily scoping it so that builds
262 public void HandleToken(IfElseStateMachine.Token tok)
264 err = (int) errTable[(int)state, (int)tok];
267 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
269 if(tok == Token.IF) {
270 stateStack.Push(state);
273 else if(tok == Token.ENDIF) {
274 state = (State)stateStack.Pop();
286 public string ErrString {
288 return (string) errStrings[err];
294 public class TokenizerController {
298 public bool CanAcceptTokens;
299 public bool CanSelectBlock;
307 public TokenizerController(Tokenizer lexer)
310 stateStack = new Stack();
312 currentState.CanAcceptTokens = true;
313 currentState.CanSelectBlock = true;
315 stateStack.Push(currentState);
320 return (State)stateStack.Peek();
324 public bool IsAcceptingTokens {
326 return currentState.CanAcceptTokens;
330 public void PositionCursorAtNextPreProcessorDirective()
332 lexer.PositionCursorAtNextPreProcessorDirective();
335 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
337 if(tok == IfElseStateMachine.Token.ENDIF) {
338 currentState = (State)stateStack.Pop();
340 if(currentState.CanAcceptTokens)
343 PositionCursorAtNextPreProcessorDirective();
348 if(tok == IfElseStateMachine.Token.IF) {
349 stateStack.Push(currentState);
351 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
352 currentState.CanSelectBlock = true;
355 if(parentState.CanAcceptTokens &&
356 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
358 currentState.CanAcceptTokens = true;
359 currentState.CanSelectBlock = false;
363 currentState.CanAcceptTokens = false;
364 PositionCursorAtNextPreProcessorDirective();
370 bool allow_global_attribs = true;
372 bool expecting_global_attribs = false;
373 bool expecting_local_attribs = false;
375 bool local_attrib_section_added = false;
379 %token NONE /* This token is never returned by our lexer */
380 %token ERROR // This is used not by the parser, but by the tokenizer.
384 *These are the MonoBASIC keywords
476 %token NOTINHERITABLE
477 %token NOTOVERRIDABLE
533 %token YIELD // MonoBASIC extension
537 /* MonoBASIC single character operators/punctuation. */
539 %token OPEN_BRACKET "["
540 %token CLOSE_BRACKET "]"
541 %token OPEN_PARENS "("
542 %token OPEN_BRACE "{"
543 %token CLOSE_BRACE "}"
544 %token CLOSE_PARENS ")"
558 %token OP_IDIV "\\" //FIXME: This should be "\"
560 %token EXCLAMATION "!"
563 %token LONGTYPECHAR "&"
565 %token SINGLETYPECHAR "!"
566 %token NUMBER_SIGN "#"
567 %token DOLAR_SIGN "$"
569 %token ATTR_ASSIGN ":="
571 /* MonoBASIC multi-character operators. */
576 //%token OP_MODULUS //"mod"
578 /* VB.NET 2003 new bit-shift operators */
579 %token OP_SHIFT_LEFT "<<"
580 %token OP_SHIFT_RIGHT ">>"
583 %token LITERAL_INTEGER "int literal"
584 %token LITERAL_SINGLE "float literal"
585 %token LITERAL_DOUBLE "double literal"
586 %token LITERAL_DECIMAL "decimal literal"
587 %token LITERAL_CHARACTER "character literal"
588 %token LITERAL_STRING "string literal"
589 %token LITERAL_DATE "datetime literal"
593 /* Add precedence rules to solve dangling else s/r conflict */
602 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
604 %left STAR DIV PERCENT
605 %right BITWISE_NOT CARRET UMINUS
606 %nonassoc OP_INC OP_DEC
608 %left OPEN_BRACKET OPEN_BRACE
613 %start compilation_unit
617 : logical_end_of_line
623 | logical_end_of_line pp_directive
627 : logical_end_of_line
628 opt_option_directives
629 opt_imports_directives
636 opt_option_directives
637 opt_imports_directives
645 opt_option_directives
652 | option_directives option_directive
656 : option_explicit_directive
657 | option_strict_directive
658 | option_compare_directive
687 option_explicit_directive
688 : OPTION EXPLICIT on_off logical_end_of_line
690 if (!UseExtendedSyntax)
691 OptionExplicit = (bool)$3;
694 9999, lexer.Location,
695 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
700 option_strict_directive
701 : OPTION STRICT on_off logical_end_of_line
703 if (!UseExtendedSyntax)
704 OptionStrict = (bool)$3;
707 9999, lexer.Location,
708 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
712 option_compare_directive
713 : OPTION COMPARE text_or_binary logical_end_of_line
715 OptionCompareBinary = (bool)$3;
726 | declarations declaration
730 : declaration_qualifiers
732 // FIXME: Need to check declaration qualifiers for multi-file compilation
733 // FIXME: Qualifiers cannot be applied to namespaces
734 allow_global_attribs = false;
736 namespace_declaration
737 |declaration_qualifiers
739 // FIXME: Need to check declaration qualifiers for multi-file compilation
740 allow_global_attribs = false;
742 type_spec_declaration
747 if ($3 is Class || $3 is Struct || $3 is Module ){
748 TypeContainer c = (TypeContainer) $3;
749 mod_flags = c.ModFlags;
754 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
756 1527, lexer.Location,
757 "Namespace elements cannot be explicitly " +
758 "declared private or protected in '" + name + "'");
773 : PERCENT { $$ = TypeManager.system_int32_expr; }
774 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
775 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
776 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
777 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
778 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
782 : /* empty */ { $$ = null; }
783 | type_character { $$ = $1; }
789 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
791 $$ = (($1).ToString ()) + "." + ($3.ToString ());
795 opt_imports_directives
802 | imports_directives imports_directive
806 : IMPORTS imports_terms logical_end_of_line
811 | imports_terms COMMA imports_term
815 : namespace_or_type_name
817 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
819 | identifier ASSIGN namespace_or_type_name
821 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
826 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
827 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
828 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
836 local_attrib_section_added = false;
845 expecting_local_attribs = false;
846 expecting_global_attribs = false;
850 if (expecting_local_attribs) {
851 local_attrib_section_added = true;
852 allow_global_attribs = false;
854 $$ = new Attributes ((ArrayList) $1);
857 if (expecting_global_attribs) {
859 CodeGen.AddGlobalAttributes ((ArrayList) $1);
862 expecting_local_attribs = false;
863 expecting_global_attribs = false;
873 ArrayList attrs = (ArrayList) $3;
875 if (expecting_local_attribs) {
876 if (local_attrib_section_added) {
877 expecting_local_attribs = false;
878 expecting_global_attribs = false;
879 Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
884 $$ = new Attributes (attrs);
886 ((Attributes) $1).Add (attrs);
888 local_attrib_section_added = true;
889 allow_global_attribs = false;
892 if (expecting_global_attribs) {
894 CodeGen.AddGlobalAttributes ((ArrayList) $3);
898 expecting_local_attribs = false;
899 expecting_global_attribs = false;
904 : OP_LT attribute_list OP_GT opt_end_of_stmt
908 if (expecting_global_attribs && !(bool) $4) {
909 Report.Error (30205, lexer.Location, "End of statement expected");
913 if (expecting_local_attribs) {
915 Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
926 : /* empty */ { $$ = false; }
927 | end_of_stmt { $$ = true; }
933 ArrayList attrs = null;
935 attrs = new ArrayList ();
940 | attribute_list COMMA attribute
942 ArrayList attrs = null;
945 attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
954 : namespace_or_type_name
958 opt_attribute_arguments
962 if (expecting_global_attribs)
963 Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
965 expecting_local_attribs = true;
966 $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
969 | attribute_target_specifier
974 namespace_or_type_name
978 opt_attribute_arguments
982 string attribute_target = (string) $1;
983 if (attribute_target != "assembly" && attribute_target != "module") {
984 Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
987 if (!allow_global_attribs) {
988 Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
992 if (expecting_local_attribs) {
993 Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
997 expecting_global_attribs = true;
998 $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
1002 attribute_target_specifier
1003 : ASSEMBLY { $$ = "assembly"; }
1004 | MODULE { $$ = "module"; }
1005 | namespace_or_type_name
1009 opt_attribute_arguments
1010 : /* empty */ { $$ = null; }
1011 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
1017 opt_attribute_arguments_list
1019 | attribute_arguments_list
1022 attribute_arguments_list
1023 : positional_argument_list
1025 ArrayList args = new ArrayList ();
1030 | positional_argument_list COMMA named_argument_list
1032 ArrayList args = new ArrayList ();
1038 | named_argument_list
1040 ArrayList args = new ArrayList ();
1048 positional_argument_list
1049 : constant_expression
1051 ArrayList args = new ArrayList ();
1052 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
1056 | positional_argument_list COMMA constant_expression
1058 ArrayList args = (ArrayList) $1;
1059 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
1068 ArrayList args = new ArrayList ();
1073 | named_argument_list COMMA named_argument
1075 ArrayList args = (ArrayList) $1;
1083 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
1085 $$ = new DictionaryEntry (
1087 new Argument ((Expression) $3, Argument.AType.Expression));
1091 namespace_declaration
1092 : NAMESPACE qualified_identifier logical_end_of_line
1094 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2);
1097 END NAMESPACE logical_end_of_line
1099 current_namespace = current_namespace.Parent;
1103 declaration_qualifiers
1107 current_attributes = (Attributes) $1;
1108 current_modifiers = (int) $2;
1112 type_spec_declaration
1114 | module_declaration
1115 | interface_declaration
1116 | delegate_declaration
1117 | struct_declaration
1122 : CLASS identifier logical_end_of_line opt_inherits opt_implements
1124 // Module members are static by default, but Class *can't* be declared static
1125 // so we must fix it, if mbas was the one actually responsible for this
1126 // instead of triggering an error.
1127 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1128 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1133 name = MakeName ((string) $2);
1134 new_class = new Class (current_container, name, current_modifiers,
1135 (Attributes) current_attributes, lexer.Location);
1137 current_container = new_class;
1138 current_container.Namespace = current_namespace;
1139 RootContext.Tree.RecordDecl (name, new_class);
1141 opt_class_member_declarations
1142 END CLASS logical_end_of_line
1144 Class new_class = (Class) current_container;
1146 ArrayList bases = (ArrayList) $4;
1148 ArrayList ifaces = (ArrayList) $5;
1149 if (ifaces != null){
1151 bases.AddRange(ifaces);
1155 new_class.Bases = bases;
1157 current_container = current_container.Parent;
1158 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1165 : /* empty */ { $$ = null; }
1166 | INHERITS type_list logical_end_of_line { $$ = $2; }
1170 : /* empty */ { $$ = null; }
1171 | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
1175 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1176 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1181 | modifiers modifier
1186 if ((m1 & m2) != 0) {
1187 Location l = lexer.Location;
1188 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1190 $$ = (int) (m1 | m2);
1195 : PUBLIC { $$ = Modifiers.PUBLIC; }
1196 | PROTECTED { $$ = Modifiers.PROTECTED; }
1197 | PRIVATE { $$ = Modifiers.PRIVATE; }
1198 | SHARED { $$ = Modifiers.STATIC; }
1199 | FRIEND { $$ = Modifiers.INTERNAL; }
1200 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1201 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1202 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1203 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1204 | OVERLOADS { $$ = Modifiers.NEW; }
1205 | SHADOWS { $$ = Modifiers.SHADOWS; }
1206 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1207 | READONLY { $$ = Modifiers.READONLY; }
1208 | DEFAULT { $$ = Modifiers.DEFAULT; }
1209 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1213 : MODULE identifier logical_end_of_line
1217 name = MakeName((string) $2);
1218 new_module = new Module(current_container,
1220 current_modifiers, // already checks then
1221 (Attributes) current_attributes,
1223 current_container = new_module;
1224 current_container.Namespace = current_namespace;
1225 RootContext.Tree.RecordDecl(name, new_module);
1227 opt_module_member_declarations
1228 END MODULE logical_end_of_line
1230 Module new_module = (Module)current_container;
1232 current_container = current_container.Parent;
1233 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1235 TypeManager.AddStandardModule(new_module);
1241 opt_module_member_declarations
1243 | module_member_declarations
1246 module_member_declarations
1247 : module_member_declaration
1248 | module_member_declarations module_member_declaration
1251 module_member_declaration
1255 current_attributes = (Attributes) $1;
1256 current_modifiers = ((int)$2) | Modifiers.STATIC;
1257 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1258 implicit_modifiers = (!explicit_static);
1260 module_member_declarator
1262 implicit_modifiers = false;
1267 module_member_declarator
1268 : constructor_declaration
1269 | method_declaration
1271 Method method = (Method) $1;
1272 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1275 | withevents_declaration /* This is a field but must be treated specially, see below */
1276 | constant_declaration
1277 | property_declaration
1279 | type_spec_declaration
1282 constant_declaration
1283 : CONST constant_declarators logical_end_of_line
1285 // Module members are static by default, but constants *can't* be declared static
1286 // so we must fix it, if mbas was the one actually responsible for this
1287 // instead of triggering an error.
1288 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1289 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1291 int mod = (int) current_modifiers;
1293 // Structure members are Public by default
1294 if ((current_container is Struct) && (mod == 0))
1295 mod = Modifiers.PUBLIC;
1297 ArrayList consts = (ArrayList) $2;
1298 if(consts.Count > 0)
1300 VariableDeclaration.FixupTypes ((ArrayList) $2);
1301 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1303 foreach (VariableDeclaration var in (ArrayList) $2){
1304 Location l = var.Location;
1305 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1306 (Expression)var.expression_or_array_initializer,
1307 mod, (Attributes) null, l);
1309 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1315 opt_class_member_declarations
1317 | class_member_declarations
1320 class_member_declarations
1321 : class_member_declaration
1322 | class_member_declarations class_member_declaration
1325 class_member_declaration
1329 current_attributes = (Attributes) $1;
1330 current_modifiers = (int) $2;
1332 class_member_declarator
1338 class_member_declarator
1339 : constructor_declaration
1340 | method_declaration
1342 Method method = (Method) $1;
1343 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1346 | constant_declaration
1347 | property_declaration
1349 | withevents_declaration /* This is a field but must be treated specially, see below */
1350 | type_spec_declaration
1357 | must_override_declaration
1360 must_override_declaration
1361 : must_override_sub_declaration
1362 | must_override_func_declaration
1365 must_override_sub_declaration
1366 : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
1368 if (current_container is Module)
1369 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1371 if (current_container is Struct)
1372 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1374 current_modifiers |= Modifiers.ABSTRACT;
1376 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1377 (Parameters) $4, null, (ArrayList) $5, lexer.Location);
1379 if (!(current_container is Class))
1380 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1387 must_override_func_declaration
1388 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1390 Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.
1391 system_object_expr : (Expression) $4 ) : (Expression) $6;
1393 if (current_container is Module)
1394 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1396 if (current_container is Struct)
1397 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1399 current_modifiers |= Modifiers.ABSTRACT;
1401 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1402 (string) $3,(Parameters) $5, null, (ArrayList) $7,
1405 if (!(current_container is Class))
1406 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1413 : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1415 current_local_parameters = (Parameters) $3;
1418 // Structure members are Public by default
1419 if ((current_container is Struct) && (current_modifiers == 0))
1420 current_modifiers = Modifiers.PUBLIC;
1422 member_location = lexer.Location;
1425 END SUB logical_end_of_line
1427 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1428 (Parameters) current_local_parameters, (Attributes) current_attributes,
1429 (ArrayList) $5, member_location);
1431 method.Block = (Block) end_block();
1435 // we have an event handler to take care of
1437 Expression handles_exp = (Expression) $4;
1438 Location loc = lexer.Location;
1440 if (handles_exp is MemberAccess) {
1441 string evt_def = ((MemberAccess)$4).ToString();
1442 int pos = evt_def.LastIndexOf (".");
1443 string evt_target = evt_def.Substring (0, pos);
1446 if (current_container.Properties != null) {
1447 foreach (Property p in current_container.Properties) {
1448 if (p.Name == evt_target) {
1451 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1452 DecomposeQI((string) $2, loc),
1455 current_container.AddEventHandler (addhnd);
1463 Report.Error(30506, lexer.Location,
1464 evt_target + " is not declared with WithEvents");
1466 } else if (handles_exp is BaseAccess) {
1467 string evt_id = ((BaseAccess) $4).member;
1468 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1469 DecomposeQI((string) $2, loc),
1472 current_container.AddEventHandler (addhnd);
1480 : FUNCTION identifier opt_type_character
1481 opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1483 current_local_parameters = (Parameters) $4;
1484 member_location = lexer.Location;
1487 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1489 // Structure members are Public by default
1490 if ((current_container is Struct) && (current_modifiers == 0))
1491 current_modifiers = Modifiers.PUBLIC;
1492 // Add local var declaration
1494 ArrayList retval = new ArrayList ();
1495 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1496 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1499 END FUNCTION logical_end_of_line
1501 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1503 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1504 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1505 (ArrayList) $6, member_location);
1506 method.Block = end_block();
1512 : STRUCTURE identifier logical_end_of_line
1513 opt_implement_clause
1516 string full_struct_name = MakeName ((string) $2);
1518 // Module members are static by default, but structures *can't* be declared static
1519 // so we must fix it, if mbas was the one actually responsible for this
1520 // instead of triggering an error.
1521 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1522 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1524 new_struct = new Struct (current_container, full_struct_name,
1525 (int) current_modifiers,
1526 (Attributes) current_attributes, lexer.Location);
1527 current_container = new_struct;
1528 current_container.Namespace = current_namespace;
1529 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1531 opt_struct_member_declarations
1533 Struct new_struct = (Struct) current_container;
1536 new_struct.Bases = (ArrayList) $4;
1538 current_container = current_container.Parent;
1539 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1542 END STRUCTURE logical_end_of_line
1545 opt_struct_member_declarations
1547 | struct_member_declarations
1550 struct_member_declarations
1551 : struct_member_declaration
1552 | struct_member_declarations struct_member_declaration
1555 struct_member_declaration
1557 struct_member_declarator
1560 struct_member_declarator
1562 | constant_declaration
1563 | constructor_declaration
1564 | method_declaration
1566 Method method = (Method) $1;
1567 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1569 | property_declaration
1571 | type_spec_declaration
1574 * This is only included so we can flag error 575:
1575 * destructors only allowed on class types
1577 //| destructor_declaration
1581 : EVENT identifier AS type opt_implement_clause logical_end_of_line
1583 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1585 Event e = new Event ((Expression) $4, var.identifier,
1586 null, current_modifiers,
1587 current_attributes, (ArrayList) $5,
1590 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1592 | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1594 string delName = null;
1597 delName = (string) $2;
1598 delName = delName + "EventHandler";
1599 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1600 (current_container, TypeManager.system_void_expr,
1601 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1602 (Attributes) current_attributes, lexer.Location);
1604 del.Namespace = current_namespace;
1605 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1607 ArrayList impls = (ArrayList) $4;
1608 if (impls.Count > 1) {
1609 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1610 "' can not be implemented with Event '" +
1611 (string) $2 + "', since it's delegate type does not match " +
1612 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1613 Report.Error (31407, lexer.Location, expstr);
1615 Expression impl = (Expression) impls[0];
1616 delName = impl.ToString();
1617 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1618 delName = delName + "EventHandler";
1621 Event e = new Event (DecomposeQI (delName, lexer.Location),
1623 null, current_modifiers,
1624 current_attributes, (ArrayList) $4,
1627 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1632 : ENUM identifier opt_type_spec logical_end_of_line
1633 opt_enum_member_declarations
1635 Location enum_location = lexer.Location;
1636 string full_name = MakeName ((string) $2);
1637 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1638 ArrayList enum_members = (ArrayList) $5;
1640 if (enum_members.Count == 0)
1641 Report.Error (30280, enum_location,
1642 "Enum can not have empty member list");
1644 // Module members are static by default, but enums *can't* be declared static
1645 // so we must fix it if mbas was the one actually responsible for this
1646 // instead of triggering an error.
1647 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1648 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1650 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1651 (int) current_modifiers, full_name,
1652 (Attributes) current_attributes, enum_location);
1654 foreach (VariableDeclaration ev in enum_members) {
1655 Location loc = (Location) ev.Location;
1657 CheckDef (e.AddEnumMember (ev.identifier,
1658 (Expression) ev.expression_or_array_initializer,
1659 loc, ev.OptAttributes), ev.identifier, loc);
1662 e.Namespace = current_namespace;
1664 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1665 RootContext.Tree.RecordDecl (full_name, e);
1668 END ENUM logical_end_of_line
1671 opt_enum_member_declarations
1672 : /* empty */ { $$ = new ArrayList (); }
1673 | enum_member_declarations { $$ = $1; }
1676 enum_member_declarations
1677 : enum_member_declaration
1679 ArrayList l = new ArrayList ();
1684 | enum_member_declarations enum_member_declaration
1686 ArrayList l = (ArrayList) $1;
1694 enum_member_declaration
1695 : opt_attributes identifier logical_end_of_line
1697 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1699 | opt_attributes identifier
1701 $$ = lexer.Location;
1703 ASSIGN expression logical_end_of_line
1705 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1709 interface_declaration
1710 : INTERFACE identifier logical_end_of_line
1712 Interface new_interface;
1713 string full_interface_name = MakeName ((string) $2);
1715 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1716 (Attributes) current_attributes, lexer.Location);
1717 if (current_interface != null) {
1718 Location l = lexer.Location;
1719 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1721 current_interface = new_interface;
1722 new_interface.Namespace = current_namespace;
1723 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1728 Interface new_interface = (Interface) current_interface;
1731 new_interface.Bases = (ArrayList) $5;
1733 current_interface = null;
1734 CheckDef (current_container.AddInterface (new_interface),
1735 new_interface.Name, new_interface.Location);
1738 END INTERFACE logical_end_of_line
1742 : /* empty */ { $$ = null; }
1748 | interface_bases interface_base
1750 ArrayList bases = (ArrayList) $1;
1751 bases.AddRange ((ArrayList) $2);
1757 : INHERITS type_list logical_end_of_line { $$ = $2; }
1761 : opt_interface_member_declarations
1764 opt_interface_member_declarations
1766 | interface_member_declarations
1769 interface_member_declarations
1770 : interface_member_declaration
1771 | interface_member_declarations interface_member_declaration
1774 interface_member_declaration
1778 current_attributes = (Attributes) $1;
1779 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
1781 interface_member_declarator
1787 interface_member_declarator
1788 : interface_method_declaration
1790 Method m = (Method) $1;
1791 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1793 | interface_property_declaration
1794 | interface_event_declaration
1797 interface_method_declaration
1798 : SUB identifier opt_params logical_end_of_line
1800 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1801 (Parameters) $3, current_attributes, null, lexer.Location);
1805 | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
1807 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.
1808 system_object_expr : (Expression) $3 ) : (Expression) $5;
1810 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1811 (string) $2,(Parameters) $4, current_attributes, null,
1818 interface_property_declaration
1819 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1821 Expression ftype = ($5 == null) ? (($3 == null) ?
1822 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1824 current_local_parameters = (Parameters) $4;
1825 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1826 get_parameters = current_local_parameters.Copy (lexer.Location);
1827 set_parameters = current_local_parameters.Copy (lexer.Location);
1829 Parameter implicit_value_parameter = new Parameter (
1830 ftype, "Value", Parameter.Modifier.NONE, null);
1832 set_parameters.AppendParameter (implicit_value_parameter);
1836 get_parameters = Parameters.EmptyReadOnlyParameters;
1837 set_parameters = new Parameters (null, null ,lexer.Location);
1839 Parameter implicit_value_parameter = new Parameter (
1840 ftype, "Value", Parameter.Modifier.NONE, null);
1842 set_parameters.AppendParameter (implicit_value_parameter);
1844 lexer.PropertyParsing = true;
1846 Accessor get_block = new Accessor (null, null);
1847 Accessor set_block = new Accessor (null, null);
1849 Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
1850 get_block, set_block, current_attributes, lexer.Location,
1851 null, get_parameters, set_parameters, null);
1853 CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
1855 get_implicit_value_parameter_type = null;
1856 set_implicit_value_parameter_type = null;
1857 get_parameters = null;
1858 set_parameters = null;
1859 current_local_parameters = null;
1863 interface_event_declaration
1864 : EVENT identifier AS type logical_end_of_line
1866 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1868 Event e = new Event ((Expression) $4, var.identifier,
1869 null, current_modifiers,
1870 current_attributes, lexer.Location);
1872 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1875 | EVENT identifier opt_params logical_end_of_line
1877 string delName = (string) $2;
1878 delName = delName + "EventHandler";
1879 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
1880 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1881 (current_container, TypeManager.system_void_expr,
1882 (int) delModifiers, MakeName(delName), (Parameters) $3,
1883 (Attributes) current_attributes, lexer.Location);
1885 del.Namespace = current_namespace;
1886 CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
1888 Event e = new Event (DecomposeQI (delName, lexer.Location),
1890 null, current_modifiers,
1891 current_attributes, lexer.Location);
1893 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1897 property_declaration
1898 : abstract_propery_declaration
1899 | non_abstract_propery_declaration
1902 abstract_propery_declaration
1903 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1905 Expression ftype = ($6 == null) ? (($4 == null) ?
1906 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
1908 if (current_container is Module)
1909 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1911 if (current_container is Struct)
1912 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1914 current_modifiers |= Modifiers.ABSTRACT;
1916 current_local_parameters = (Parameters) $5;
1917 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1918 get_parameters = current_local_parameters.Copy (lexer.Location);
1919 set_parameters = current_local_parameters.Copy (lexer.Location);
1921 Parameter implicit_value_parameter = new Parameter (
1922 ftype, "Value", Parameter.Modifier.NONE, null);
1924 set_parameters.AppendParameter (implicit_value_parameter);
1928 get_parameters = Parameters.EmptyReadOnlyParameters;
1929 set_parameters = new Parameters (null, null ,lexer.Location);
1931 Parameter implicit_value_parameter = new Parameter (
1932 ftype, "Value", Parameter.Modifier.NONE, null);
1934 set_parameters.AppendParameter (implicit_value_parameter);
1936 lexer.PropertyParsing = true;
1938 Accessor get_block = new Accessor (null, null);
1939 Accessor set_block = new Accessor (null, null);
1941 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1942 get_block, set_block, current_attributes, lexer.Location,
1943 null, get_parameters, set_parameters, null);
1945 if (!(current_container is Class))
1946 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1948 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1950 get_implicit_value_parameter_type = null;
1951 set_implicit_value_parameter_type = null;
1952 get_parameters = null;
1953 set_parameters = null;
1954 current_local_parameters = null;
1959 non_abstract_propery_declaration
1960 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
1962 get_implicit_value_parameter_type =
1963 ($5 == null) ? (($3 == null) ?
1964 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1965 get_implicit_value_parameter_name = (string) $2;
1967 current_local_parameters = (Parameters) $4;
1968 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1969 get_parameters = current_local_parameters.Copy (lexer.Location);
1970 set_parameters = current_local_parameters.Copy (lexer.Location);
1974 get_parameters = Parameters.EmptyReadOnlyParameters;
1975 set_parameters = new Parameters (null, null ,lexer.Location);
1977 lexer.PropertyParsing = true;
1979 $$ = lexer.Location;
1981 accessor_declarations
1982 END PROPERTY logical_end_of_line
1984 lexer.PropertyParsing = false;
1987 Pair pair = (Pair) $9;
1989 Accessor get_block = null;
1990 Accessor set_block = null;
1992 if (pair.First != null){
1993 get_block = (Accessor) pair.First;
1996 if (pair.Second != null) {
1997 set_block = (Accessor) pair.Second;
2000 Location loc = lexer.Location;
2002 // Structure members are Public by default
2003 if ((current_container is Struct) && (current_modifiers == 0))
2004 current_modifiers = Modifiers.PUBLIC;
2006 prop = new Property ((Expression) get_implicit_value_parameter_type,
2007 (string) $2, current_modifiers, get_block, set_block,
2008 current_attributes, loc, set_implicit_value_parameter_name,
2009 get_parameters, set_parameters, (ArrayList) $6);
2011 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
2012 get_implicit_value_parameter_type = null;
2013 set_implicit_value_parameter_type = null;
2014 get_parameters = null;
2015 set_parameters = null;
2016 current_local_parameters = null;
2020 opt_property_parameters
2023 $$ = Parameters.EmptyReadOnlyParameters;
2025 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2031 opt_implement_clause
2036 | IMPLEMENTS implement_clause_list
2042 implement_clause_list
2043 : qualified_identifier
2045 ArrayList impl_list = new ArrayList ();
2046 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
2049 | implement_clause_list COMMA qualified_identifier
2051 ArrayList impl_list = (ArrayList) $1;
2052 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
2058 accessor_declarations
2059 : get_accessor_declaration opt_set_accessor_declaration
2061 $$ = new Pair ($1, $2);
2063 | set_accessor_declaration opt_get_accessor_declaration
2065 $$ = new Pair ($2, $1);
2069 opt_get_accessor_declaration
2070 : /* empty */ { $$ = null; }
2071 | get_accessor_declaration
2074 opt_set_accessor_declaration
2075 : /* empty */ { $$ = null; }
2076 | set_accessor_declaration
2079 get_accessor_declaration
2080 : opt_attributes GET logical_end_of_line
2082 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
2083 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
2085 current_local_parameters = get_parameters;
2087 lexer.PropertyParsing = false;
2090 // Add local var declaration
2092 ArrayList retval = new ArrayList ();
2093 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
2094 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
2097 END GET logical_end_of_line
2099 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2100 current_local_parameters = null;
2101 lexer.PropertyParsing = true;
2105 set_accessor_declaration
2106 : opt_attributes SET opt_set_parameter logical_end_of_line
2108 if ((current_modifiers & Modifiers.READONLY) != 0)
2109 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
2111 Parameter implicit_value_parameter = new Parameter (
2112 set_implicit_value_parameter_type,
2113 set_implicit_value_parameter_name,
2114 Parameter.Modifier.NONE, null);
2116 current_local_parameters = set_parameters;
2117 current_local_parameters.AppendParameter (implicit_value_parameter);
2120 lexer.PropertyParsing = false;
2123 END SET logical_end_of_line
2125 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2126 current_local_parameters = null;
2127 lexer.PropertyParsing = true;
2134 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2135 set_implicit_value_parameter_name = "Value";
2137 |OPEN_PARENS CLOSE_PARENS
2139 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2140 set_implicit_value_parameter_name = "Value";
2142 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2144 Parameter.Modifier pm = (Parameter.Modifier)$2;
2145 if ((pm | Parameter.Modifier.VAL) != 0)
2146 Report.Error (31065,
2148 "Set cannot have a paremeter modifier other than 'ByVal'");
2150 set_implicit_value_parameter_type = (Expression) $4;
2152 if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
2153 Report.Error (31064,
2155 "Set value parameter type can not be different from property type");
2158 set_implicit_value_parameter_name = (string) $3;
2160 set_implicit_value_parameter_name = "Value";
2166 variable_declarators logical_end_of_line
2168 int mod = (int) current_modifiers;
2170 VariableDeclaration.FixupTypes ((ArrayList) $2);
2171 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2173 if (current_container is Module)
2174 mod = mod | Modifiers.STATIC;
2176 // Structure members are Public by default
2177 if ((current_container is Struct) && (mod == 0))
2178 mod = Modifiers.PUBLIC;
2180 if ((mod & Modifiers.Accessibility) == 0)
2181 mod |= Modifiers.PRIVATE;
2183 foreach (VariableDeclaration var in (ArrayList) $2){
2184 Location l = var.Location;
2185 Field field = new Field (var.type, mod, var.identifier,
2186 var.expression_or_array_initializer,
2187 (Attributes) null, l);
2189 CheckDef (current_container.AddField (field), field.Name, l);
2194 withevents_declaration
2195 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2197 // Module members are static by default, but delegates *can't* be declared static
2198 // so we must fix it, if mbas was the one actually responsible for this
2199 // instead of triggering an error.
2200 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2201 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2203 /* WithEvents Fields must be resolved into properties
2204 with a bit of magic behind the scenes */
2206 VariableDeclaration.FixupTypes ((ArrayList) $3);
2208 foreach (VariableDeclaration var in (ArrayList) $3) {
2209 // 1 - We create a private field
2210 Location l = var.Location;
2212 if ((current_modifiers & Modifiers.STATIC) > 0)
2213 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2215 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2216 var.expression_or_array_initializer,
2217 (Attributes) null, l);
2219 CheckDef (current_container.AddField (field), field.Name, l);
2221 // 2 - Public property
2223 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2224 field, (int) current_modifiers,
2225 (Attributes) current_attributes, l);
2227 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2237 delegate_declaration
2239 identifier OPEN_PARENS
2240 opt_formal_parameter_list
2244 Location l = lexer.Location;
2245 // Module members are static by default, but delegates *can't* be declared static
2246 // so we must fix it, if mbas was the one actually responsible for this
2247 // instead of triggering an error.
2248 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2249 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2251 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2252 TypeManager.system_void_expr,
2253 (int) current_modifiers,
2254 MakeName ((string) $3), (Parameters) $5,
2255 (Attributes) current_attributes, l);
2257 del.Namespace = current_namespace;
2258 CheckDef (current_container.AddDelegate (del), del.Name, l);
2261 identifier OPEN_PARENS
2262 opt_formal_parameter_list
2263 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2265 Location l = lexer.Location;
2267 // Module members are static by default, but delegates *can't* be declared static
2268 // so we must fix it, if mbas was the one actually responsible for this
2269 // instead of triggering an error.
2270 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2271 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2273 Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2275 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2277 ftype, (int) current_modifiers, MakeName ((string) $3),
2278 (Parameters) $5, (Attributes) current_attributes, l);
2280 del.Namespace = current_namespace;
2281 CheckDef (current_container.AddDelegate (del), del.Name, l);
2286 : /* empty */ { $$ = null; }
2287 | HANDLES evt_handler { $$ = $2; }
2291 : qualified_identifier
2293 $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);
2299 | ME DOT qualified_identifier
2301 $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);
2303 /*| MYBASE DOT qualified_identifier
2305 // FIXME: this is blatantly wrong and crash-prone
2306 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2310 constructor_declaration
2311 : SUB NEW opt_params logical_end_of_line
2313 current_local_parameters = (Parameters) $3;
2315 oob_stack.Push (lexer.Location);
2317 Location l = (Location) oob_stack.Pop ();
2318 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2323 Constructor c = (Constructor) $1;
2324 c.Block = (Block) end_block();
2325 c.ModFlags = (int) current_modifiers;
2326 c.OptAttributes = current_attributes;
2328 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2330 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2331 current_local_parameters = null;
2333 END SUB logical_end_of_line
2336 opt_formal_parameter_list
2339 $$ = Parameters.EmptyReadOnlyParameters;
2341 | formal_parameter_list
2344 //Parameter p = ((Parameters) $1).FixedParameters[0];
2348 formal_parameter_list
2351 ArrayList pars_list = (ArrayList) $1;
2352 Parameter [] pars = null;
2353 Parameter array_parameter = null;
2354 int non_array_count = pars_list.Count;
2355 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2356 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2357 non_array_count = pars_list.Count - 1;
2359 foreach (Parameter par in pars_list)
2360 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2361 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2362 non_array_count = 0;
2363 array_parameter = null;
2366 if (non_array_count > 0) {
2367 pars = new Parameter [non_array_count];
2368 pars_list.CopyTo (0, pars, 0, non_array_count);
2370 $$ = new Parameters (pars, array_parameter, lexer.Location);
2377 ArrayList pars = new ArrayList ();
2382 | parameters COMMA parameter
2384 ArrayList pars = (ArrayList) $1;
2393 opt_parameter_modifier
2394 identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2396 Parameter.Modifier pm = (Parameter.Modifier)$2;
2397 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2400 if (opt_parm && ($7 == null))
2401 Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
2403 if (!opt_parm && ($7 != null))
2404 Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
2406 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2407 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2408 Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
2411 if ((pm & Parameter.Modifier.REF) !=0)
2412 pm |= Parameter.Modifier.ISBYREF;
2414 if ($4 != null && $6 != null && $4 != $6)
2415 Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2417 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2419 string t = ptype.ToString ();
2420 if (t.IndexOf('[') >= 0)
2421 Report.Error (31087, lexer.Location, "Array types specified in too many places");
2423 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
2425 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2426 Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
2427 $$ = new Parameter (ptype, (string) $3, pm,
2428 (Attributes) $1, (Expression) $7, opt_parm);
2432 opt_parameter_modifier
2433 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2434 | parameter_modifiers { $$ = $1; }
2438 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2439 | parameter_modifier { $$ = $1; }
2443 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2444 | BYVAL { $$ = Parameter.Modifier.VAL; }
2445 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2446 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2451 | statement_list end_of_stmt
2456 | statement_list end_of_stmt statement
2460 : declaration_statement
2462 if ($1 != null && (Block) $1 != current_block){
2463 current_block.AddStatement ((Statement) $1);
2464 current_block = (Block) $1;
2467 | embedded_statement
2469 Statement s = (Statement) $1;
2471 current_block.AddStatement ((Statement) $1);
2474 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2476 AddHandler ((Expression) $2, (Expression) $5);
2478 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2480 RemoveHandler ((Expression) $2, (Expression) $5);
2482 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2484 RaiseEvent ((string) $2, (ArrayList) $3);
2486 /* | array_handling_statement */
2487 /* | empty_statement */
2490 Statement s = (Statement) $1;
2492 current_block.AddStatement ((Statement) $1);
2496 opt_raise_event_args
2497 : /* empty */ { $$ = null; }
2498 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2515 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2517 if (!current_block.AddLabel ((string) $1, labeled)){
2518 Location l = lexer.Location;
2519 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2521 current_block.AddStatement (labeled);
2525 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2527 if (!current_block.AddLabel ((string) $1, labeled)){
2528 Location l = lexer.Location;
2529 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2531 current_block.AddStatement (labeled);
2537 : expression_statement
2538 | selection_statement
2539 | iteration_statement
2541 | synclock_statement
2543 | array_handling_statement
2549 $$ = new EmptyStatement ();
2555 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2557 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2558 Expression e = (Expression) $2;
2565 Block b = end_block();
2572 array_handling_statement
2578 : REDIM opt_preserve redim_clauses
2580 ArrayList list = (ArrayList) $3;
2581 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2588 : /* empty */ { $$ = false; }
2589 | PRESERVE { $$ = true; }
2595 ArrayList clauses = new ArrayList ();
2600 | redim_clauses COMMA redim_clause
2602 ArrayList clauses = (ArrayList) ($1);
2610 : invocation_expression
2612 Invocation i = (Invocation) $1;
2613 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2619 : ERASE erase_clauses
2621 ArrayList list = (ArrayList) $2;
2622 foreach(Expression e in list)
2624 Erase r = new Erase (e, lexer.Location);
2633 ArrayList clauses = new ArrayList ();
2638 | erase_clauses COMMA erase_clause
2640 ArrayList clauses = (ArrayList) ($1);
2648 : primary_expression
2653 | continue_statement
2654 | */return_statement
2664 $$ = new Goto (current_block, (string) $2, lexer.Location);
2669 : THROW opt_expression
2671 $$ = new Throw ((Expression) $2, lexer.Location);
2678 $$ = new Exit ((ExitType)$2, lexer.Location);
2683 : DO { $$ = ExitType.DO; }
2684 | FOR { $$ = ExitType.FOR; }
2685 | WHILE { $$ = ExitType.WHILE; }
2686 | SELECT { $$ = ExitType.SELECT; }
2687 | SUB { $$ = ExitType.SUB; }
2688 | FUNCTION { $$ = ExitType.FUNCTION; }
2689 | PROPERTY { $$ = ExitType.PROPERTY; }
2690 | TRY { $$ = ExitType.TRY; }
2693 : RETURN opt_expression
2695 $$ = new Return ((Expression) $2, lexer.Location);
2707 : FOR EACH identifier opt_type_spec IN
2709 oob_stack.Push (lexer.Location);
2711 expression end_of_stmt
2713 Location l = lexer.Location;
2714 LocalVariableReference v = null;
2720 VariableDeclaration decl = new VariableDeclaration ((string) $3,
2721 (Expression) $4, null, lexer.Location, null);
2723 vi = current_block.AddVariable (
2724 (Expression) $4, decl.identifier, current_local_parameters, decl.Location);
2727 if (decl.expression_or_array_initializer is Expression)
2728 expr = (Expression) decl.expression_or_array_initializer;
2729 else if (decl.expression_or_array_initializer == null)
2733 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
2734 expr = new ArrayCreation ((Expression) $4, "", init, decl.Location);
2737 v = new LocalVariableReference (current_block, decl.identifier, l);
2741 Assign a = new Assign (v, expr, decl.Location);
2742 current_block.AddStatement (new StatementExpression (a, lexer.Location));
2747 vi = current_block.GetVariableInfo ((string) $3);
2750 // Get a reference to this variable.
2751 v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
2754 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2763 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2764 Block foreach_block = end_block();
2765 Location l = (Location) oob_stack.Pop ();
2769 f = new Foreach (null, v, (Expression) $7, foreach_block, l);
2773 current_block.AddStatement (f);
2784 if (!UseExtendedSyntax)
2790 if (iterator_container == null){
2791 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2794 iterator_container.SetYields ();
2795 $$ = new Yield ((Expression) $2, lexer.Location);
2800 if (!UseExtendedSyntax)
2806 if (iterator_container == null){
2807 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2810 iterator_container.SetYields ();
2811 $$ = new YieldBreak (lexer.Location);
2817 : SYNCLOCK expression end_of_stmt
2824 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2841 tmp_catch_clauses = (ArrayList) $5;
2850 ArrayList s = new ArrayList ();
2852 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2859 // Now s contains the list of specific catch clauses
2860 // and g contains the general one.
2861 Block b = end_block();
2863 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2870 tmp_block = end_block();
2880 ArrayList s = new ArrayList ();
2881 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2883 if (catch_list != null){
2884 foreach (Catch cc in catch_list) {
2892 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2898 : /* empty */ { $$ = null; }
2905 ArrayList l = new ArrayList ();
2910 | catch_clauses catch_clause
2912 ArrayList l = (ArrayList) $1;
2920 : /* empty */ { $$ = null; }
2925 : /* empty */ { $$ = null; }
2926 | WHEN boolean_expression { $$ = $2; }
2930 : CATCH opt_catch_args opt_when end_of_stmt
2932 Expression type = null;
2936 DictionaryEntry cc = (DictionaryEntry) $2;
2937 type = (Expression) cc.Key;
2938 id = (string) cc.Value;
2941 ArrayList one = new ArrayList ();
2942 Location loc = lexer.Location;
2944 one.Add (new VariableDeclaration (id, type, loc));
2947 current_block = new Block (current_block);
2948 Block b = declare_local_variables (type, one, loc);
2953 opt_statement_list {
2954 Expression type = null;
2956 Block b_catch = current_block;
2959 DictionaryEntry cc = (DictionaryEntry) $2;
2960 type = (Expression) cc.Key;
2961 id = (string) cc.Value;
2965 // FIXME: I can change this for an assignment.
2967 while (current_block != (Block) $1)
2968 current_block = current_block.Parent;
2971 $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, lexer.Location);
2976 : /* empty */ { $$ = null; }
2981 : identifier AS type
2983 $$ = new DictionaryEntry ($3, $1);
2989 : DO opt_do_construct end_of_stmt
2992 oob_stack.Push (lexer.Location);
2995 LOOP opt_do_construct
2997 Expression t_before = (Expression) $2;
2998 Expression t_after = (Expression) $7;
3001 if ((t_before != null) && (t_after != null))
3002 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
3004 if ((t_before == null) && (t_after == null))
3005 t = new BoolLiteral (true);
3007 t = (t_before != null) ? t_before : t_after;
3009 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
3011 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
3012 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
3013 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
3015 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
3020 : /* empty */ { $$ = null; }
3021 | while_or_until boolean_expression
3023 do_type = (DoOptions)$1;
3024 $$ = (Expression) $2;
3029 : WHILE { $$ = DoOptions.WHILE; }
3030 | UNTIL { $$ = DoOptions.UNTIL; }
3037 oob_stack.Push (lexer.Location);
3039 boolean_expression end_of_stmt
3043 Location l = (Location) oob_stack.Pop ();
3044 Block b = end_block();
3045 Expression e = (Expression) $3;
3046 $$ = new While ((Expression) e, (Statement) b, l);
3051 : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
3056 ArrayList VarDeclaration = new ArrayList ();
3057 VarDeclaration.Add (new VariableDeclaration ((string) $2,
3058 (Expression) $3, null, lexer.Location, null));
3060 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
3061 Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3064 oob_stack.Push (lexer.Location);
3070 Block inner_statement = end_block();
3071 Location l = (Location) oob_stack.Pop ();
3072 Expression for_var = (Expression) DecomposeQI ((string)$2, l);
3074 Expression assign_expr = new Assign (for_var, (Expression) $5, l);
3075 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
3076 for_var, (Expression) $7, l);
3077 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
3078 for_var, (Expression) $8, l), l);
3080 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
3081 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
3083 For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
3086 current_block.AddStatement (f);
3095 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
3096 | STEP expression { $$ = $2; }
3105 : if_statement_open opt_then if_statement_rest
3109 | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
3113 Location l = (Location) oob_stack.Pop ();
3114 tmp_expr = (Expression)expr_stack.Pop();
3115 $$ = new If ((Expression) tmp_expr, end_block(), l);
3119 Location l = (Location) oob_stack.Pop ();
3120 tmp_expr = (Expression)expr_stack.Pop();
3121 tmp_block = (Block) tmp_blocks.Pop ();
3122 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3125 | if_statement_open THEN else_pre_embedded_statement
3127 Location l = (Location) oob_stack.Pop ();
3128 tmp_expr = (Expression)expr_stack.Pop();
3129 tmp_block = (Block) tmp_blocks.Pop ();
3130 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3134 pre_embedded_statement
3135 : embedded_statement
3137 Statement s = (Statement) $1;
3139 current_block.AddStatement ((Statement) $1);
3143 opt_else_pre_embedded_statement
3145 | else_pre_embedded_statement
3148 else_pre_embedded_statement
3151 Block bl = end_block();
3152 tmp_blocks.Push(bl);
3156 | ELSE embedded_statement
3158 Block bl = end_block();
3159 tmp_blocks.Push(bl);
3162 Statement s = (Statement) $2;
3163 current_block.AddStatement ((Statement) $2);
3168 : IF boolean_expression
3170 oob_stack.Push (lexer.Location);
3172 tmp_expr = (Expression) $2;
3173 expr_stack.Push(tmp_expr);
3187 Location l = (Location) oob_stack.Pop ();
3188 Expression expr = (Expression)expr_stack.Pop();
3189 $$ = new If ((Expression) expr, (Statement) end_block(), l);
3195 Block bl = end_block();
3196 tmp_blocks.Push(bl);
3202 Location l = (Location) oob_stack.Pop ();
3203 tmp_expr = (Expression)expr_stack.Pop();
3204 tmp_block = (Block) tmp_blocks.Pop();
3205 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
3209 ELSEIF boolean_expression opt_then
3211 tmp_expr = (Expression) $4;
3212 expr_stack.Push(tmp_expr);
3213 tmp_block = end_block();
3214 tmp_blocks.Push(tmp_block);
3217 else_if_statement_rest
3219 Statement stmt = (Statement) statement_stack.Pop();
3220 Block bl = (Block) tmp_blocks.Pop();
3221 Expression expr = (Expression)expr_stack.Pop();
3222 Location l = (Location) oob_stack.Pop ();
3223 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3228 else_if_statement_rest
3233 Location l = (Location) oob_stack.Pop ();
3235 Expression expr = (Expression)expr_stack.Pop();
3236 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3237 statement_stack.Push(stmt);
3243 Block bl = end_block();
3244 tmp_blocks.Push(bl);
3250 Location l = (Location) oob_stack.Pop ();
3252 Expression expr = (Expression)expr_stack.Pop();
3253 Block bl = (Block)tmp_blocks.Pop();
3254 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3255 statement_stack.Push(stmt);
3259 ELSEIF boolean_expression opt_then
3261 expr_stack.Push((Expression) $4);
3262 Block bl = end_block();
3263 tmp_blocks.Push(bl);
3266 else_if_statement_rest
3268 Location l = (Location) oob_stack.Pop ();
3270 Statement tmp_stmt = (Statement)statement_stack.Pop();
3271 Block bl = (Block) tmp_blocks.Pop();
3272 Expression expr = (Expression)expr_stack.Pop();
3273 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3274 statement_stack.Push(stmt);
3279 : SELECT opt_case expression end_of_stmt
3281 oob_stack.Push (lexer.Location);
3282 switch_stack.Push (current_block);
3287 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3288 current_block = (Block) switch_stack.Pop ();
3293 : /* empty */ { $$ = null; }
3294 | case_sections { $$ = $1; }
3298 : case_sections case_section
3300 ArrayList sections = (ArrayList) $1;
3307 ArrayList sections = new ArrayList ();
3321 : CASE case_clauses ends
3327 //Block topmost = current_block;
3328 Block topmost = end_block();
3330 while (topmost.Implicit)
3331 topmost = topmost.Parent;
3333 // FIXME: This is a horrible hack which MUST go
3334 topmost.statements.Add (new Break (lexer.Location));
3335 $$ = new SwitchSection ((ArrayList) $2, topmost);
3338 /* FIXME: we should somehow flag an error
3339 (BC30321 'Case' cannot follow a 'Case Else'
3340 in the same 'Select' statement.)
3341 if Case Else is not the last of the Case clauses
3348 //Block topmost = current_block;
3349 Block topmost = end_block();
3351 while (topmost.Implicit)
3352 topmost = topmost.Parent;
3354 // FIXME: This is a horrible hack which MUST go
3355 topmost.statements.Add (new Break (lexer.Location));
3357 ArrayList a = new ArrayList();
3358 a.Add (new SwitchLabel (null, lexer.Location));
3359 $$ = new SwitchSection ((ArrayList) a, topmost);
3366 ArrayList labels = new ArrayList ();
3371 | case_clauses COMMA case_clause
3373 ArrayList labels = (ArrayList) ($1);
3381 : opt_is comparison_operator expression
3384 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3406 expression_statement
3407 : statement_expression
3414 statement_expression
3415 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3416 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3417 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3420 object_creation_expression
3421 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3423 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3427 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3431 array_creation_expression
3432 : object_creation_expression opt_rank_specifiers array_initializer
3435 ArrayList dims = new ArrayList();
3437 if (n.Arguments != null) {
3438 foreach (Argument a in n.Arguments) {
3443 Expression atype = n.RequestedType;
3446 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
3448 ArrayList init = (ArrayList) $3;
3449 if (init.Count == 0)
3452 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3453 VariableDeclaration.VBFixIndexList (ref dims);
3454 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3458 string rank = VariableDeclaration.BuildRank (dims);
3459 $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location);
3461 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3466 : object_creation_expression
3467 | array_creation_expression
3470 declaration_statement
3471 : local_variable_declaration
3474 DictionaryEntry de = (DictionaryEntry) $1;
3476 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3479 | local_constant_declaration
3482 DictionaryEntry de = (DictionaryEntry) $1;
3484 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3489 local_variable_declaration
3490 : DIM variable_declarators
3492 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3497 local_constant_declaration
3498 : CONST constant_declarators
3501 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3507 constant_declarators
3508 : constant_declarator
3510 ArrayList decl = new ArrayList ();
3516 | constant_declarators COMMA constant_declarator
3518 ArrayList decls = (ArrayList) $1;
3527 : variable_name opt_type_decl opt_variable_initializer
3529 VarName vname = (VarName) $1;
3530 string varname = (string) vname.Name;
3531 current_rank_specifiers = (ArrayList) vname.Rank;
3532 object varinit = $3;
3533 ArrayList a_dims = null;
3535 if (varinit == null)
3537 30438, lexer.Location, "Constant should have a value"
3540 if (vname.Type != null && $2 != null)
3542 30302, lexer.Location,
3543 "Type character cannot be used with explicit type declaration" );
3545 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3547 if (current_rank_specifiers != null)
3549 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3553 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3557 variable_declarators
3558 : variable_declarator
3560 ArrayList decl = new ArrayList ();
3561 decl.AddRange ((ArrayList) $1);
3564 | variable_declarators COMMA variable_declarator
3566 ArrayList decls = (ArrayList) $1;
3567 decls.AddRange ((ArrayList) $3);
3573 : variable_names opt_type_decl opt_variable_initializer
3575 ArrayList names = (ArrayList) $1;
3576 object varinit = $3;
3577 ArrayList VarDeclarations = new ArrayList();
3579 ArrayList a_dims = null;
3581 if ((names.Count > 1) && (varinit != null))
3583 30671, lexer.Location,
3584 "Multiple variables with single type can not have " +
3585 "a explicit initialization" );
3588 foreach (VarName vname in names)
3590 string varname = (string) vname.Name;
3591 current_rank_specifiers = (ArrayList) vname.Rank;
3595 if(vname.Type != null && $2 != null)
3597 30302, lexer.Location,
3598 "Type character cannot be used with explicit type declaration" );
3600 // Some checking is required for particularly weird declarations
3601 // like Dim a As Integer(,)
3603 vartype = (Expression) ((Pair) $2).First;
3605 /*if ($3 != null && $3 is ArrayList)
3606 Report.Error (205, "End of statement expected.");*/
3608 ArrayList args = (ArrayList) ((Pair) $2).Second;
3609 if (current_rank_specifiers != null)
3610 Report.Error (31087, lexer.Location,
3611 "Array types specified in too many places");
3613 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3614 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3616 current_rank_specifiers = new ArrayList ();
3617 current_rank_specifiers.Add (args);
3620 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3622 // if the variable is an array with explicit bound
3623 // and having explicit initialization throw exception
3624 if (current_rank_specifiers != null && varinit != null)
3626 bool broken = false;
3627 foreach (ArrayList exprs in current_rank_specifiers)
3629 foreach (Expression expr in exprs)
3631 if (!((Expression)expr is EmptyExpression ))
3634 30672, lexer.Location,
3635 "Array declared with explicit bound " +
3636 " can not have explicit initialization");
3647 Check for a declaration like Dim a(2) or Dim a(2,3)
3648 If this is the case, we must generate an ArrayCreationExpression
3649 and, in case, add the initializer after the array has been created.
3651 if (VariableDeclaration.IsArrayDecl (this)) {
3652 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3653 a_dims = (ArrayList) current_rank_specifiers;
3654 VariableDeclaration.VBFixIndexLists (ref a_dims);
3655 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3657 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
3660 if (vartype is New) {
3661 if (varinit != null) {
3662 Report.Error (30205, lexer.Location, "End of statement expected");
3668 vartype = ((New)vartype).RequestedType;
3671 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3673 $$ = VarDeclarations;
3680 ArrayList list = new ArrayList ();
3684 | variable_names COMMA variable_name
3686 ArrayList list = (ArrayList) $1;
3693 : identifier opt_type_character opt_array_name_modifier
3695 $$ = new VarName ($1, $2, $3);
3706 $$ = (Expression) $2;
3712 | AS type rank_specifiers
3714 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
3719 : opt_type_with_ranks
3725 New n = new New ((Expression)$3, null, lexer.Location);
3726 $$ = (Expression) n;
3728 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3730 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3731 $$ = (Expression) n;
3733 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3735 ArrayList args = new ArrayList();
3736 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3739 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3740 $$ = (Expression) n;
3744 opt_array_name_modifier
3745 : /* empty */ { $$ = null; }
3746 | array_type_modifier { $$ = $1; }
3750 : rank_specifiers { $$ = $1; }
3753 opt_variable_initializer
3754 : /* empty */ { $$ = null; }
3755 | ASSIGN variable_initializer { $$ = $2; }
3758 variable_initializer
3771 : OPEN_BRACE CLOSE_BRACE
3773 ArrayList list = new ArrayList ();
3776 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3778 $$ = (ArrayList) $2;
3782 variable_initializer_list
3783 : variable_initializer
3785 ArrayList list = new ArrayList ();
3789 | variable_initializer_list COMMA variable_initializer
3791 ArrayList list = (ArrayList) $1;
3812 ArrayList rs = new ArrayList();
3816 | rank_specifiers rank_specifier
3818 ArrayList rs = (ArrayList) $1;
3825 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
3834 ArrayList ds = new ArrayList();
3835 ds.Add (new EmptyExpression());
3840 ArrayList ds = new ArrayList();
3841 ds.Add ((Expression) $1);
3844 | opt_dim_specifiers COMMA expression
3846 ArrayList ds = (ArrayList) $1;
3847 ds.Add ((Expression) $3);
3850 | opt_dim_specifiers COMMA
3852 ArrayList ds = (ArrayList) $1;
3853 ds.Add (new EmptyExpression());
3863 | parenthesized_expression
3866 | qualified_identifier
3868 string name = (string) $1;
3869 $$ = DecomposeQI (name, lexer.Location);
3871 | get_type_expression
3873 | invocation_expression
3883 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3884 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3885 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3886 | NOTHING { $$ = NullLiteral.Null; }
3890 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3891 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3892 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3897 object v = lexer.Value;
3900 $$ = new IntLiteral ((Int32)v);
3901 else if (v is short)
3902 $$ = new ShortLiteral ((Int16)v);
3904 $$ = new LongLiteral ((Int64)v);
3906 Console.WriteLine ("OOPS. Unexpected result from scanner");
3912 : TRUE { $$ = new BoolLiteral (true); }
3913 | FALSE { $$ = new BoolLiteral (false); }
3916 parenthesized_expression
3917 : OPEN_PARENS expression CLOSE_PARENS
3922 : primary_expression DOT identifier
3925 string id_name = (string)$3;
3926 if (id_name.ToUpper() == "NEW")
3928 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3932 if (with_stack.Count > 0) {
3933 Expression e = (Expression) with_stack.Peek();
3934 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3942 /* | primary_expression DOT NEW
3944 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3946 | predefined_type DOT identifier
3949 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3952 if (with_stack.Count > 0) {
3953 Expression e = (Expression) with_stack.Peek();
3954 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3968 invocation_expression
3969 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3972 Location l = lexer.Location;
3973 Report.Error (1, l, "THIS IS CRAZY");
3975 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3976 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3978 | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3981 Location l = lexer.Location;
3982 Report.Error (1, l, "THIS IS CRAZY");
3984 $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
3985 // Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
3990 : MYBASE DOT IDENTIFIER
3992 string id_name = (string) $3;
3993 if (id_name.ToUpper() == "NEW")
3995 $$ = new BaseAccess (id_name, lexer.Location);
3999 $$ = new BaseAccess ("New", lexer.Location);
4007 The 'argument' rule returns an 'empty' argument
4008 of type NoArg (used for default arguments in invocations)
4009 if no arguments are actually passed.
4011 If there is only one argument and it is o type NoArg,
4012 we return a null (empty) list
4014 ArrayList args = (ArrayList) $1;
4015 if (args.Count == 1 &&
4016 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
4026 ArrayList list = new ArrayList ();
4030 | argument_list COMMA argument
4032 ArrayList list = (ArrayList) $1;
4041 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
4043 | BYREF variable_reference
4045 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
4049 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
4051 | ADDRESSOF expression
4053 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
4058 : expression {/* note ("section 5.4"); */ $$ = $1; }
4063 : conditional_xor_expression { $$ = $1; }
4064 /*| assignment_expression*/
4075 $$ = new This (current_block, lexer.Location);
4079 // FIXME: This is actually somewhat different from Me
4080 // because it is for accessing static (classifier) methods/properties/fields
4081 $$ = new This (current_block, lexer.Location);
4086 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
4090 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
4092 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
4094 | cast_operator OPEN_PARENS expression CLOSE_PARENS
4096 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
4101 : CBOOL { $$ = TypeManager.system_boolean_expr; }
4102 | CBYTE { $$ = TypeManager.system_byte_expr; }
4103 | CCHAR { $$ = TypeManager.system_char_expr; }
4104 | CDATE { $$ = TypeManager.system_date_expr; }
4105 | CDBL { $$ = TypeManager.system_double_expr; }
4106 | CDEC { $$ = TypeManager.system_decimal_expr; }
4107 | CINT { $$ = TypeManager.system_int32_expr; }
4108 | CLNG { $$ = TypeManager.system_int64_expr; }
4109 | COBJ { $$ = TypeManager.system_object_expr; }
4110 | CSHORT { $$ = TypeManager.system_int16_expr; }
4111 | CSNG { $$ = TypeManager.system_single_expr; }
4112 | CSTR { $$ = TypeManager.system_string_expr; }
4116 : GETTYPE OPEN_PARENS type CLOSE_PARENS
4118 $$ = new TypeOf ((Expression) $3, lexer.Location);
4122 exponentiation_expression
4123 : primary_expression
4124 | exponentiation_expression OP_EXP primary_expression
4130 prefixed_unary_expression
4131 : exponentiation_expression
4132 | PLUS prefixed_unary_expression
4134 //FIXME: Is this rule correctly defined ?
4135 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
4137 | MINUS prefixed_unary_expression
4139 //FIXME: Is this rule correctly defined ?
4140 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
4144 multiplicative_expression
4145 : prefixed_unary_expression
4146 | multiplicative_expression STAR prefixed_unary_expression
4148 $$ = new Binary (Binary.Operator.Multiply,
4149 (Expression) $1, (Expression) $3, lexer.Location);
4151 | multiplicative_expression DIV prefixed_unary_expression
4153 $$ = new Binary (Binary.Operator.Division,
4154 (Expression) $1, (Expression) $3, lexer.Location);
4158 integer_division_expression
4159 : multiplicative_expression
4160 | integer_division_expression OP_IDIV multiplicative_expression
4162 //FIXME: Is this right ?
4163 $$ = new Binary (Binary.Operator.Division,
4164 (Expression) $1, (Expression) $3, lexer.Location);
4169 : integer_division_expression
4170 | mod_expression MOD integer_division_expression
4172 $$ = new Binary (Binary.Operator.Modulus,
4173 (Expression) $1, (Expression) $3, lexer.Location);
4179 | additive_expression PLUS mod_expression
4181 $$ = new Binary (Binary.Operator.Addition,
4182 (Expression) $1, (Expression) $3, lexer.Location);
4184 | additive_expression MINUS mod_expression
4186 $$ = new Binary (Binary.Operator.Subtraction,
4187 (Expression) $1, (Expression) $3, lexer.Location);
4192 : additive_expression
4193 | concat_expression OP_CONCAT additive_expression
4195 // FIXME: This should only work for String expressions
4196 // We probably need to use something from the runtime
4197 $$ = new Binary (Binary.Operator.Addition,
4198 (Expression) $1, (Expression) $3, lexer.Location);
4204 | shift_expression OP_SHIFT_LEFT concat_expression
4208 | shift_expression OP_SHIFT_RIGHT concat_expression
4214 relational_expression
4216 | relational_expression ASSIGN shift_expression
4218 $$ = new Binary (Binary.Operator.Equality,
4219 (Expression) $1, (Expression) $3, lexer.Location);
4221 | relational_expression OP_NE shift_expression
4223 $$ = new Binary (Binary.Operator.Inequality,
4224 (Expression) $1, (Expression) $3, lexer.Location);
4226 | relational_expression OP_LT shift_expression
4228 $$ = new Binary (Binary.Operator.LessThan,
4229 (Expression) $1, (Expression) $3, lexer.Location);
4231 | relational_expression OP_GT shift_expression
4233 $$ = new Binary (Binary.Operator.GreaterThan,
4234 (Expression) $1, (Expression) $3, lexer.Location);
4236 | relational_expression OP_LE shift_expression
4238 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4239 (Expression) $1, (Expression) $3, lexer.Location);
4241 | relational_expression OP_GE shift_expression
4243 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4244 (Expression) $1, (Expression) $3, lexer.Location);
4246 | relational_expression IS shift_expression
4248 //FIXME: Should be a different op for reference equality but allows tests to use Is
4249 $$ = new Binary (Binary.Operator.Equality,
4250 (Expression) $1, (Expression) $3, lexer.Location);
4252 | TYPEOF shift_expression IS type
4254 //FIXME: Is this rule correctly defined ?
4255 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4260 : relational_expression
4261 | NOT negation_expression
4263 //FIXME: Is this rule correctly defined ?
4264 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4268 conditional_and_expression
4269 : negation_expression
4270 | conditional_and_expression AND negation_expression
4272 $$ = new Binary (Binary.Operator.LogicalAnd,
4273 (Expression) $1, (Expression) $3, lexer.Location);
4275 | conditional_and_expression ANDALSO negation_expression
4276 { // FIXME: this is likely to be broken
4277 $$ = new Binary (Binary.Operator.LogicalAnd,
4278 (Expression) $1, (Expression) $3, lexer.Location);
4282 conditional_or_expression
4283 : conditional_and_expression
4284 | conditional_or_expression OR conditional_and_expression
4286 $$ = new Binary (Binary.Operator.LogicalOr,
4287 (Expression) $1, (Expression) $3, lexer.Location);
4289 | conditional_or_expression ORELSE conditional_and_expression
4290 { // FIXME: this is likely to be broken
4291 $$ = new Binary (Binary.Operator.LogicalOr,
4292 (Expression) $1, (Expression) $3, lexer.Location);
4296 conditional_xor_expression
4297 : conditional_or_expression
4298 | conditional_xor_expression XOR conditional_or_expression
4300 $$ = new Binary (Binary.Operator.ExclusiveOr,
4301 (Expression) $1, (Expression) $3, lexer.Location);
4305 assignment_expression
4306 : prefixed_unary_expression ASSIGN expression
4308 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4310 | prefixed_unary_expression STAR ASSIGN expression
4312 Location l = lexer.Location;
4314 $$ = new CompoundAssign (
4315 Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
4317 | prefixed_unary_expression DIV ASSIGN expression
4319 Location l = lexer.Location;
4321 $$ = new CompoundAssign (
4322 Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
4324 | prefixed_unary_expression PLUS ASSIGN expression
4326 Location l = lexer.Location;
4328 $$ = new CompoundAssign (
4329 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4331 | prefixed_unary_expression MINUS ASSIGN expression
4333 Location l = lexer.Location;
4335 $$ = new CompoundAssign (
4336 Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
4338 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
4340 Location l = lexer.Location;
4342 $$ = new CompoundAssign (
4343 Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
4345 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
4347 Location l = lexer.Location;
4349 $$ = new CompoundAssign (
4350 Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
4352 | prefixed_unary_expression OP_CONCAT ASSIGN expression
4354 Location l = lexer.Location;
4356 // FIXME should be strings only
4357 $$ = new CompoundAssign (
4358 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4360 | prefixed_unary_expression OP_EXP ASSIGN expression
4362 Location l = lexer.Location;
4364 /* TODO: $$ = new CompoundAssign (
4365 Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
4367 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4369 ArrayList args = new ArrayList();
4370 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4373 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4374 n.isDelegate = true;
4375 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4388 : namespace_or_type_name
4390 $$ = DecomposeQI ((string) $1, lexer.Location);
4399 ArrayList types = new ArrayList ();
4404 | type_list COMMA type
4406 ArrayList types = (ArrayList) $1;
4413 namespace_or_type_name
4414 : qualified_identifier
4418 : OBJECT { $$ = TypeManager.system_object_expr; }
4424 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4425 | DATE { $$ = TypeManager.system_date_expr; }
4426 | CHAR { $$ = TypeManager.system_char_expr; }
4427 | STRING { $$ = TypeManager.system_string_expr; }
4433 | floating_point_type
4434 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4439 | BYTE { $$ = TypeManager.system_byte_expr; }
4440 | SHORT { $$ = TypeManager.system_int16_expr; }
4441 | INTEGER { $$ = TypeManager.system_int32_expr; }
4442 | LONG { $$ = TypeManager.system_int64_expr; }
4446 : SINGLE { $$ = TypeManager.system_single_expr; }
4447 | DOUBLE { $$ = TypeManager.system_double_expr; }
4451 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4453 if(tokenizerController.IsAcceptingTokens)
4455 if(in_external_source)
4456 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4458 in_external_source = true;
4460 lexer.EffectiveSource = (string) $4;
4461 lexer.EffectiveLine = (int) $6;
4465 | HASH IDENTIFIER LITERAL_STRING EOL
4467 if(tokenizerController.IsAcceptingTokens)
4469 string id = ($2 as string);
4471 if(!($2 as string).ToLower().Equals("region"))
4472 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4479 | HASH END IDENTIFIER EOL
4481 if(tokenizerController.IsAcceptingTokens)
4483 if( ($3 as string).ToLower().Equals("externalsource")) {
4484 if(!in_external_source)
4485 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4487 in_external_source = false;
4488 lexer.EffectiveSource = lexer.Source;
4489 lexer.EffectiveLine = lexer.Line;
4492 else if(($3 as string).ToLower().Equals("region")) {
4493 if(in_marked_region > 0)
4496 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4499 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4503 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4505 if(tokenizerController.IsAcceptingTokens)
4512 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4515 ifElseStateMachine.HandleToken(tok);
4517 catch(ApplicationException) {
4518 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4521 boolean_literal opt_then EOL
4523 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4527 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4529 ifElseStateMachine.HandleToken(tok);
4531 catch(ApplicationException) {
4532 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4535 boolean_literal opt_then EOL
4537 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4541 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4543 ifElseStateMachine.HandleToken(tok);
4545 catch(ApplicationException) {
4546 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4551 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4555 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4557 ifElseStateMachine.HandleToken(tok);
4559 catch(ApplicationException) {
4560 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4565 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4569 if(tokenizerController.IsAcceptingTokens)
4570 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4572 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4582 public Tokenizer Lexer {
4588 public static Expression DecomposeQI (string name, Location loc)
4592 if (name.IndexOf ('.') == -1){
4593 return new SimpleName (name, loc);
4595 int pos = name.LastIndexOf (".");
4596 string left = name.Substring (0, pos);
4597 string right = name.Substring (pos + 1);
4599 o = DecomposeQI (left, loc);
4601 return new MemberAccess (o, right, loc);
4605 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4607 Block implicit_block;
4608 ArrayList inits = null;
4611 // We use the `Used' property to check whether statements
4612 // have been added to the current block. If so, we need
4613 // to create another block to contain the new declaration
4614 // otherwise, as an optimization, we use the same block to
4615 // add the declaration.
4617 // FIXME: A further optimization is to check if the statements
4618 // that were added were added as part of the initialization
4619 // below. In which case, no other statements have been executed
4620 // and we might be able to reduce the number of blocks for
4621 // situations like this:
4623 // int j = 1; int k = j + 1;
4626 VariableDeclaration.FixupTypes (variable_declarators);
4628 if (current_block.Used) {
4629 implicit_block = new Block (current_block, true, loc, Location.Null);
4630 implicit_block.AddChildVariableNames (current_block);
4632 implicit_block = current_block;
4634 foreach (VariableDeclaration decl in variable_declarators){
4635 Expression type = decl.type;
4636 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4637 if (decl.expression_or_array_initializer != null){
4639 inits = new ArrayList ();
4646 return implicit_block;
4648 foreach (VariableDeclaration decl in inits){
4651 Expression type = decl.type;
4653 if ((decl.expression_or_array_initializer is Expression) ||
4654 (decl.expression_or_array_initializer is New)) {
4655 expr = (Expression) decl.expression_or_array_initializer;
4657 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4659 expr = new ArrayCreation (type, "", init, decl.Location);
4662 LocalVariableReference var;
4663 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4665 assign = new Assign (var, expr, decl.Location);
4667 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4670 return implicit_block;
4673 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4675 Block implicit_block;
4676 VariableDeclaration.FixupTypes (variable_declarators);
4678 if (current_block.Used)
4679 implicit_block = new Block (current_block, true);
4681 implicit_block = current_block;
4683 foreach (VariableDeclaration decl in variable_declarators){
4684 Expression type = decl.type;
4685 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4686 current_local_parameters, decl.Location);
4689 return implicit_block;
4697 public VarName (object n, object t, object r)
4707 // A class used to pass around variable declarations and constants
4709 public class VariableDeclaration {
4710 public string identifier;
4711 public object expression_or_array_initializer;
4712 public Location Location;
4713 public Attributes OptAttributes;
4714 public Expression type;
4715 public ArrayList dims;
4717 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4719 this.identifier = id;
4720 this.expression_or_array_initializer = eoai;
4722 this.OptAttributes = opt_attrs;
4727 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4731 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4735 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4736 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4740 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4742 // FIXME : This is broken: only the first rank is parsed
4743 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4746 public static void FixupTypes (ArrayList vars)
4748 int varcount = vars.Count;
4749 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4751 if (last_var.type == null)
4752 last_var.type = TypeManager.system_object_expr;
4754 Expression cur_type = last_var.type;
4755 int n = varcount - 1;
4758 VariableDeclaration var = (VariableDeclaration) vars[n--];
4759 if (var.type == null)
4760 var.type = cur_type;
4762 cur_type = var.type;
4766 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4770 if (IndexList != null) {
4771 foreach (Expression e in IndexList)
4772 if (!(e is EmptyExpression)) {
4781 public static bool IndexesSpecified (ArrayList ranks)
4785 if (ranks != null) {
4786 foreach (ArrayList IndexList in ranks) {
4787 if (IndexesSpecifiedInRank (IndexList)) {
4796 public static string StripDims (string varname, ref string d)
4798 string res = varname;
4801 if (varname.IndexOf("[") >= 0) {
4802 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4803 res = varname.Substring(0, varname.IndexOf("["));
4809 public static string StripDims (string varname)
4813 return (StripDims(varname, ref dres));
4816 public static string StripIndexesFromDims (string dims)
4818 StringBuilder sb = new StringBuilder();
4820 foreach (char c in dims)
4821 if (c == ',' || c == ']' || c == '[')
4824 return sb.ToString();
4827 public static string BuildRank (ArrayList rank)
4830 return BuildRank(rank, out allEmpty);
4833 public static string BuildRank (ArrayList rank, out bool allEmpty)
4840 foreach (object e in rank) {
4841 if (!(e is EmptyExpression))
4852 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
4856 bool allEmpty = true;
4857 foreach (ArrayList rank in rank_specifiers) {
4859 res = BuildRank (rank, out tmp) + res;
4863 if (!allEmpty && mustBeEmpty)
4864 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
4869 public static void VBFixIndexList (ref ArrayList IndexList)
4871 if (IndexList != null) {
4872 for (int x = 0; x < IndexList.Count; x++) {
4873 Expression e = (Expression) IndexList[x];
4874 if (!(e is EmptyExpression)) {
4875 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4881 public static bool IsArrayDecl (Parser t)
4883 // return (varname.IndexOf("[") >= 0);
4884 return (t.current_rank_specifiers != null);
4887 public static void VBFixIndexLists (ref ArrayList ranks)
4889 if (ranks != null) {
4890 for (int x = 0; x < ranks.Count; x++) {
4891 ArrayList IndexList = (ArrayList) ranks[x];
4892 VBFixIndexList (ref IndexList);
4897 public static void FixupArrayTypes (ArrayList vars)
4899 int varcount = vars.Count;
4902 foreach (VariableDeclaration var in vars) {
4903 if (var.identifier.EndsWith(",")) {
4904 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4905 var.identifier.LastIndexOf(",")) + "]";
4906 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4907 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4914 public Property BuildSimpleProperty (Expression p_type, string name,
4915 Field p_fld, int mod_flags,
4916 Attributes attrs, Location loc)
4919 Block get_block, set_block;
4920 Accessor acc_set, acc_get;
4921 StatementExpression a_set;
4926 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4927 args = new Parameter [1];
4928 args [0] = implicit_value_parameter;
4930 Parameters set_params = new Parameters (args, null, loc);
4931 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4932 (Expression) new SimpleName("value", loc), loc), loc);
4934 set_block = new Block (current_block, set_params, loc, Location.Null);
4935 set_block.AddStatement ((Statement) a_set);
4936 acc_set = new Accessor (set_block, attrs);
4939 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4940 get_block = new Block (current_block, null, loc, Location.Null);
4941 get_block.AddStatement ((Statement) a_get);
4942 acc_get = new Accessor (get_block, attrs);
4944 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4951 current_block = new Block (current_block, current_local_parameters,
4952 lexer.Location, Location.Null);
4959 while (current_block.Implicit)
4960 current_block = current_block.Parent;
4962 res = current_block;
4964 current_block.SetEndLocation (lexer.Location);
4965 current_block = current_block.Parent;
4970 private void AddHandler (Expression evt_definition, Expression handler_exp)
4972 AddHandler (current_block, evt_definition, handler_exp);
4975 void CheckAttributeTarget (string a)
4979 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4983 Location l = lexer.Location;
4984 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4989 private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
4991 Expression evt_target;
4992 Location loc = lexer.Location;
4994 Statement addhnd = (Statement) new AddHandler (evt_id,
4998 b.AddStatement (addhnd);
5001 private void RaiseEvent (string evt_name, ArrayList args)
5003 Location loc = lexer.Location;
5005 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
5006 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
5007 current_block.AddStatement (s);
5010 private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
5012 Expression evt_target;
5013 Location loc = lexer.Location;
5015 Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
5018 b.AddStatement (rmhnd);
5022 // This method is used to get at the complete string representation of
5023 // a fully-qualified type name, hiding inside a MemberAccess ;-)
5024 // This is necessary because local_variable_type admits primary_expression
5025 // as the type of the variable. So we do some extra checking
5027 string GetQualifiedIdentifier (Expression expr)
5029 if (expr is SimpleName)
5030 return ((SimpleName)expr).Name;
5031 else if (expr is MemberAccess)
5032 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
5034 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
5038 private void RemoveHandler (Expression evt_definition, Expression handler_exp)
5040 RemoveHandler (current_block, evt_definition, handler_exp);
5043 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
5045 ConstructorInitializer ci = null;
5048 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
5049 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
5051 if (i.expr is BaseAccess) {
5052 BaseAccess ba = (BaseAccess) i.expr;
5053 if (ba.member == "New" || ba.member == ".ctor") {
5054 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
5058 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
5059 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
5067 void Error_ExpectingTypeName (Location l, Expression expr)
5069 if (expr is Invocation){
5070 Report.Error (1002, l, "; expected");
5072 Report.Error (-1, l, "Invalid Type definition");
5076 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
5080 private void ReportError9998()
5082 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
5085 protected override int parse ()
5087 RootContext.InitializeImports(ImportsList);
5088 current_namespace = new Namespace (null, RootContext.RootNamespace);
5089 current_container = RootContext.Tree.Types;
5090 current_container.Namespace = current_namespace;
5091 oob_stack = new Stack ();
5092 switch_stack = new Stack ();
5093 expr_stack = new Stack ();
5094 tmp_blocks = new Stack();
5095 with_stack = new Stack();
5096 statement_stack = new Stack();
5098 allow_global_attribs = true;
5099 expecting_global_attribs = false;
5100 expecting_local_attribs = false;
5101 local_attrib_section_added = false;
5103 UseExtendedSyntax = name.EndsWith(".mbs");
5104 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
5105 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
5106 OptionCompareBinary = InitialOptionCompareBinary;
5108 lexer = new Tokenizer (input, name, defines);
5110 ifElseStateMachine = new IfElseStateMachine();
5111 tokenizerController = new TokenizerController(lexer);
5113 StringBuilder value = new StringBuilder ();
5115 if (yacc_verbose_flag > 0)
5116 yyparse (lexer, new yydebug.yyDebugSimple ());
5122 catch(MBASException e) {
5123 Report.Error(e.code, e.loc, e.Message);
5125 catch (Exception e) {
5126 if (Report.Stacktrace)
5127 Console.WriteLine(e);
5128 Report.Error (29999, lexer.Location, "Parsing error");
5131 RootContext.VerifyImports();
5133 return Report.Errors;
5139 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
5141 catch(ApplicationException) {
5142 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5145 if(in_external_source)
5146 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
5148 if(in_marked_region > 0)
5149 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
5152 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
5155 tokenizerController.PositionTokenizerCursor(tok, expr);
5157 catch(ApplicationException) {
5158 tok = IfElseStateMachine.Token.EOF;
5160 ifElseStateMachine.HandleToken(tok);
5162 catch(ApplicationException) {
5163 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);