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)
8 // Manjula GHM (mmanjula@novell.com)
9 // Sudharsan V (vsudharsan@novell.com)
11 // Licensed under the terms of the GNU GPL
13 // Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
14 // Copyright (C) 2003, 2004 Novell
17 namespace Mono.MonoBASIC
21 using System.Reflection;
22 using System.Collections;
26 public class MBASException : ApplicationException
31 public MBASException(int code, Location loc, string text) : base(text)
39 /// The MonoBASIC Parser
42 public class Parser : GenericParser
48 /// Current block is used to add statements as we find
54 /// Tmp block is used to store block endings in if/select's
59 /// Tmp block is used to store tmp copies of expressions
64 /// Tmp catch is used to store catch clauses in try..catch..finally
66 ArrayList tmp_catch_clauses;
69 /// Current interface is used by the various declaration
70 /// productions in the interface declaration to "add"
71 /// the interfaces as we find them.
73 Interface current_interface;
76 /// This is used by the unary_expression code to resolve
77 /// a name against a parameter.
79 Parameters current_local_parameters;
82 /// This are used when parsing parameters in property
85 Parameters set_parameters;
86 Parameters get_parameters;
89 /// This is used by the sub_header parser to store modifiers
90 /// to be passed to sub/constructor
92 int current_modifiers;
95 /// This is used by the sub_header parser to store attributes
96 /// to be passed to sub/constructor
98 Attributes current_attributes;
101 /// Using during property parsing to describe the implicit
102 /// value parameter that is passed to the "set" accessor
105 string get_implicit_value_parameter_name;
108 // Using during property parsing to describe the implicit
109 // value parameter that is passed to the "set" and "get"accesor
110 // methods (properties and indexers).
112 Expression get_implicit_value_parameter_type;
115 /// Using during property parsing to describe the implicit
116 /// value parameter that is passed to the "set" accessor
119 string set_implicit_value_parameter_name;
122 // Using during property parsing to describe the implicit
123 // value parameter that is passed to the "set" and "get"accesor
124 // methods (properties and indexers).
126 Expression set_implicit_value_parameter_type;
128 // An out-of-band stack.
132 ArrayList current_rank_specifiers;
134 //To handle the End of a block
135 // We use grammer, priority, strings, and an integer called Parenta
137 // FIX ME: Need to implement some better method than this and in
138 // some cases parser will come out without proceeding further
139 // if it comes acorss error.
142 // 1) The value for corresponding blocks with which it will be accessed...
143 // In case of any more addition to end of blocks... add it at the end
145 public enum Start_block {
171 // In case of any more addition to end of blocks... add it at the end
173 public string[,] end_blocks = {
174 { "empty" , "empty" },
178 { "Sub" , "End Sub" },
179 { "Module" , "End Module" },
180 { "NameSpace" , "End NameSpace" },
181 { "Class" , "End Class" },
182 { "Function" , "End Function" },
183 { "Structure" , "End Structure" },
184 { "Enum" , "End Enum" },
185 { "Interface" , "End Interface" },
186 { "Property" , "End Property" },
187 { "With" , "End With" },
188 { "SyncLock" , "End SyncLock" },
189 { "Try" , "End Try" },
190 { "While" , "End While" },
191 { "Select" , "End Select" },
192 { "Set" , "End Set" },
193 { "Get" , "End Get" }
198 // 1) Error number for End of block missing
199 // 2) Extra End of Block
200 // 3) Priority for the end 0f blocks
201 // In case of any more addition to end of blocks... add it at the end
203 public int[,] error_end_blocks = {
204 { 29999 , 29999 , 0 },
205 { 30084 , 30092 , 1 },
206 { 30083 , 30091 , 1 },
207 { 30081 , 30087 , 1 },
208 { 30289 , 30429 , 3 },
209 { 30625 , 30622 , 5 },
210 { 30626 , 30623 , 6 },
211 { 30481 , 30460 , 4 },
212 { 30027 , 30430 , 3 },
213 { 30624 , 30621 , 4 },
214 { 30185 , 30184 , 1 },
215 { 30253 , 30252 , 3 },
216 { 30025 , 30431 , 3 },
217 { 30085 , 30093 , 1 },
218 { 30675 , 30674 , 1 },
219 { 30384 , 30383 , 1 },
220 { 30082 , 30090 , 1 },
221 { 30095 , 30088 , 1 },
222 { 30633 , 30632 , 2 },
223 { 30631 , 30630 , 2 }
228 Stack loc_end_of_block;
229 Stack loc_temp_block;
239 // Expression stack for nested ifs
243 Stack statement_stack;
245 // A stack for With expressions.
250 // Hash table for const preprocessing directive
252 public static Hashtable constPreDir = new Hashtable();
254 static public bool InitialOptionExplicit = false;
255 static public bool InitialOptionStrict = false;
256 static public bool InitialOptionCompareBinary = true;
257 static public ArrayList ImportsList = null;
261 bool OptionCompareBinary;
263 static public bool UseExtendedSyntax; // for ".mbs" files
265 bool implicit_modifiers;
267 public override string[] extensions()
269 string [] list = { ".vb", ".mbs" };
273 bool in_external_source = false;
274 int in_marked_region = 0;
276 TokenizerController tokenizerController;
277 IfElseStateMachine ifElseStateMachine;
280 public class IfElseStateMachine {
304 public static Hashtable errStrings = new Hashtable();
307 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
309 static IfElseStateMachine()
311 // FIXME: Fix both the error nos and the error strings.
312 // Currently the error numbers and the error strings are
313 // just placeholders for getting the state-machine going.
315 errStrings.Add(0, "");
316 errStrings.Add(30012, "#If must end with a matching #End If");
317 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
318 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
319 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
320 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
322 errTable[(int)State.START, (int)Token.IF] = 0;
323 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
324 errTable[(int)State.START, (int)Token.ELSE] = 30028;
325 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
326 errTable[(int)State.START, (int)Token.EOF] = 0;
328 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
329 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
330 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
331 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
332 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
334 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
335 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
336 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
337 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
338 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
340 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
341 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
342 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
343 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
344 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
346 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
347 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
348 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
349 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
350 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
353 public IfElseStateMachine()
357 stateStack = new Stack();
358 stateStack.Push(state);
361 // The parameter here need not be qualified with IfElseStateMachine
362 // But it hits a bug in mcs. So temporarily scoping it so that builds
365 public void HandleToken(IfElseStateMachine.Token tok)
367 err = (int) errTable[(int)state, (int)tok];
370 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
372 if(tok == Token.IF) {
373 stateStack.Push(state);
376 else if(tok == Token.ENDIF) {
377 state = (State)stateStack.Pop();
389 public string ErrString {
391 return (string) errStrings[err];
397 public class TokenizerController {
401 public bool CanAcceptTokens;
402 public bool CanSelectBlock;
409 public TokenizerController(Tokenizer lexer)
412 stateStack = new Stack();
414 currentState.CanAcceptTokens = true;
415 currentState.CanSelectBlock = true;
417 stateStack.Push(currentState);
422 return (State)stateStack.Peek();
426 public bool IsAcceptingTokens {
428 return currentState.CanAcceptTokens;
432 public void PositionCursorAtNextPreProcessorDirective()
434 lexer.PositionCursorAtNextPreProcessorDirective();
437 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
439 if(tok == IfElseStateMachine.Token.ENDIF) {
440 currentState = (State)stateStack.Pop();
442 if(currentState.CanAcceptTokens)
445 PositionCursorAtNextPreProcessorDirective();
450 if(tok == IfElseStateMachine.Token.IF) {
451 stateStack.Push(currentState);
453 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
454 currentState.CanSelectBlock = true;
457 if(parentState.CanAcceptTokens &&
458 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
460 currentState.CanAcceptTokens = true;
461 currentState.CanSelectBlock = false;
465 currentState.CanAcceptTokens = false;
466 PositionCursorAtNextPreProcessorDirective();
472 bool allow_global_attribs = true;
474 bool expecting_global_attribs = false;
475 bool expecting_local_attribs = false;
477 bool local_attrib_section_added = false;
481 %token NONE /* This token is never returned by our lexer */
482 %token ERROR // This is used not by the parser, but by the tokenizer.
486 *These are the MonoBASIC keywords
579 %token NOTINHERITABLE
580 %token NOTOVERRIDABLE
636 %token YIELD // MonoBASIC extension
640 /* MonoBASIC single character operators/punctuation. */
642 %token OPEN_BRACKET "["
643 %token CLOSE_BRACKET "]"
644 %token OPEN_PARENS "("
645 %token OPEN_BRACE "{"
646 %token CLOSE_BRACE "}"
647 %token CLOSE_PARENS ")"
661 %token OP_IDIV "\\" //FIXME: This should be "\"
663 %token EXCLAMATION "!"
666 %token LONGTYPECHAR "&"
668 %token SINGLETYPECHAR "!"
669 %token NUMBER_SIGN "#"
670 %token DOLAR_SIGN "$"
672 %token ATTR_ASSIGN ":="
674 /* MonoBASIC multi-character operators. */
679 //%token OP_MODULUS //"mod"
681 /* VB.NET 2003 new bit-shift operators */
682 %token OP_SHIFT_LEFT "<<"
683 %token OP_SHIFT_RIGHT ">>"
686 %token LITERAL_INTEGER "int literal"
687 %token LITERAL_SINGLE "float literal"
688 %token LITERAL_DOUBLE "double literal"
689 %token LITERAL_DECIMAL "decimal literal"
690 %token LITERAL_CHARACTER "character literal"
691 %token LITERAL_STRING "string literal"
692 %token LITERAL_DATE "datetime literal"
696 /* Add precedence rules to solve dangling else s/r conflict */
705 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
707 %left STAR DIV PERCENT
708 %right BITWISE_NOT CARRET UMINUS
709 %nonassoc OP_INC OP_DEC
711 %left OPEN_BRACKET OPEN_BRACE
716 %start compilation_unit
720 : logical_end_of_line
727 | logical_end_of_line pp_directive
731 : logical_end_of_line _mark_
732 opt_option_directives
733 opt_imports_directives
739 | logical_end_of_line _mark_
740 opt_option_directives
741 opt_imports_directives
749 opt_option_directives
756 | option_directives option_directive
760 : option_explicit_directive
761 | option_strict_directive
762 | option_compare_directive
763 | OPTION _mark_ logical_end_of_line
765 Report.Error(30206 ,(Location)$2, "Option must be followed by 'Compare' or 'Explicit' or 'Strict'");
767 | OPTION _mark_ IDENTIFIER logical_end_of_line
769 Report.Error(30206 ,(Location)$2, "Option must be followed by 'Compare' or 'Explicit' or 'Strict'");
799 option_explicit_directive
800 : OPTION EXPLICIT _mark_ on_off logical_end_of_line
802 if (!UseExtendedSyntax)
803 OptionExplicit = (bool)$4;
807 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
812 option_strict_directive
813 : OPTION STRICT _mark_ on_off logical_end_of_line
815 if (!UseExtendedSyntax)
816 OptionStrict = (bool)$4;
820 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
824 option_compare_directive
825 : OPTION COMPARE text_or_binary logical_end_of_line
827 OptionCompareBinary = (bool)$3;
838 | declarations declaration
842 : declaration_qualifiers
844 // FIXME: Need to check declaration qualifiers for multi-file compilation
845 // FIXME: Qualifiers cannot be applied to namespaces
846 allow_global_attribs = false;
848 namespace_declaration
849 |declaration_qualifiers _mark_
851 // FIXME: Need to check declaration qualifiers for multi-file compilation
852 allow_global_attribs = false;
854 type_spec_declaration
859 if ($4 is Class || $4 is Struct || $4 is Module ){
860 TypeContainer c = (TypeContainer) $4;
861 mod_flags = c.ModFlags;
866 if ((mod_flags & (Modifiers.PRIVATE)) != 0){
869 "Namespace elements cannot be explicitly " +
870 "declared private in '" + name + "'");
872 else if ((mod_flags & (Modifiers.PROTECTED)) != 0){
875 "Namespace elements cannot be explicitly " +
876 "declared protected in '" + name + "'");
891 : PERCENT { $$ = TypeManager.system_int32_expr; }
892 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
893 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
894 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
895 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
896 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
900 : /* empty */ { $$ = null; }
901 | type_character { $$ = $1; }
907 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
909 $$ = (($1).ToString ()) + "." + ($3.ToString ());
913 opt_imports_directives
920 | imports_directives imports_directive
924 : IMPORTS imports_terms logical_end_of_line
929 | imports_terms COMMA imports_term
933 : namespace_or_type_name
935 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
937 | identifier _mark_ ASSIGN namespace_or_type_name
939 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $4, (Location)$2);
941 | identifier _mark_ ASSIGN
943 Report.Error(30203, (Location)$2, "Alias Statement no complete: Expression Expected");
947 Report.Error(30203, (Location)$1, "No namespace imported: Expression Expected");
952 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
953 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
954 | OPEN_PARENS _mark_ opt_formal_parameter_list CLOSE_PARENS { $$ = $3; }
957 Report.Error(30203,(Location)$2, "Identifier Expected");
958 $$ = Parameters.EmptyReadOnlyParameters;
960 | OPEN_PARENS _mark_ opt_formal_parameter_list error
962 Report.Error(30198,(Location)$2, "'(' is not having a matching ')'");
965 | error _mark_ opt_formal_parameter_list CLOSE_PARENS
967 Report.Error(30205,(Location)$2, "')' is not having a matching '('");
977 local_attrib_section_added = false;
986 expecting_local_attribs = false;
987 expecting_global_attribs = false;
991 if (expecting_local_attribs) {
992 local_attrib_section_added = true;
993 allow_global_attribs = false;
995 $$ = new Attributes ((ArrayList) $1);
998 if (expecting_global_attribs) {
1000 CodeGen.AddGlobalAttributes ((ArrayList) $1);
1003 expecting_local_attribs = false;
1004 expecting_global_attribs = false;
1006 | attribute_sections
1008 $$ = lexer.Location;
1014 ArrayList attrs = (ArrayList) $3;
1016 if (expecting_local_attribs) {
1017 if (local_attrib_section_added) {
1018 expecting_local_attribs = false;
1019 expecting_global_attribs = false;
1020 Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
1025 $$ = new Attributes (attrs);
1027 ((Attributes) $1).Add (attrs);
1029 local_attrib_section_added = true;
1030 allow_global_attribs = false;
1033 if (expecting_global_attribs) {
1035 CodeGen.AddGlobalAttributes ((ArrayList) $3);
1039 expecting_local_attribs = false;
1040 expecting_global_attribs = false;
1045 : OP_LT _mark_ attribute_list OP_GT opt_end_of_stmt
1049 if (expecting_global_attribs && !(bool) $5) {
1050 Report.Error (30205, (Location)$2, "End of statement expected");
1054 if (expecting_local_attribs) {
1056 Report.Error (32035, (Location)$2, "Use a line continuation after the attribute specifier to apply it to the following statement.");
1067 : /* empty */ { $$ = false; }
1068 | end_of_stmt { $$ = true; }
1074 ArrayList attrs = null;
1076 attrs = new ArrayList ();
1081 | attribute_list COMMA attribute
1083 ArrayList attrs = null;
1086 attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
1095 : namespace_or_type_name
1097 $$ = lexer.Location;
1099 opt_attribute_arguments
1103 if (expecting_global_attribs)
1104 Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
1106 expecting_local_attribs = true;
1107 $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
1110 | attribute_target_specifier
1112 $$ = lexer.Location;
1115 namespace_or_type_name
1117 $$ = lexer.Location;
1119 opt_attribute_arguments
1123 string attribute_target = (string) $1;
1124 if (attribute_target != "assembly" && attribute_target != "module") {
1125 Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
1128 if (!allow_global_attribs) {
1129 Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
1133 if (expecting_local_attribs) {
1134 Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
1138 expecting_global_attribs = true;
1139 $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
1143 attribute_target_specifier
1144 : ASSEMBLY { $$ = "assembly"; }
1145 | MODULE { $$ = "module"; }
1146 | namespace_or_type_name
1150 opt_attribute_arguments
1151 : /* empty */ { $$ = null; }
1152 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
1158 opt_attribute_arguments_list
1160 | attribute_arguments_list
1163 attribute_arguments_list
1164 : positional_argument_list
1166 ArrayList args = new ArrayList ();
1171 | positional_argument_list COMMA named_argument_list
1173 ArrayList args = new ArrayList ();
1179 | named_argument_list
1181 ArrayList args = new ArrayList ();
1189 positional_argument_list
1190 : constant_expression
1192 ArrayList args = new ArrayList ();
1193 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
1197 | positional_argument_list COMMA constant_expression
1199 ArrayList args = (ArrayList) $1;
1200 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
1209 ArrayList args = new ArrayList ();
1214 | named_argument_list COMMA named_argument
1216 ArrayList args = (ArrayList) $1;
1224 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
1226 $$ = new DictionaryEntry (
1228 new Argument ((Expression) $3, Argument.AType.Expression));
1232 namespace_declaration
1233 : NAMESPACE _mark_ qualified_identifier logical_end_of_line
1235 push_into_stack((int)Start_block.NAMESPACE, (Location)$2);
1236 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
1242 pop_out_of_stack((int)$7, lexer.Location);
1246 current_namespace = current_namespace.Parent;
1250 declaration_qualifiers
1254 current_attributes = (Attributes) $1;
1255 current_modifiers = (int) $2;
1259 type_spec_declaration
1261 | module_declaration
1262 | interface_declaration
1263 | delegate_declaration
1264 | struct_declaration
1269 : CLASS identifier _mark_ end_of_stmt opt_inherits opt_implements
1271 // Module members are static by default, but Class *can't* be declared static
1272 // so we must fix it, if mbas was the one actually responsible for this
1273 // instead of triggering an error.
1274 push_into_stack((int)Start_block.CLASS, (Location)$3);
1276 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1277 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1282 name = MakeName ((string) $2);
1283 new_class = new Class (current_container, name, current_modifiers,
1284 (Attributes) current_attributes, (Location)$3);
1286 current_container = new_class;
1287 current_container.Namespace = current_namespace;
1288 RootContext.Tree.RecordDecl (name, new_class);
1290 opt_class_member_declarations
1293 pop_out_of_stack((int)$9, lexer.Location);
1297 Class new_class = (Class) current_container;
1299 ArrayList bases = (ArrayList) $5;
1301 ArrayList ifaces = (ArrayList) $6;
1302 if (ifaces != null){
1304 bases.AddRange(ifaces);
1308 new_class.Bases = bases;
1310 current_container = current_container.Parent;
1311 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1318 : /* empty */ { $$ = null; }
1319 | INHERITS type_list end_of_stmt { $$ = $2; }
1323 : /* empty */ { $$ = null; }
1324 | IMPLEMENTS type_list end_of_stmt { $$ = $2; }
1328 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1329 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1334 | modifiers modifier
1339 if ((m1 & m2) != 0) {
1340 Location l = lexer.Location;
1341 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1343 $$ = (int) (m1 | m2);
1348 : PUBLIC { $$ = Modifiers.PUBLIC; }
1349 | PROTECTED { $$ = Modifiers.PROTECTED; }
1350 | PRIVATE { $$ = Modifiers.PRIVATE; }
1351 | SHARED { $$ = Modifiers.STATIC; }
1352 | FRIEND { $$ = Modifiers.INTERNAL; }
1353 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1354 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1355 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1356 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1357 | OVERLOADS { $$ = Modifiers.NEW; }
1358 | SHADOWS { $$ = Modifiers.SHADOWS; }
1359 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1360 | READONLY { $$ = Modifiers.READONLY; }
1361 | DEFAULT { $$ = Modifiers.DEFAULT; }
1362 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1366 : MODULE _mark_ identifier logical_end_of_line
1368 push_into_stack((int)Start_block.MODULE, (Location)$2);
1371 name = MakeName((string) $3);
1372 new_module = new Module(current_container,
1374 current_modifiers, // already checks then
1375 (Attributes) current_attributes,
1377 current_container = new_module;
1378 current_container.Namespace = current_namespace;
1379 RootContext.Tree.RecordDecl(name, new_module);
1381 opt_module_member_declarations
1384 pop_out_of_stack((int)$7, lexer.Location);
1388 Module new_module = (Module)current_container;
1390 current_container = current_container.Parent;
1391 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1393 TypeManager.AddStandardModule(new_module);
1399 opt_module_member_declarations
1401 | module_member_declarations
1404 module_member_declarations
1405 : module_member_declaration
1406 | module_member_declarations module_member_declaration
1409 module_member_declaration
1413 current_attributes = (Attributes) $1;
1414 current_modifiers = ((int)$2) | Modifiers.STATIC;
1415 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1416 implicit_modifiers = (!explicit_static);
1418 module_member_declarator
1420 implicit_modifiers = false;
1425 module_member_declarator
1426 : constructor_declaration
1427 | method_declaration
1429 Method method = (Method) $1;
1430 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1433 | withevents_declaration /* This is a field but must be treated specially, see below */
1434 | constant_declaration
1435 | property_declaration
1437 | type_spec_declaration
1440 constant_declaration
1441 : CONST constant_declarators end_of_stmt
1443 // Module members are static by default, but constants *can't* be declared static
1444 // so we must fix it, if mbas was the one actually responsible for this
1445 // instead of triggering an error.
1446 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1447 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1449 int mod = (int) current_modifiers;
1451 // Structure members are Public by default
1452 if ((current_container is Struct) && (mod == 0))
1453 mod = Modifiers.PUBLIC;
1455 ArrayList consts = (ArrayList) $2;
1456 if(consts.Count > 0)
1458 VariableDeclaration.FixupTypes ((ArrayList) $2);
1459 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1461 foreach (VariableDeclaration var in (ArrayList) $2){
1462 Location l = var.Location;
1463 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1464 (Expression)var.expression_or_array_initializer,
1465 mod, (Attributes) null, l);
1467 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1473 opt_class_member_declarations
1475 | class_member_declarations
1478 class_member_declarations
1479 : class_member_declaration
1480 | class_member_declarations class_member_declaration
1483 class_member_declaration
1487 current_attributes = (Attributes) $1;
1488 current_modifiers = (int) $2;
1490 class_member_declarator
1496 class_member_declarator
1497 : constructor_declaration
1498 | method_declaration
1500 Method method = (Method) $1;
1501 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1504 | constant_declaration
1505 | property_declaration
1507 | withevents_declaration /* This is a field but must be treated specially, see below */
1508 | type_spec_declaration
1515 | must_override_declaration
1518 must_override_declaration
1519 : must_override_sub_declaration
1520 | must_override_func_declaration
1523 must_override_sub_declaration
1524 : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause _mark_ logical_end_of_line
1526 if (current_container is Module)
1527 Report.Error (30433, (Location)$6, "Methods in a Module cannot be declared 'MustOverride'.");
1529 if (current_container is Struct)
1530 Report.Error (435, (Location)$6, "Methods in a Structure cannot be declared 'MustOverride'.");
1532 current_modifiers |= Modifiers.ABSTRACT;
1534 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1535 (Parameters) $4, null, (ArrayList) $5, (Location)$6);
1537 if (!(current_container is Class))
1538 Report.Error (9999, (Location)$6, "THIS SHOULD NEVER HAPPEN!");
1545 must_override_func_declaration
1546 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
1548 Expression ftype = ($7 == null) ? (($4 == null) ? TypeManager.
1549 system_object_expr : (Expression) $4 ) : (Expression) $7;
1551 if (current_container is Module)
1552 Report.Error (30433, (Location)$6,"Methods in a Module cannot be declared 'MustOverride'.");
1554 if (current_container is Struct)
1555 Report.Error (435, (Location)$6,"Methods in a Structure cannot be declared 'MustOverride'.");
1557 current_modifiers |= Modifiers.ABSTRACT;
1559 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1560 (string) $3,(Parameters) $5, null, (ArrayList) $8,
1563 if (!(current_container is Class))
1564 Report.Error (9999, (Location)$6,"THIS SHOULD NEVER HAPPEN!");
1571 : SUB identifier _mark_ opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1573 push_into_stack((int)Start_block.SUB, (Location)$3);
1574 current_local_parameters = (Parameters) $4;
1577 // Structure members are Public by default
1578 if ((current_container is Struct) && (current_modifiers == 0))
1579 current_modifiers = Modifiers.PUBLIC;
1585 pop_out_of_stack((int)$10, lexer.Location);
1589 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1590 (Parameters) current_local_parameters, (Attributes) current_attributes,
1591 (ArrayList) $6, (Location)$3);
1593 method.Block = (Block) end_block();
1597 // we have an event handler to take care of
1599 Expression handles_exp = (Expression) $5;
1600 Location loc = (Location)$3;
1602 if (handles_exp is MemberAccess) {
1603 string evt_def = ((MemberAccess)$5).ToString();
1604 int pos = evt_def.LastIndexOf (".");
1605 string evt_target = evt_def.Substring (0, pos);
1608 if (current_container.Properties != null) {
1609 foreach (Property p in current_container.Properties) {
1610 if (p.Name == evt_target) {
1613 Statement addhnd = (Statement) new AddHandler ((Expression) $5,
1614 DecomposeQI((string) $2, loc),
1617 current_container.AddEventHandler (addhnd);
1625 Report.Error(30506, (Location)$3,
1626 evt_target + " is not declared with WithEvents");
1628 } else if (handles_exp is BaseAccess) {
1629 Statement addhnd = (Statement) new AddHandler ((Expression) $5,
1630 DecomposeQI((string) $2, loc),
1633 current_container.AddEventHandler (addhnd);
1641 : FUNCTION identifier opt_type_character
1642 opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
1644 push_into_stack((int)Start_block.FUNCTION, (Location)$5);
1645 current_local_parameters = (Parameters) $4;
1648 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
1650 // Structure members are Public by default
1651 if ((current_container is Struct) && (current_modifiers == 0))
1652 current_modifiers = Modifiers.PUBLIC;
1653 // Add local var declaration
1655 ArrayList retval = new ArrayList ();
1656 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, (Location)$5));
1657 declare_local_variables ((Expression) ftype, retval, (Location)$5);
1662 pop_out_of_stack((int)$11, lexer.Location);
1666 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
1668 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1669 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1670 (ArrayList) $7, (Location)$5);
1671 method.Block = end_block();
1677 : STRUCTURE _mark_ identifier end_of_stmt
1678 opt_implement_clause
1680 push_into_stack((int)Start_block.STRUCTURE, (Location)$2);
1682 string full_struct_name = MakeName ((string) $3);
1684 // Module members are static by default, but structures *can't* be declared static
1685 // so we must fix it, if mbas was the one actually responsible for this
1686 // instead of triggering an error.
1687 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1688 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1690 new_struct = new Struct (current_container, full_struct_name,
1691 (int) current_modifiers,
1692 (Attributes) current_attributes, (Location)$2);
1693 current_container = new_struct;
1694 current_container.Namespace = current_namespace;
1695 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1697 opt_struct_member_declarations
1699 Struct new_struct = (Struct) current_container;
1702 new_struct.Bases = (ArrayList) $5;
1704 current_container = current_container.Parent;
1705 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1710 pop_out_of_stack((int)$9, lexer.Location);
1715 opt_struct_member_declarations
1717 | struct_member_declarations
1720 struct_member_declarations
1721 : struct_member_declaration
1722 | struct_member_declarations struct_member_declaration
1725 struct_member_declaration
1727 struct_member_declarator
1730 struct_member_declarator
1732 | constant_declaration
1733 | constructor_declaration
1734 | method_declaration
1736 Method method = (Method) $1;
1737 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1739 | property_declaration
1741 | type_spec_declaration
1744 * This is only included so we can flag error 575:
1745 * destructors only allowed on class types
1747 //| destructor_declaration
1751 : EVENT identifier _mark_ AS type opt_implement_clause logical_end_of_line
1753 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $5, (Location)$3);
1755 Event e = new Event ((Expression) $5, var.identifier,
1756 null, current_modifiers,
1757 current_attributes, (ArrayList) $6,
1760 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1762 | EVENT identifier _mark_ opt_params opt_implement_clause logical_end_of_line
1764 string delName = null;
1767 delName = (string) $2;
1768 delName = delName + "EventHandler";
1769 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1770 (current_container, TypeManager.system_void_expr,
1771 (int) current_modifiers, MakeName(delName), (Parameters) $4,
1772 (Attributes) current_attributes, (Location)$3);
1774 del.Namespace = current_namespace;
1775 CheckDef (current_container.AddDelegate (del), del.Name, (Location)$3);
1777 ArrayList impls = (ArrayList) $5;
1778 if (impls.Count > 1) {
1779 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1780 "' can not be implemented with Event '" +
1781 (string) $2 + "', since it's delegate type does not match " +
1782 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1783 Report.Error (31407, (Location)$3, expstr);
1785 Expression impl = (Expression) impls[0];
1786 delName = impl.ToString();
1787 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1788 delName = delName + "EventHandler";
1791 Event e = new Event (DecomposeQI (delName, (Location)$3),
1793 null, current_modifiers,
1794 current_attributes, (ArrayList) $5,
1797 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1802 : ENUM _mark_ identifier opt_type_spec logical_end_of_line
1803 opt_enum_member_declarations
1805 push_into_stack((int)Start_block.ENUM, (Location)$2);
1806 Location enum_location = (Location)$2;
1807 string full_name = MakeName ((string) $3);
1808 Expression enum_type = ($4 == null) ? TypeManager.system_int32_expr : (Expression) $4;
1809 ArrayList enum_members = (ArrayList) $6;
1811 if (enum_members.Count == 0)
1812 Report.Error (30280, enum_location,
1813 "Enum can not have empty member list");
1815 // Module members are static by default, but enums *can't* be declared static
1816 // so we must fix it if mbas was the one actually responsible for this
1817 // instead of triggering an error.
1818 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1819 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1821 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1822 (int) current_modifiers, full_name,
1823 (Attributes) current_attributes, enum_location);
1825 foreach (VariableDeclaration ev in enum_members) {
1826 Location loc = (Location) ev.Location;
1828 CheckDef (e.AddEnumMember (ev.identifier,
1829 (Expression) ev.expression_or_array_initializer,
1830 loc, ev.OptAttributes), ev.identifier, loc);
1833 e.Namespace = current_namespace;
1835 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1836 RootContext.Tree.RecordDecl (full_name, e);
1841 pop_out_of_stack((int)$8,lexer.Location);
1846 opt_enum_member_declarations
1847 : /* empty */ { $$ = new ArrayList (); }
1848 | enum_member_declarations { $$ = $1; }
1851 enum_member_declarations
1852 : enum_member_declaration
1854 ArrayList l = new ArrayList ();
1859 | enum_member_declarations enum_member_declaration
1861 ArrayList l = (ArrayList) $1;
1869 enum_member_declaration
1870 : opt_attributes identifier _mark_ logical_end_of_line
1872 $$ = new VariableDeclaration ((string) $2, null, (Location)$3, (Attributes) $1);
1874 | opt_attributes identifier
1876 $$ = lexer.Location;
1878 ASSIGN expression logical_end_of_line
1880 $$ = new VariableDeclaration ((string) $2, (Expression)$5, (Location)$3, (Attributes) $1);
1884 interface_declaration
1885 : INTERFACE _mark_ identifier logical_end_of_line
1887 push_into_stack((int)Start_block.INTERFACE, (Location)$2);
1888 Interface new_interface;
1889 string full_interface_name = MakeName ((string) $3);
1891 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1892 (Attributes) current_attributes, (Location)$2);
1893 if (current_interface != null) {
1894 Report.Error (-2, (Location)$2, "Internal compiler error: interface inside interface");
1896 current_interface = new_interface;
1897 new_interface.Namespace = current_namespace;
1898 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1903 Interface new_interface = (Interface) current_interface;
1906 new_interface.Bases = (ArrayList) $6;
1908 current_interface = null;
1909 CheckDef (current_container.AddInterface (new_interface),
1910 new_interface.Name, new_interface.Location);
1915 pop_out_of_stack((int)$9, lexer.Location);
1921 : /* empty */ { $$ = null; }
1927 | interface_bases interface_base
1929 ArrayList bases = (ArrayList) $1;
1930 bases.AddRange ((ArrayList) $2);
1936 : INHERITS type_list logical_end_of_line { $$ = $2; }
1940 : opt_interface_member_declarations
1943 opt_interface_member_declarations
1945 | interface_member_declarations
1948 interface_member_declarations
1949 : interface_member_declaration
1950 | interface_member_declarations interface_member_declaration
1953 interface_member_declaration
1957 current_attributes = (Attributes) $1;
1958 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
1960 interface_member_declarator
1966 interface_member_declarator
1967 : interface_method_declaration
1969 Method m = (Method) $1;
1970 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1972 | interface_property_declaration
1973 | interface_event_declaration
1976 interface_method_declaration
1977 : SUB identifier opt_params _mark_ logical_end_of_line
1979 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1980 (Parameters) $3, current_attributes, null, (Location)$4);
1984 | FUNCTION identifier opt_type_character opt_params _mark_ opt_type_with_ranks logical_end_of_line
1986 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.
1987 system_object_expr : (Expression) $3 ) : (Expression) $6;
1989 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1990 (string) $2,(Parameters) $4, current_attributes, null,
1997 interface_property_declaration
1998 : PROPERTY identifier _mark_ opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
2000 Expression ftype = ($6 == null) ? (($4 == null) ?
2001 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
2003 current_local_parameters = (Parameters) $5;
2004 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2005 get_parameters = current_local_parameters.Copy ((Location)$3);
2006 set_parameters = current_local_parameters.Copy ((Location)$3);
2008 Parameter implicit_value_parameter = new Parameter (
2009 ftype, "Value", Parameter.Modifier.NONE, null);
2011 set_parameters.AppendParameter (implicit_value_parameter);
2015 get_parameters = Parameters.EmptyReadOnlyParameters;
2016 set_parameters = new Parameters (null, null ,(Location)$3);
2018 Parameter implicit_value_parameter = new Parameter (
2019 ftype, "Value", Parameter.Modifier.NONE, null);
2021 set_parameters.AppendParameter (implicit_value_parameter);
2023 lexer.PropertyParsing = true;
2025 Accessor get_block = new Accessor (null, null);
2026 Accessor set_block = new Accessor (null, null);
2028 Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
2029 get_block, set_block, current_attributes, (Location)$3,
2030 null, get_parameters, set_parameters, null);
2032 CheckDef (current_interface.AddProperty (prop), prop.Name, (Location)$3);
2034 get_implicit_value_parameter_type = null;
2035 set_implicit_value_parameter_type = null;
2036 get_parameters = null;
2037 set_parameters = null;
2038 current_local_parameters = null;
2042 interface_event_declaration
2043 : EVENT identifier AS _mark_ type logical_end_of_line
2045 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $5, (Location)$4);
2047 Event e = new Event ((Expression) $5, var.identifier,
2048 null, current_modifiers,
2049 current_attributes, (Location)$4);
2051 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2054 | EVENT identifier opt_params _mark_ logical_end_of_line
2056 string delName = (string) $2;
2057 delName = delName + "EventHandler";
2058 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
2059 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
2060 (current_container, TypeManager.system_void_expr,
2061 (int) delModifiers, MakeName(delName), (Parameters) $3,
2062 (Attributes) current_attributes, (Location)$4);
2064 del.Namespace = current_namespace;
2065 CheckDef (current_interface.AddDelegate (del), del.Name, (Location)$4);
2067 Event e = new Event (DecomposeQI (delName, (Location)$4),
2069 null, current_modifiers,
2070 current_attributes, (Location)$4);
2072 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2076 property_declaration
2077 : abstract_propery_declaration
2078 | non_abstract_propery_declaration
2081 abstract_propery_declaration
2082 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters _mark_ opt_type_with_ranks logical_end_of_line
2084 Expression ftype = ($7 == null) ? (($4 == null) ?
2085 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $7;
2087 if (current_container is Module)
2088 Report.Error (30503, (Location) $6 , "Properties in a Module cannot be declared 'MustOverride'.");
2090 if (current_container is Struct)
2091 Report.Error (435, (Location) $6 ,"Methods in a Structure cannot be declared 'MustOverride'.");
2093 current_modifiers |= Modifiers.ABSTRACT;
2095 current_local_parameters = (Parameters) $5;
2096 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2097 get_parameters = current_local_parameters.Copy (lexer.Location);
2098 set_parameters = current_local_parameters.Copy (lexer.Location);
2100 Parameter implicit_value_parameter = new Parameter (
2101 ftype, "Value", Parameter.Modifier.NONE, null);
2103 set_parameters.AppendParameter (implicit_value_parameter);
2107 get_parameters = Parameters.EmptyReadOnlyParameters;
2108 set_parameters = new Parameters (null, null ,lexer.Location);
2110 Parameter implicit_value_parameter = new Parameter (
2111 ftype, "Value", Parameter.Modifier.NONE, null);
2113 set_parameters.AppendParameter (implicit_value_parameter);
2115 lexer.PropertyParsing = true;
2117 Accessor get_block = new Accessor (null, null);
2118 Accessor set_block = new Accessor (null, null);
2120 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
2121 get_block, set_block, current_attributes, lexer.Location,
2122 null, get_parameters, set_parameters, null);
2124 if (!(current_container is Class))
2125 Report.Error (9999, (Location) $6, "THIS SHOULD NEVER HAPPEN!");
2127 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
2129 get_implicit_value_parameter_type = null;
2130 set_implicit_value_parameter_type = null;
2131 get_parameters = null;
2132 set_parameters = null;
2133 current_local_parameters = null;
2138 non_abstract_propery_declaration
2139 : PROPERTY identifier
2141 opt_property_parameters
2144 opt_implement_clause
2146 push_into_stack((int)Start_block.PROPERTY, (Location)$5);
2147 if ((current_modifiers & Modifiers.DEFAULT) > 0) {
2148 if (current_container.DefaultPropName != null
2149 && current_container.DefaultPropName != (string) $2)
2150 Report.Error (30359,
2152 "Type '" + current_container.Name +
2153 "' cannot have more than one 'Default Property' ");
2155 current_container.DefaultPropName = (string) $2;
2158 get_implicit_value_parameter_type =
2159 ($6 == null) ? (($3 == null) ?
2160 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
2161 get_implicit_value_parameter_name = (string) $2;
2163 current_local_parameters = (Parameters) $4;
2164 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2165 get_parameters = current_local_parameters.Copy ((Location)$5);
2166 set_parameters = current_local_parameters.Copy ((Location)$5);
2170 get_parameters = Parameters.EmptyReadOnlyParameters;
2171 set_parameters = new Parameters (null, null ,(Location)$5);
2173 lexer.PropertyParsing = true;
2178 accessor_declarations
2181 pop_out_of_stack((int)$11,lexer.Location);
2185 lexer.PropertyParsing = false;
2188 Pair pair = (Pair) $10;
2190 Accessor get_block = null;
2191 Accessor set_block = null;
2193 if (pair.First != null){
2194 get_block = (Accessor) pair.First;
2197 if (pair.Second != null) {
2198 set_block = (Accessor) pair.Second;
2201 Location loc = (Location) $5 ;
2203 // Structure members are Public by default
2204 if ((current_container is Struct) && (current_modifiers == 0))
2205 current_modifiers = Modifiers.PUBLIC;
2207 prop = new Property ((Expression) get_implicit_value_parameter_type,
2208 (string) $2, current_modifiers, get_block, set_block,
2209 current_attributes, loc, set_implicit_value_parameter_name,
2210 get_parameters, set_parameters, (ArrayList) $7);
2212 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
2213 get_implicit_value_parameter_type = null;
2214 set_implicit_value_parameter_type = null;
2215 get_parameters = null;
2216 set_parameters = null;
2217 current_local_parameters = null;
2221 opt_property_parameters
2224 $$ = Parameters.EmptyReadOnlyParameters;
2226 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2232 opt_implement_clause
2237 | IMPLEMENTS implement_clause_list
2243 implement_clause_list
2244 : qualified_identifier
2246 ArrayList impl_list = new ArrayList ();
2247 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
2250 | implement_clause_list COMMA qualified_identifier
2252 ArrayList impl_list = (ArrayList) $1;
2253 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
2259 accessor_declarations
2260 : get_accessor_declaration opt_set_accessor_declaration
2262 $$ = new Pair ($1, $2);
2264 | set_accessor_declaration opt_get_accessor_declaration
2266 $$ = new Pair ($2, $1);
2270 opt_get_accessor_declaration
2271 : /* empty */ { $$ = null; }
2272 | get_accessor_declaration
2275 opt_set_accessor_declaration
2276 : /* empty */ { $$ = null; }
2277 | set_accessor_declaration
2280 get_accessor_declaration
2281 : opt_attributes GET _mark_ logical_end_of_line
2283 push_into_stack((int)Start_block.GET, (Location)$3);
2284 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
2285 Report.Error (30023, (Location)$3, "'WriteOnly' properties cannot have a 'Get' accessor");
2287 current_local_parameters = get_parameters;
2289 lexer.PropertyParsing = false;
2292 // Add local var declaration
2294 ArrayList retval = new ArrayList ();
2295 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, (Location)$3));
2296 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
2301 pop_out_of_stack((int)$7,lexer.Location);
2305 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2306 current_local_parameters = null;
2307 lexer.PropertyParsing = true;
2311 set_accessor_declaration
2312 : opt_attributes SET opt_set_parameter _mark_ logical_end_of_line
2314 push_into_stack((int)Start_block.SET, (Location)$4);
2315 if ((current_modifiers & Modifiers.READONLY) != 0)
2316 Report.Error (30022,
2318 "'ReadOnly' properties cannot have a 'Set' accessor");
2320 Parameter implicit_value_parameter = new Parameter (
2321 set_implicit_value_parameter_type,
2322 set_implicit_value_parameter_name,
2323 Parameter.Modifier.NONE, null);
2325 current_local_parameters = set_parameters;
2326 current_local_parameters.AppendParameter (implicit_value_parameter);
2329 lexer.PropertyParsing = false;
2334 pop_out_of_stack((int)$8,lexer.Location);
2339 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2340 current_local_parameters = null;
2341 lexer.PropertyParsing = true;
2348 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2349 set_implicit_value_parameter_name = "Value";
2351 |OPEN_PARENS CLOSE_PARENS
2353 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2354 set_implicit_value_parameter_name = "Value";
2356 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2358 Parameter.Modifier pm = (Parameter.Modifier)$2;
2359 if ((pm | Parameter.Modifier.VAL) != 0)
2360 Report.Error (31065,
2362 "Set cannot have a paremeter modifier other than 'ByVal'");
2364 set_implicit_value_parameter_type = (Expression) $4;
2366 if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
2367 Report.Error (31064,
2369 "Set value parameter type can not be different from property type");
2372 set_implicit_value_parameter_name = (string) $3;
2374 set_implicit_value_parameter_name = "Value";
2380 variable_declarators end_of_stmt
2382 int mod = (int) current_modifiers;
2384 VariableDeclaration.FixupTypes ((ArrayList) $2);
2385 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2387 if (current_container is Module)
2388 mod = mod | Modifiers.STATIC;
2390 // Structure members are Public by default
2391 if ((current_container is Struct) && (mod == 0))
2392 mod = Modifiers.PUBLIC;
2394 if ((mod & Modifiers.Accessibility) == 0)
2395 mod |= Modifiers.PRIVATE;
2397 foreach (VariableDeclaration var in (ArrayList) $2){
2398 Location l = var.Location;
2399 Field field = new Field (var.type, mod, var.identifier,
2400 var.expression_or_array_initializer,
2401 (Attributes) null, l);
2403 CheckDef (current_container.AddField (field), field.Name, l);
2408 withevents_declaration
2409 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2411 // Module members are static by default, but delegates *can't* be declared static
2412 // so we must fix it, if mbas was the one actually responsible for this
2413 // instead of triggering an error.
2414 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2415 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2417 /* WithEvents Fields must be resolved into properties
2418 with a bit of magic behind the scenes */
2420 VariableDeclaration.FixupTypes ((ArrayList) $3);
2422 foreach (VariableDeclaration var in (ArrayList) $3) {
2423 // 1 - We create a private field
2424 Location l = var.Location;
2426 if ((current_modifiers & Modifiers.STATIC) > 0)
2427 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2429 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2430 var.expression_or_array_initializer,
2431 (Attributes) null, l);
2433 CheckDef (current_container.AddField (field), field.Name, l);
2435 // 2 - Public property
2437 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2438 field, (int) current_modifiers,
2439 (Attributes) current_attributes, l);
2441 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2451 delegate_declaration
2452 : DELEGATE SUB _mark_
2453 identifier OPEN_PARENS
2454 opt_formal_parameter_list
2458 Location l = (Location)$3;
2459 // Module members are static by default, but delegates *can't* be declared static
2460 // so we must fix it, if mbas was the one actually responsible for this
2461 // instead of triggering an error.
2462 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2463 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2465 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2466 TypeManager.system_void_expr,
2467 (int) current_modifiers,
2468 MakeName ((string) $4), (Parameters) $6,
2469 (Attributes) current_attributes, l);
2471 del.Namespace = current_namespace;
2472 CheckDef (current_container.AddDelegate (del), del.Name, l);
2474 | DELEGATE FUNCTION _mark_
2475 identifier OPEN_PARENS
2476 opt_formal_parameter_list
2477 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2479 Location l = (Location)$3;
2481 // Module members are static by default, but delegates *can't* be declared static
2482 // so we must fix it, if mbas was the one actually responsible for this
2483 // instead of triggering an error.
2484 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2485 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2487 Expression ftype = ($8 == null) ? TypeManager.system_object_expr : (Expression) $8;
2489 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2491 ftype, (int) current_modifiers, MakeName ((string) $4),
2492 (Parameters) $6, (Attributes) current_attributes, l);
2494 del.Namespace = current_namespace;
2495 CheckDef (current_container.AddDelegate (del), del.Name, l);
2500 : /* empty */ { $$ = null; }
2501 | HANDLES evt_handler { $$ = $2; }
2505 : qualified_identifier _mark_
2507 $$ = (Expression) DecomposeQI ((string)$1, (Location)$2);
2513 | ME DOT qualified_identifier _mark_
2515 $$ = (Expression) DecomposeQI ((string)$3, (Location)$4);
2517 /*| MYBASE DOT qualified_identifier
2519 // FIXME: this is blatantly wrong and crash-prone
2520 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2524 constructor_declaration
2525 : SUB _mark_ NEW opt_params logical_end_of_line
2527 push_into_stack((int)Start_block.SUB, (Location)$2);
2528 current_local_parameters = (Parameters) $4;
2530 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, (Location)$2);
2535 Constructor c = (Constructor) $1;
2536 c.Block = (Block) end_block();
2537 c.ModFlags = (int) current_modifiers;
2538 c.OptAttributes = current_attributes;
2540 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2542 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2543 current_local_parameters = null;
2547 pop_out_of_stack((int)$9, lexer.Location);
2552 opt_formal_parameter_list
2555 $$ = Parameters.EmptyReadOnlyParameters;
2557 | formal_parameter_list
2560 //Parameter p = ((Parameters) $1).FixedParameters[0];
2564 formal_parameter_list
2567 ArrayList pars_list = (ArrayList) $1;
2568 Parameter [] pars = null;
2569 Parameter array_parameter = null;
2570 int non_array_count = pars_list.Count;
2571 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2572 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2573 non_array_count = pars_list.Count - 1;
2575 foreach (Parameter par in pars_list)
2576 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2577 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2578 non_array_count = 0;
2579 array_parameter = null;
2582 if (non_array_count > 0) {
2583 pars = new Parameter [non_array_count];
2584 pars_list.CopyTo (0, pars, 0, non_array_count);
2586 $$ = new Parameters (pars, array_parameter, lexer.Location);
2593 ArrayList pars = new ArrayList ();
2598 | parameters COMMA parameter
2600 ArrayList pars = (ArrayList) $1;
2609 opt_parameter_modifier
2610 identifier _mark_ opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2612 Parameter.Modifier pm = (Parameter.Modifier)$2;
2613 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2616 if (opt_parm && ($8 == null))
2617 Report.Error (30812, (Location)$4, "Optional parameters must have a default value");
2619 if (!opt_parm && ($8 != null))
2620 Report.Error (32024, (Location)$4, "Non-Optional parameters should not have a default value");
2622 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2623 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2624 Report.Error (30667, (Location)$4, "ParamArray parameters must be ByVal");
2627 if ((pm & Parameter.Modifier.REF) !=0)
2628 pm |= Parameter.Modifier.ISBYREF;
2630 if ($5 != null && $7 != null && $5 != $7)
2631 Report.Error (30302, (Location)$4, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2633 ptype = (Expression)(($7 == null) ? (($5 == null) ? TypeManager.system_object_expr : $5) : $7);
2635 string t = ptype.ToString ();
2636 if (t.IndexOf('[') >= 0)
2637 Report.Error (31087, (Location)$4, "Array types specified in too many places");
2639 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $6, true, (Location)$4), (Location)$4);
2641 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2642 Report.Error (30050, (Location)$4, "ParamArray parameters must be an array type");
2643 $$ = new Parameter (ptype, (string) $3, pm,
2644 (Attributes) $1, (Expression) $8, opt_parm);
2648 opt_parameter_modifier
2649 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2650 | parameter_modifiers { $$ = $1; }
2654 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2655 | parameter_modifier { $$ = $1; }
2659 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2660 | BYVAL { $$ = Parameter.Modifier.VAL; }
2661 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2662 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2667 | statement_list end_of_stmt
2672 | statement_list end_of_stmt
2677 : declaration_statement
2679 if ($1 != null && (Block) $1 != current_block){
2680 current_block.AddStatement ((Statement) $1);
2681 current_block = (Block) $1;
2684 | embedded_statement
2686 current_block.AddStatement ((Statement) $1);
2689 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2691 AddHandler ((Expression) $2, (Expression) $5);
2693 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2695 RemoveHandler ((Expression) $2, (Expression) $5);
2697 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2699 RaiseEvent ((string) $2, (ArrayList) $3);
2701 /* | array_handling_statement */
2702 /* | empty_statement */
2705 current_block.AddStatement ((Statement) $1);
2710 : END_EOL {$$ = new End (lexer.Location);}
2714 opt_raise_event_args
2715 : /* empty */ { $$ = null; }
2716 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2733 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2735 if (!current_block.AddLabel ((string) $1, labeled)){
2736 Location l = lexer.Location;
2737 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2739 current_block.AddStatement (labeled);
2743 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2745 if (!current_block.AddLabel ((string) $1, labeled)){
2746 Location l = lexer.Location;
2747 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2749 current_block.AddStatement (labeled);
2755 : expression_statement
2756 | selection_statement
2757 | iteration_statement
2759 | synclock_statement
2761 | array_handling_statement
2767 $$ = new EmptyStatement ();
2773 : WITH _mark_ expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2775 // was : Expression e = DecomposeQI ((string) $3, (Location)$2);
2776 push_into_stack((int)Start_block.WITH, (Location)$2);
2777 Expression e = (Expression) $3;
2784 pop_out_of_stack((int)$7,lexer.Location);
2785 Block b = end_block();
2792 array_handling_statement
2798 : REDIM opt_preserve redim_clauses
2800 ArrayList list = (ArrayList) $3;
2801 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2808 : /* empty */ { $$ = false; }
2809 | PRESERVE { $$ = true; }
2815 ArrayList clauses = new ArrayList ();
2820 | redim_clauses COMMA redim_clause
2822 ArrayList clauses = (ArrayList) ($1);
2830 : invocation_expression
2832 Invocation i = (Invocation) $1;
2833 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2839 : ERASE erase_clauses
2841 ArrayList list = (ArrayList) $2;
2842 foreach(Expression e in list)
2844 Erase r = new Erase (e, lexer.Location);
2853 ArrayList clauses = new ArrayList ();
2858 | erase_clauses COMMA erase_clause
2860 ArrayList clauses = (ArrayList) ($1);
2868 : primary_expression
2873 | continue_statement
2874 | */return_statement
2885 $$ = new Goto (current_block, (string) $2, lexer.Location);
2890 : THROW _mark_ opt_expression
2892 $$ = new Throw ((Expression) $3, (Location)$2);
2899 $$ = new Exit ((ExitType)$2, lexer.Location);
2904 : DO { $$ = ExitType.DO; }
2905 | FOR { $$ = ExitType.FOR; }
2906 | WHILE { $$ = ExitType.WHILE; }
2907 | SELECT { $$ = ExitType.SELECT; }
2908 | SUB { $$ = ExitType.SUB; }
2909 | FUNCTION { $$ = ExitType.FUNCTION; }
2910 | PROPERTY { $$ = ExitType.PROPERTY; }
2911 | TRY { $$ = ExitType.TRY; }
2914 : RETURN opt_expression
2916 $$ = new Return ((Expression) $2, lexer.Location);
2928 : FOR EACH identifier _mark_ opt_type_spec IN
2929 expression end_of_stmt
2931 Location l = (Location)$4;
2932 push_into_stack((int)Start_block.FOR, l);
2933 LocalVariableReference v = null;
2939 VariableDeclaration decl = new VariableDeclaration ((string) $3,
2940 (Expression) $5, null, (Location)$4, null);
2942 vi = current_block.AddVariable (
2943 (Expression) $5, decl.identifier, current_local_parameters, decl.Location);
2946 if (decl.expression_or_array_initializer is Expression)
2947 expr = (Expression) decl.expression_or_array_initializer;
2948 else if (decl.expression_or_array_initializer == null)
2952 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
2953 expr = new ArrayCreation ((Expression) $5, "", init, decl.Location);
2956 v = new LocalVariableReference (current_block, decl.identifier, l);
2960 Assign a = new Assign (v, expr, decl.Location);
2961 current_block.AddStatement (new StatementExpression (a, (Location)$4));
2966 vi = current_block.GetVariableInfo ((string) $3);
2969 // Get a reference to this variable.
2970 v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
2973 Report.Error (451, (Location)$4,"Name '" + (string) $3 + "' is not declared.");
2982 pop_out_of_stack((int)$11,lexer.Location);
2984 _mark_ opt_identifier
2986 string s = $3.ToString();
2989 s1 = $14.ToString();
2990 if (s1 != "" && s != s1)
2992 Report.Error(30070, (Location)$13, "Next Control Variable '"+s1+"' does not match with For Loop control variable '"+s+"'");
2994 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2995 Block foreach_block = end_block();
2999 f = new Foreach (null, v, (Expression) $7, foreach_block, (Location)$4);
3003 current_block.AddStatement (f);
3012 : YIELD expression _mark_
3014 if (!UseExtendedSyntax)
3020 if (iterator_container == null){
3021 Report.Error (204, (Location)$3, "yield statement can only be used within a method, operator or property");
3024 iterator_container.SetYields ();
3025 $$ = new Yield ((Expression) $2, (Location)$3);
3030 if (!UseExtendedSyntax)
3036 if (iterator_container == null){
3037 Report.Error (204, (Location)$3, "yield statement can only be used within a method, operator or property");
3040 iterator_container.SetYields ();
3041 $$ = new YieldBreak ((Location)$3);
3047 : SYNCLOCK _mark_ expression end_of_stmt
3049 push_into_stack((int)Start_block.SYNCLOCK, (Location)$2);
3055 pop_out_of_stack((int)$7,lexer.Location);
3056 $$ = new Lock ((Expression) $3, (Statement) (Block) end_block(), (Location)$2);
3066 : TRY _mark_ end_of_stmt
3068 push_into_stack((int)Start_block.TRY, (Location)$2);
3069 try_top=(Location)$2;
3075 tmp_catch_clauses = (ArrayList) $6;
3080 /*FIXME: Try block without a end try is throwing error at a wrong place*/
3083 _mark_ opt_end_block
3085 pop_out_of_stack((int)$3,lexer.Location);
3087 ArrayList s = new ArrayList ();
3089 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
3096 // Now s contains the list of specific catch clauses
3097 // and g contains the general one.
3098 Block b = end_block();
3100 $$ = new Try ((Block) b, s, g, null, try_top);
3107 tmp_block = end_block();
3114 _mark_ opt_end_block
3116 pop_out_of_stack((int)$8,lexer.Location);
3118 ArrayList s = new ArrayList ();
3119 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
3121 if (catch_list != null){
3122 foreach (Catch cc in catch_list) {
3130 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), try_top);
3136 : /* empty */ { $$ = null; }
3143 ArrayList l = new ArrayList ();
3148 | catch_clauses catch_clause
3150 ArrayList l = (ArrayList) $1;
3158 : /* empty */ { $$ = null; }
3163 : /* empty */ { $$ = null; }
3164 | WHEN boolean_expression
3171 : CATCH opt_catch_args opt_when _mark_ end_of_stmt
3173 Expression type = null;
3177 DictionaryEntry cc = (DictionaryEntry) $2;
3178 type = (Expression) cc.Key;
3179 id = (string) cc.Value;
3182 ArrayList one = new ArrayList ();
3183 Location loc = (Location)$4;
3185 one.Add (new VariableDeclaration (id, type, loc));
3188 current_block = new Block (current_block);
3189 Block b = declare_local_variables (type, one, loc);
3194 opt_statement_list {
3195 Expression type = null;
3197 Block b_catch = current_block;
3200 DictionaryEntry cc = (DictionaryEntry) $2;
3201 type = (Expression) cc.Key;
3202 id = (string) cc.Value;
3206 // FIXME: I can change this for an assignment.
3208 while (current_block != (Block) $1)
3209 current_block = current_block.Parent;
3212 $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, (Location)$4);
3217 : /* empty */ { $$ = null; }
3222 : identifier AS _mark_ type
3224 $$ = new DictionaryEntry ($4, $1);
3226 | error _mark_ AS type
3228 Report.Error(30203, (Location)$2, "Identifier Expected");
3231 | identifier AS _mark_ error
3233 Report.Error(30182, (Location)$3, "Type Expected");
3240 : DO _mark_ opt_do_construct end_of_stmt
3242 push_into_stack((int)Start_block.DO, (Location)$2);
3248 pop_out_of_stack((int)$7,lexer.Location);
3250 _mark_ opt_do_construct
3252 Expression t_before = (Expression) $3;
3253 Expression t_after = (Expression) $10;
3256 if ((t_before != null) && (t_after != null))
3257 Report.Error (30238, (Location)$9, "'Loop' cannot have a condition if matching 'Do' has one.");
3259 if ((t_before == null) && (t_after == null))
3260 t = new BoolLiteral (true);
3262 t = (t_before != null) ? t_before : t_after;
3264 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
3266 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
3267 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
3268 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, (Location)$2);
3270 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, (Location)$2);
3275 : /* empty */ { $$ = null; }
3276 | while_or_until boolean_expression
3278 do_type = (DoOptions)$1;
3279 $$ = (Expression) $2;
3284 : WHILE { $$ = DoOptions.WHILE; }
3285 | UNTIL { $$ = DoOptions.UNTIL; }
3291 push_into_stack((int)Start_block.WHILE, lexer.Location);
3293 oob_stack.Push (lexer.Location);
3295 boolean_expression end_of_stmt
3299 Location l = (Location) oob_stack.Pop ();
3300 pop_out_of_stack((int)$6,lexer.Location);
3301 Block b = end_block();
3302 Expression e = (Expression) $3;
3303 $$ = new While ((Expression) e, (Statement) b, l);
3308 : FOR _mark_ identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
3310 push_into_stack((int)Start_block.FOR, (Location)$2);
3314 ArrayList VarDeclaration = new ArrayList ();
3315 VarDeclaration.Add (new VariableDeclaration ((string) $3,
3316 (Expression) $4, null, (Location)$2, null));
3318 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), VarDeclaration);
3319 Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location)$2);
3327 pop_out_of_stack((int)$13,lexer.Location);
3329 _mark_ opt_identifier
3331 string s = $3.ToString();
3334 s1 = $16.ToString();
3335 if (s1 != "" && s != s1) {
3336 Report.Error(30070, (Location)$15, "Next Control Variable '"+s1+"' does not match with For Loop control variable '"+s+"'");
3339 Block inner_statement = end_block();
3340 Location l = (Location)$2;
3341 Expression for_var = (Expression) DecomposeQI ((string)$3, l);
3343 For f = new For (for_var, (Expression) $6, (Expression) $8, (Expression) $9, inner_statement, l);
3346 current_block.AddStatement (f);
3355 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
3356 | STEP expression { $$ = $2; }
3365 : if_statement_open opt_then end_of_stmt opt_statement_list
3367 push_into_stack((int)Start_block.IF, (Location)$1);
3373 | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
3377 Location l = (Location) oob_stack.Pop ();
3378 tmp_expr = (Expression)expr_stack.Pop();
3379 $$ = new If ((Expression) tmp_expr, end_block(), l);
3383 Location l = (Location) oob_stack.Pop ();
3384 tmp_expr = (Expression)expr_stack.Pop();
3385 tmp_block = (Block) tmp_blocks.Pop ();
3386 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3389 | if_statement_open THEN else_pre_embedded_statement
3391 Location l = (Location) oob_stack.Pop ();
3392 tmp_expr = (Expression)expr_stack.Pop();
3393 tmp_block = (Block) tmp_blocks.Pop ();
3394 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3398 pre_embedded_statement
3399 : embedded_statement
3401 current_block.AddStatement ((Statement) $1);
3405 opt_else_pre_embedded_statement
3407 | else_pre_embedded_statement
3410 else_pre_embedded_statement
3413 Block bl = end_block();
3414 tmp_blocks.Push(bl);
3418 | ELSE embedded_statement
3420 Block bl = end_block();
3421 tmp_blocks.Push(bl);
3424 current_block.AddStatement ((Statement) $2);
3428 /*FIXME:if without end if not working. Error line shown is nor correct*/
3432 oob_stack.Push (lexer.Location);
3437 tmp_expr = (Expression) $4;
3438 expr_stack.Push(tmp_expr);
3452 Location l = (Location) oob_stack.Pop ();
3453 pop_out_of_stack((int)$1,lexer.Location);
3454 Expression expr = (Expression)expr_stack.Pop();
3455 $$ = new If ((Expression) expr, (Statement) end_block(), l);
3460 Block bl = end_block();
3461 tmp_blocks.Push(bl);
3467 Location l = (Location) oob_stack.Pop ();
3468 pop_out_of_stack((int)$5,lexer.Location);
3469 tmp_expr = (Expression)expr_stack.Pop();
3470 tmp_block = (Block) tmp_blocks.Pop();
3471 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
3474 opt_elseif boolean_expression opt_then
3476 tmp_expr = (Expression) $2;
3477 expr_stack.Push(tmp_expr);
3478 tmp_block = end_block();
3479 tmp_blocks.Push(tmp_block);
3482 end_of_stmt opt_statement_list
3483 else_if_statement_rest
3485 Statement stmt = (Statement) statement_stack.Pop();
3486 Block bl = (Block) tmp_blocks.Pop();
3487 Expression expr = (Expression)expr_stack.Pop();
3488 Location l = (Location) oob_stack.Pop ();
3489 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3494 else_if_statement_rest
3498 Block bl = end_block();
3499 tmp_blocks.Push(bl);
3505 Location l = (Location) oob_stack.Pop ();
3506 pop_out_of_stack((int)$5,lexer.Location);
3508 Expression expr = (Expression)expr_stack.Pop();
3509 Block bl = (Block)tmp_blocks.Pop();
3510 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3511 statement_stack.Push(stmt);
3514 opt_elseif boolean_expression opt_then
3516 expr_stack.Push((Expression) $2);
3517 Block bl = end_block();
3518 tmp_blocks.Push(bl);
3521 end_of_stmt opt_statement_list
3522 else_if_statement_rest
3524 Location l = (Location) oob_stack.Pop ();
3526 Statement tmp_stmt = (Statement)statement_stack.Pop();
3527 Block bl = (Block) tmp_blocks.Pop();
3528 Expression expr = (Expression)expr_stack.Pop();
3529 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3530 statement_stack.Push(stmt);
3535 Location l = (Location) oob_stack.Pop ();
3536 pop_out_of_stack((int)$1,lexer.Location);
3538 Expression expr = (Expression)expr_stack.Pop();
3539 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3540 statement_stack.Push(stmt);
3544 /*FIXME:Select without an expression is showing a parser error instead of a expression missing error*/
3547 _mark_ opt_case expression end_of_stmt
3549 push_into_stack((int)Start_block.SELECT, (Location)$2);
3550 oob_stack.Push (lexer.Location);
3551 switch_stack.Push (current_block);
3556 pop_out_of_stack((int)$8,lexer.Location);
3557 current_block = (Block) switch_stack.Pop ();
3558 $$ = new Switch ((Expression) $4, (ArrayList) $7, (Location) oob_stack.Pop ());
3563 : /* empty */ { $$ = null; }
3564 | case_sections { $$ = $1; }
3568 : case_sections case_section
3570 ArrayList sections = (ArrayList) $1;
3577 ArrayList sections = new ArrayList ();
3591 : CASE case_clauses ends
3597 //Block topmost = current_block;
3598 Block topmost = end_block();
3600 while (topmost.Implicit)
3601 topmost = topmost.Parent;
3603 // FIXME: This is a horrible hack which MUST go
3604 topmost.statements.Add (new Break (lexer.Location));
3605 $$ = new SwitchSection ((ArrayList) $2, topmost);
3608 /* FIXME: we should somehow flag an error
3609 (BC30321 'Case' cannot follow a 'Case Else'
3610 in the same 'Select' statement.)
3611 if Case Else is not the last of the Case clauses
3618 //Block topmost = current_block;
3619 Block topmost = end_block();
3621 while (topmost.Implicit)
3622 topmost = topmost.Parent;
3624 // FIXME: This is a horrible hack which MUST go
3625 topmost.statements.Add (new Break (lexer.Location));
3627 ArrayList a = new ArrayList();
3628 a.Add (new SwitchLabel (null, lexer.Location));
3629 $$ = new SwitchSection ((ArrayList) a, topmost);
3636 if ($1 is ArrayList) //From expression TO expression
3640 ArrayList labels = new ArrayList ();
3646 | case_clauses COMMA case_clause
3648 ArrayList labels = (ArrayList) ($1);
3656 : opt_is comparison_operator expression
3659 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3661 | expression TO expression
3663 //FIXME: need to handle when expressions are character strings.
3664 Constant start = (Constant) $1;
3665 Constant end = (Constant) $3;
3666 int i = 0, s = 0, e = 0;
3667 Location l = lexer.Location ;
3668 ArrayList labels = new ArrayList ();
3671 s = (int) start.GetValue ();
3673 e = (int) end.GetValue ();
3674 for(i = s; i <= e; i++) {
3675 labels.Add(new SwitchLabel ((Expression)new IntLiteral(i), l));
3700 expression_statement
3701 : statement_expression
3708 statement_expression
3709 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3710 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3711 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3714 object_creation_expression
3715 : NEW type OPEN_PARENS _mark_ opt_argument_list CLOSE_PARENS
3717 $$ = new New ((Expression) $2, (ArrayList) $5, (Location)$4);
3721 $$ = new New ((Expression) $2, new ArrayList(), (Location)$3);
3725 array_creation_expression
3726 : object_creation_expression opt_rank_specifiers _mark_ array_initializer
3729 ArrayList dims = new ArrayList();
3731 if (n.Arguments != null) {
3732 foreach (Argument a in n.Arguments) {
3737 Expression atype = n.RequestedType;
3740 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, (Location)$3), (Location)$3);
3742 ArrayList init = (ArrayList) $4;
3743 if (init.Count == 0)
3746 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3747 VariableDeclaration.VBFixIndexList (ref dims);
3748 $$ = new ArrayCreation (atype, dims, "", init, (Location)$3);
3752 string rank = VariableDeclaration.BuildRank (dims);
3753 $$ = new ArrayCreation (atype, rank, (ArrayList) $4, (Location)$3);
3755 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3760 : object_creation_expression
3761 | array_creation_expression
3764 declaration_statement
3765 : _mark_ local_variable_declaration
3768 DictionaryEntry de = (DictionaryEntry) $2;
3770 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location)$1);
3773 | local_constant_declaration
3776 DictionaryEntry de = (DictionaryEntry) $1;
3778 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3783 local_variable_declaration
3784 : DIM _mark_ variable_declarators
3786 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), $3);
3791 local_constant_declaration
3792 : CONST constant_declarators
3795 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3801 constant_declarators
3802 : constant_declarator
3804 ArrayList decl = new ArrayList ();
3810 | constant_declarators COMMA constant_declarator
3812 ArrayList decls = (ArrayList) $1;
3821 : _mark_ variable_name opt_type_decl opt_variable_initializer
3823 VarName vname = (VarName) $2;
3824 string varname = (string) vname.Name;
3825 current_rank_specifiers = (ArrayList) vname.Rank;
3826 object varinit = $4;
3828 if (varinit == null)
3830 30438, (Location)$1, "Constant should have a value"
3833 if (vname.Type != null && $3 != null)
3835 30302, (Location)$1,
3836 "Type character cannot be used with explicit type declaration" );
3838 Expression vartype = ($3 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $3;
3840 if (current_rank_specifiers != null)
3842 Report.Error (30424, (Location)$1, "Constant doesn't support array");
3846 $$ = new VariableDeclaration (varname, vartype, varinit, (Location)$1, null);
3850 variable_declarators
3851 : variable_declarator
3853 ArrayList decl = new ArrayList ();
3854 decl.AddRange ((ArrayList) $1);
3857 | variable_declarators COMMA variable_declarator
3859 ArrayList decls = (ArrayList) $1;
3860 decls.AddRange ((ArrayList) $3);
3866 : _mark_ variable_names opt_type_decl opt_variable_initializer
3868 ArrayList names = (ArrayList) $2;
3869 object varinit = $4;
3870 ArrayList VarDeclarations = new ArrayList();
3872 ArrayList a_dims = null;
3874 if ((names.Count > 1) && (varinit != null))
3876 30671, (Location)$1,
3877 "Multiple variables with single type can not have " +
3878 "a explicit initialization" );
3881 foreach (VarName vname in names)
3883 string varname = (string) vname.Name;
3884 current_rank_specifiers = (ArrayList) vname.Rank;
3888 if(vname.Type != null && $3 != null)
3890 30302, (Location)$1,
3891 "Type character cannot be used with explicit type declaration" );
3893 // Some checking is required for particularly weird declarations
3894 // like Dim a As Integer(,)
3896 vartype = (Expression) ((Pair) $3).First;
3898 /*if ($4 != null && $4 is ArrayList)
3899 Report.Error (205, "End of statement expected.");*/
3901 ArrayList args = (ArrayList) ((Pair) $3).Second;
3902 if (current_rank_specifiers != null)
3903 Report.Error (31087, (Location)$1,
3904 "Array types specified in too many places");
3906 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3907 Report.Error (30638, (Location)$1,"Array bounds cannot appear in type specifiers.");
3909 current_rank_specifiers = new ArrayList ();
3910 current_rank_specifiers.Add (args);
3913 vartype = ($3 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $3;
3915 // if the variable is an array with explicit bound
3916 // and having explicit initialization throw exception
3917 if (current_rank_specifiers != null && varinit != null)
3919 bool broken = false;
3920 foreach (ArrayList exprs in current_rank_specifiers)
3922 foreach (Expression expr in exprs)
3924 if (!((Expression)expr is EmptyExpression ))
3927 30672, (Location)$1,
3928 "Array declared with explicit bound " +
3929 " can not have explicit initialization");
3940 Check for a declaration like Dim a(2) or Dim a(2,3)
3941 If this is the case, we must generate an ArrayCreationExpression
3942 and, in case, add the initializer after the array has been created.
3944 if (VariableDeclaration.IsArrayDecl (this)) {
3945 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3946 a_dims = (ArrayList) current_rank_specifiers;
3947 VariableDeclaration.VBFixIndexLists (ref a_dims);
3948 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, (Location)$1);
3950 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, (Location)$1), (Location)$1);
3953 if (vartype is New) {
3954 if (varinit != null) {
3955 Report.Error (30205, (Location)$1, "End of statement expected");
3961 vartype = ((New)vartype).RequestedType;
3964 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, (Location)$1, null));
3966 $$ = VarDeclarations;
3973 ArrayList list = new ArrayList ();
3977 | variable_names COMMA variable_name
3979 ArrayList list = (ArrayList) $1;
3986 : identifier opt_type_character opt_array_name_modifier
3988 $$ = new VarName ($1, $2, $3);
3999 $$ = (Expression) $2;
4005 | AS type _mark_ rank_specifiers
4007 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$4, true, (Location)$3), (Location)$3);
4012 : opt_type_with_ranks
4018 New n = new New ((Expression)$3, null, lexer.Location);
4019 $$ = (Expression) n;
4021 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
4023 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
4024 $$ = (Expression) n;
4026 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
4028 ArrayList args = new ArrayList();
4029 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
4032 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
4033 $$ = (Expression) n;
4037 opt_array_name_modifier
4038 : /* empty */ { $$ = null; }
4039 | array_type_modifier { $$ = $1; }
4043 : rank_specifiers { $$ = $1; }
4046 opt_variable_initializer
4047 : /* empty */ { $$ = null; }
4048 | ASSIGN variable_initializer { $$ = $2; }
4051 variable_initializer
4054 Expression etmp = (Expression) $1;
4055 etmp = SetValueRequiredFlag (etmp);
4066 : OPEN_BRACE CLOSE_BRACE
4068 ArrayList list = new ArrayList ();
4071 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
4073 $$ = (ArrayList) $2;
4077 variable_initializer_list
4078 : variable_initializer
4080 ArrayList list = new ArrayList ();
4084 | variable_initializer_list COMMA variable_initializer
4086 ArrayList list = (ArrayList) $1;
4107 ArrayList rs = new ArrayList();
4111 | rank_specifiers rank_specifier
4113 ArrayList rs = (ArrayList) $1;
4120 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
4129 ArrayList ds = new ArrayList();
4130 ds.Add (new EmptyExpression());
4135 ArrayList ds = new ArrayList();
4136 ds.Add ((Expression) $1);
4139 | opt_dim_specifiers COMMA expression
4141 ArrayList ds = (ArrayList) $1;
4142 ds.Add ((Expression) $3);
4145 | opt_dim_specifiers COMMA
4147 ArrayList ds = (ArrayList) $1;
4148 ds.Add (new EmptyExpression());
4158 | parenthesized_expression
4161 | qualified_identifier opt_type_character _mark_
4163 string name = (string) $1;
4164 $$ = DecomposeQI (name, (Location)$3);
4166 | get_type_expression
4168 | invocation_expression
4173 { Report.Error(30201,(Location)$2,"Expression expected"); $$ = (Expression)null;}
4180 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
4181 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
4182 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
4183 | NOTHING { $$ = NullLiteral.Null; }
4187 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
4188 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
4189 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
4194 object v = lexer.Value;
4197 $$ = new IntLiteral ((Int32)v);
4198 else if (v is short)
4199 $$ = new ShortLiteral ((Int16)v);
4201 $$ = new LongLiteral ((Int64)v);
4203 Console.WriteLine ("Unexpected result from scanner");
4209 : TRUE { $$ = new BoolLiteral (true); }
4210 | FALSE { $$ = new BoolLiteral (false); }
4213 parenthesized_expression
4214 : OPEN_PARENS expression CLOSE_PARENS
4219 : primary_expression DOT _mark_ identifier
4222 string id_name = (string)$4;
4223 if (id_name.ToUpper() == "NEW")
4225 $$ = new MemberAccess ((Expression) $1, id_name, (Location)$3);
4229 if (with_stack.Count > 0) {
4230 Expression e = (Expression) with_stack.Peek();
4231 $$ = new MemberAccess (e, (string) $4, (Location)$3);
4239 /* | primary_expression DOT _mark_ NEW
4241 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", (Location)$3);
4243 | predefined_type DOT _mark_ identifier
4246 $$ = new MemberAccess ((Expression) $1, (string) $4, (Location)$3);
4249 if (with_stack.Count > 0) {
4250 Expression e = (Expression) with_stack.Peek();
4251 $$ = new MemberAccess (e, (string) $4, (Location)$3);
4265 invocation_expression
4266 // To support Mid$()
4267 : primary_expression opt_dolar_sign OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
4270 Location l = (Location)$5;
4271 Report.Error (1, l, "THIS IS CRAZY");
4273 $$ = new Invocation ((Expression) $1, (ArrayList) $4, (Location)$5);
4274 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($4 != null) ? ((ArrayList) $4).Count : 0);
4276 | CALL primary_expression OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
4279 Location l = (Location)$5;
4280 Report.Error (1, l, "THIS IS CRAZY");
4282 $$ = new Invocation ((Expression) $2, (ArrayList) $3, (Location)$5);
4283 // Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
4285 | primary_expression EXCLAMATION _mark_ identifier // FIXME : This should be identifier-or-keyword
4288 Location l = (Location)$3;
4289 Report.Error (1, l, "THIS IS CRAZY");
4292 ArrayList args = new ArrayList ();
4293 Expression etmp = new StringLiteral ((string)$4);
4295 args.Add (new Argument (etmp, Argument.AType.Expression));
4296 $$ = new Invocation ((Expression) $1, args, (Location)$3);
4306 : MYBASE DOT IDENTIFIER
4308 string id_name = (string) $3;
4309 if (id_name.ToUpper() == "NEW")
4311 $$ = new BaseAccess (id_name, lexer.Location);
4315 $$ = new BaseAccess ("New", lexer.Location);
4323 The 'argument' rule returns an 'empty' argument
4324 of type NoArg (used for default arguments in invocations)
4325 if no arguments are actually passed.
4327 If there is only one argument and it is o type NoArg,
4328 we return a null (empty) list
4330 ArrayList args = (ArrayList) $1;
4331 if (args.Count == 1 &&
4332 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
4342 ArrayList list = new ArrayList ();
4346 | argument_list COMMA argument
4348 ArrayList list = (ArrayList) $1;
4357 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
4359 | BYREF variable_reference
4361 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
4365 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
4367 | ADDRESSOF expression
4369 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
4374 : expression {/* note ("section 5.4"); */ $$ = $1; }
4379 : conditional_xor_expression { $$ = $1; }
4380 /*| assignment_expression*/
4391 $$ = new This (current_block, lexer.Location);
4395 $$ = new This (This.TypeOfAccess.MyClass, current_block, lexer.Location);
4400 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
4404 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
4406 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
4408 | cast_operator OPEN_PARENS expression CLOSE_PARENS
4410 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
4415 : CBOOL { $$ = TypeManager.system_boolean_expr; }
4416 | CBYTE { $$ = TypeManager.system_byte_expr; }
4417 | CCHAR { $$ = TypeManager.system_char_expr; }
4418 | CDATE { $$ = TypeManager.system_date_expr; }
4419 | CDBL { $$ = TypeManager.system_double_expr; }
4420 | CDEC { $$ = TypeManager.system_decimal_expr; }
4421 | CINT { $$ = TypeManager.system_int32_expr; }
4422 | CLNG { $$ = TypeManager.system_int64_expr; }
4423 | COBJ { $$ = TypeManager.system_object_expr; }
4424 | CSHORT { $$ = TypeManager.system_int16_expr; }
4425 | CSNG { $$ = TypeManager.system_single_expr; }
4426 | CSTR { $$ = TypeManager.system_string_expr; }
4430 : GETTYPE OPEN_PARENS _mark_ type CLOSE_PARENS
4432 $$ = new TypeOf ((Expression) $4, (Location)$3);
4436 exponentiation_expression
4437 : prefixed_unary_expression
4438 | exponentiation_expression OP_EXP _mark_ primary_expression
4440 $$ = new Binary (Binary.Operator.Exponentiation,
4441 (Expression) $1, (Expression) $4, (Location)$3);
4445 prefixed_unary_expression
4446 : primary_expression
4447 | PLUS _mark_ prefixed_unary_expression
4449 //FIXME: Is this rule correctly defined ?
4450 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $3, (Location)$2);
4452 | MINUS _mark_ prefixed_unary_expression
4454 //FIXME: Is this rule correctly defined ?
4455 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $3, (Location)$2);
4459 multiplicative_expression
4460 : exponentiation_expression
4461 | multiplicative_expression STAR _mark_ prefixed_unary_expression
4463 $$ = new Binary (Binary.Operator.Multiply,
4464 (Expression) $1, (Expression) $4, (Location)$3);
4466 | multiplicative_expression DIV _mark_ prefixed_unary_expression
4468 $$ = new Binary (Binary.Operator.Division,
4469 (Expression) $1, (Expression) $4, (Location)$3);
4473 integer_division_expression
4474 : multiplicative_expression
4475 | integer_division_expression OP_IDIV _mark_ multiplicative_expression
4477 //FIXME: Is this right ?
4478 $$ = new Binary (Binary.Operator.IntDivision,
4479 (Expression) $1, (Expression) $4, (Location)$3);
4484 : integer_division_expression
4485 | mod_expression MOD _mark_ integer_division_expression
4487 $$ = new Binary (Binary.Operator.Modulus,
4488 (Expression) $1, (Expression) $4, (Location)$3);
4494 | additive_expression PLUS _mark_ mod_expression
4496 $$ = new Binary (Binary.Operator.Addition,
4497 (Expression) $1, (Expression) $4, (Location)$3);
4499 | additive_expression MINUS _mark_ mod_expression
4501 $$ = new Binary (Binary.Operator.Subtraction,
4502 (Expression) $1, (Expression) $4, (Location)$3);
4507 : additive_expression
4508 | concat_expression OP_CONCAT _mark_ additive_expression
4510 // FIXME: This should only work for String expressions
4511 // We probably need to use something from the runtime
4512 $$ = new StringConcat((Location)$3,
4513 (Expression) $1, (Expression) $4);
4520 | shift_expression OP_SHIFT_LEFT _mark_ concat_expression
4522 $$ = new Binary(Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, (Location)$3);
4524 | shift_expression OP_SHIFT_RIGHT _mark_ concat_expression
4526 $$ = new Binary(Binary.Operator.RightShift, (Expression) $1, (Expression) $4, (Location)$3);
4530 relational_expression
4532 | relational_expression LIKE _mark_ shift_expression
4534 $$ = new Binary (Binary.Operator.Like,
4535 (Expression) $1, (Expression) $4, (Location)$3);
4537 | relational_expression ASSIGN _mark_ shift_expression
4539 $$ = new Binary (Binary.Operator.Equality,
4540 (Expression) $1, (Expression) $4, (Location)$3);
4542 | relational_expression OP_NE _mark_ shift_expression
4544 $$ = new Binary (Binary.Operator.Inequality,
4545 (Expression) $1, (Expression) $4, (Location)$3);
4547 | relational_expression OP_LT _mark_ shift_expression
4549 $$ = new Binary (Binary.Operator.LessThan,
4550 (Expression) $1, (Expression) $4, (Location)$3);
4552 | relational_expression OP_GT _mark_ shift_expression
4554 $$ = new Binary (Binary.Operator.GreaterThan,
4555 (Expression) $1, (Expression) $4, (Location)$3);
4557 | relational_expression OP_LE _mark_ shift_expression
4559 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4560 (Expression) $1, (Expression) $4, (Location)$3);
4562 | relational_expression OP_GE _mark_ shift_expression
4564 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4565 (Expression) $1, (Expression) $4, (Location)$3);
4567 | relational_expression IS _mark_ shift_expression
4569 $$ = new Binary (Binary.Operator.Is,
4570 (Expression) $1, (Expression) $4, (Location)$3);
4572 | TYPEOF shift_expression _mark_ IS type
4574 //FIXME: Is this rule correctly defined ?
4575 $$ = new Is ((Expression) $2, (Expression) $5, (Location)$3);
4580 : relational_expression
4581 | NOT _mark_ negation_expression
4583 //FIXME: Is this rule correctly defined ?
4584 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $3, (Location)$2);
4588 conditional_and_expression
4589 : negation_expression
4590 | conditional_and_expression AND _mark_ negation_expression
4592 $$ = new Binary (Binary.Operator.BitwiseAnd,
4593 (Expression) $1, (Expression) $4, (Location)$3);
4595 | conditional_and_expression ANDALSO _mark_ negation_expression
4596 { // FIXME: this is likely to be broken
4597 $$ = new Binary (Binary.Operator.LogicalAnd,
4598 (Expression) $1, (Expression) $4, (Location)$3);
4602 conditional_or_expression
4603 : conditional_and_expression
4604 | conditional_or_expression OR _mark_ conditional_and_expression
4606 $$ = new Binary (Binary.Operator.BitwiseOr,
4607 (Expression) $1, (Expression) $4, (Location)$3);
4609 | conditional_or_expression ORELSE _mark_ conditional_and_expression
4610 { // FIXME: this is likely to be broken
4611 $$ = new Binary (Binary.Operator.LogicalOr,
4612 (Expression) $1, (Expression) $4, (Location)$3);
4616 conditional_xor_expression
4617 : conditional_or_expression
4618 | conditional_xor_expression XOR _mark_ conditional_or_expression
4620 $$ = new Binary (Binary.Operator.ExclusiveOr,
4621 (Expression) $1, (Expression) $4, (Location)$3);
4625 assignment_expression
4626 : prefixed_unary_expression ASSIGN _mark_ expression
4628 $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$3);
4630 | prefixed_unary_expression OP_EXP ASSIGN _mark_ expression
4632 Location l = (Location)$4;
4633 $$ = new CompoundAssign (
4634 Binary.Operator.Exponentiation, (Expression) $1, (Expression) $5, l);
4636 | prefixed_unary_expression STAR ASSIGN _mark_ expression
4638 Location l = (Location)$4;
4639 $$ = new CompoundAssign (
4640 Binary.Operator.Multiply, (Expression) $1, (Expression) $5, l);
4642 | prefixed_unary_expression DIV ASSIGN _mark_ expression
4644 Location l = (Location)$4;
4645 $$ = new CompoundAssign (
4646 Binary.Operator.Division, (Expression) $1, (Expression) $5, l);
4648 | prefixed_unary_expression PLUS ASSIGN _mark_ expression
4650 Location l = (Location)$4;
4651 $$ = new CompoundAssign (
4652 Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
4654 | prefixed_unary_expression MINUS ASSIGN _mark_ expression
4656 Location l = (Location)$4;
4657 $$ = new CompoundAssign (
4658 Binary.Operator.Subtraction, (Expression) $1, (Expression) $5, l);
4660 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN _mark_ expression
4662 Location l = (Location)$4;
4663 $$ = new CompoundAssign (
4664 Binary.Operator.LeftShift, (Expression) $1, (Expression) $5, l);
4666 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN _mark_ expression
4668 Location l = (Location)$4;
4669 $$ = new CompoundAssign (
4670 Binary.Operator.RightShift, (Expression) $1, (Expression) $5, l);
4672 | prefixed_unary_expression OP_CONCAT ASSIGN _mark_ expression
4674 Location l = (Location)$4;
4676 // FIXME should be strings only
4677 $$ = new CompoundAssign (
4678 Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
4680 | prefixed_unary_expression ASSIGN ADDRESSOF _mark_ expression
4682 ArrayList args = new ArrayList();
4683 Argument arg = new Argument ((Expression) $5, Argument.AType.Expression);
4686 New n = new New ((Expression) $1, (ArrayList) args, (Location)$4);
4687 n.isDelegate = true;
4688 $$ = new Assign ((Expression) $1, (Expression) n, (Location)$4);
4699 Expression expr = (Expression) $1;
4700 expr = SetValueRequiredFlag (expr);
4706 : namespace_or_type_name
4708 $$ = DecomposeQI ((string) $1, lexer.Location);
4717 ArrayList types = new ArrayList ();
4722 | type_list COMMA type
4724 ArrayList types = (ArrayList) $1;
4731 namespace_or_type_name
4732 : qualified_identifier
4736 : OBJECT { $$ = TypeManager.system_object_expr; }
4742 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4743 | DATE { $$ = TypeManager.system_date_expr; }
4744 | CHAR { $$ = TypeManager.system_char_expr; }
4745 | STRING { $$ = TypeManager.system_string_expr; }
4751 | floating_point_type
4752 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4757 | BYTE { $$ = TypeManager.system_byte_expr; }
4758 | SHORT { $$ = TypeManager.system_int16_expr; }
4759 | INTEGER { $$ = TypeManager.system_int32_expr; }
4760 | LONG { $$ = TypeManager.system_int64_expr; }
4764 : SINGLE { $$ = TypeManager.system_single_expr; }
4765 | DOUBLE { $$ = TypeManager.system_double_expr; }
4770 | constant_expression _mark_ //FIXME: Fix for binary expression
4772 Expression exp = (Expression) $1;
4773 if(exp is SimpleName) {
4774 string key = ((SimpleName)exp).Name;
4775 if(constPreDir.Contains(key)) {
4776 $$ = new BoolLiteral ((bool)constPreDir [key]);
4780 object o = ((Constant) exp).GetValue ();
4781 bool temp = Convert.ToBoolean(o);
4782 $$ = new BoolLiteral ((bool)temp);
4783 // Report.Error (30580, (Location)$2, "value of Const used is not set");
4789 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS _mark_ EOL
4791 if(tokenizerController.IsAcceptingTokens)
4793 if(in_external_source)
4794 Report.Error (30580, (Location)$8, "#ExternalSource directives may not be nested");
4796 in_external_source = true;
4798 lexer.EffectiveSource = (string) $4;
4799 lexer.EffectiveLine = (int) $6;
4803 | HASH IDENTIFIER LITERAL_STRING _mark_ EOL
4805 if(tokenizerController.IsAcceptingTokens)
4807 if(!($2 as string).ToLower().Equals("region"))
4808 Report.Error (30205, (Location)$4, "Invalid Pre-processor directive");
4815 | HASH END IDENTIFIER _mark_ EOL
4817 if(tokenizerController.IsAcceptingTokens)
4819 if( ($3 as string).ToLower().Equals("externalsource")) {
4820 if(!in_external_source)
4821 Report.Error (30578, (Location)$4, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4823 in_external_source = false;
4824 lexer.EffectiveSource = lexer.Source;
4825 lexer.EffectiveLine = lexer.Line;
4828 else if(($3 as string).ToLower().Equals("region")) {
4829 if(in_marked_region > 0)
4832 Report.Error (30205, (Location)$4, "'#End Region' must be preceded by a matching '#Region'");
4835 Report.Error (29999, (Location)$4, "Unrecognized Pre-Processor statement");
4839 | HASH CONST IDENTIFIER ASSIGN constant_expression _mark_ EOL
4842 Expression express = (Expression) $5;
4843 if (express is Binary) {
4847 object o = ((Constant) express).GetValue ();
4848 bool temp = Convert.ToBoolean(o);
4849 constPreDir.Add($3,temp);
4854 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4857 ifElseStateMachine.HandleToken(tok);
4859 catch(ApplicationException) {
4860 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
4863 directive_exp opt_then EOL
4865 //FIXME: Fix for constant expression
4867 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$5);
4869 | HASH opt_elseif _mark_
4871 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4873 ifElseStateMachine.HandleToken(tok);
4875 catch(ApplicationException) {
4876 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
4879 directive_exp opt_then EOL
4881 //FIXME: Fix for constant expression
4883 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$5);
4887 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4889 ifElseStateMachine.HandleToken(tok);
4891 catch(ApplicationException) {
4892 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
4897 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4899 | HASH END IF _mark_
4901 /*FIXME: IF without ENDIF not working properly. Error line is not diplayed properly*/
4903 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4905 ifElseStateMachine.HandleToken(tok);
4907 catch(ApplicationException) {
4908 throw new MBASException(ifElseStateMachine.Error, (Location)$4, ifElseStateMachine.ErrString);
4913 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4915 | HASH error _mark_ EOL
4917 if(tokenizerController.IsAcceptingTokens)
4918 Report.Error(29999, (Location)$3, "Unrecognized Pre-Processor statement");
4920 Report.Warning (29999, (Location)$3,"Unrecognized Pre-Processor statement");
4925 // Utility rule to save location information
4928 { $$ = lexer.Location; if (yyToken == Token.EOL) { $$ = new Location (lexer.Location.Row - 1, lexer.Location.Col); } }
4931 // Changed to accept "Else If" also along with "ElseIf"
4937 // Changed so as to check if every block is closed or not...
4986 /*In case of any new end block please add it here.. after END_GET as single token... and please continue the numbering from 17...*/
4994 public Tokenizer Lexer {
5000 public static Expression DecomposeQI (string name, Location loc)
5004 if (name.IndexOf ('.') == -1){
5005 return new SimpleName (name, loc);
5007 int pos = name.LastIndexOf (".");
5008 string left = name.Substring (0, pos);
5009 string right = name.Substring (pos + 1);
5011 o = DecomposeQI (left, loc);
5013 return new MemberAccess (o, right, loc);
5017 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
5019 Block implicit_block;
5020 ArrayList inits = null;
5023 // We use the `Used' property to check whether statements
5024 // have been added to the current block. If so, we need
5025 // to create another block to contain the new declaration
5026 // otherwise, as an optimization, we use the same block to
5027 // add the declaration.
5029 // FIXME: A further optimization is to check if the statements
5030 // that were added were added as part of the initialization
5031 // below. In which case, no other statements have been executed
5032 // and we might be able to reduce the number of blocks for
5033 // situations like this:
5035 // int j = 1; int k = j + 1;
5038 VariableDeclaration.FixupTypes (variable_declarators);
5040 if (current_block.Used) {
5041 implicit_block = new Block (current_block, true, loc, Location.Null);
5042 implicit_block.AddChildVariableNames (current_block);
5044 implicit_block = current_block;
5046 foreach (VariableDeclaration decl in variable_declarators){
5047 Expression type = decl.type;
5048 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, loc) != null) {
5049 if (decl.expression_or_array_initializer != null){
5051 inits = new ArrayList ();
5058 return implicit_block;
5060 foreach (VariableDeclaration decl in inits){
5063 Expression type = decl.type;
5065 if ((decl.expression_or_array_initializer is Expression) ||
5066 (decl.expression_or_array_initializer is New)) {
5067 expr = (Expression) decl.expression_or_array_initializer;
5069 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
5071 expr = new ArrayCreation (type, "", init, decl.Location);
5074 LocalVariableReference var;
5075 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
5077 assign = new Assign (var, expr, decl.Location);
5079 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
5082 return implicit_block;
5085 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
5087 Block implicit_block;
5088 VariableDeclaration.FixupTypes (variable_declarators);
5090 if (current_block.Used)
5091 implicit_block = new Block (current_block, true);
5093 implicit_block = current_block;
5095 foreach (VariableDeclaration decl in variable_declarators){
5096 Expression type = decl.type;
5097 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
5098 current_local_parameters, decl.Location);
5101 return implicit_block;
5109 public VarName (object n, object t, object r)
5119 // A class used to pass around variable declarations and constants
5121 public class VariableDeclaration {
5122 public string identifier;
5123 public object expression_or_array_initializer;
5124 public Location Location;
5125 public Attributes OptAttributes;
5126 public Expression type;
5127 public ArrayList dims;
5129 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
5131 this.identifier = id;
5132 this.expression_or_array_initializer = eoai;
5134 this.OptAttributes = opt_attrs;
5139 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
5143 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
5147 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
5148 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
5152 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
5154 // FIXME : This is broken: only the first rank is parsed
5155 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
5158 public static void FixupTypes (ArrayList vars)
5160 int varcount = vars.Count;
5161 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
5163 if (last_var.type == null)
5164 last_var.type = TypeManager.system_object_expr;
5166 Expression cur_type = last_var.type;
5167 int n = varcount - 1;
5170 VariableDeclaration var = (VariableDeclaration) vars[n--];
5171 if (var.type == null)
5172 var.type = cur_type;
5174 cur_type = var.type;
5178 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
5182 if (IndexList != null) {
5183 foreach (Expression e in IndexList)
5184 if (!(e is EmptyExpression)) {
5193 public static bool IndexesSpecified (ArrayList ranks)
5197 if (ranks != null) {
5198 foreach (ArrayList IndexList in ranks) {
5199 if (IndexesSpecifiedInRank (IndexList)) {
5208 public static string StripDims (string varname, ref string d)
5210 string res = varname;
5213 if (varname.IndexOf("[") >= 0) {
5214 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
5215 res = varname.Substring(0, varname.IndexOf("["));
5221 public static string StripDims (string varname)
5225 return (StripDims(varname, ref dres));
5228 public static string StripIndexesFromDims (string dims)
5230 StringBuilder sb = new StringBuilder();
5232 foreach (char c in dims)
5233 if (c == ',' || c == ']' || c == '[')
5236 return sb.ToString();
5239 public static string BuildRank (ArrayList rank)
5242 return BuildRank(rank, out allEmpty);
5245 public static string BuildRank (ArrayList rank, out bool allEmpty)
5252 foreach (object e in rank) {
5253 if (!(e is EmptyExpression))
5264 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
5268 bool allEmpty = true;
5269 foreach (ArrayList rank in rank_specifiers) {
5271 res = BuildRank (rank, out tmp) + res;
5275 if (!allEmpty && mustBeEmpty)
5276 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
5281 public static void VBFixIndexList (ref ArrayList IndexList)
5283 if (IndexList != null) {
5284 for (int x = 0; x < IndexList.Count; x++) {
5285 Expression e = (Expression) IndexList[x];
5286 if (!(e is EmptyExpression)) {
5287 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
5293 public static bool IsArrayDecl (Parser t)
5295 // return (varname.IndexOf("[") >= 0);
5296 return (t.current_rank_specifiers != null);
5299 public static void VBFixIndexLists (ref ArrayList ranks)
5301 if (ranks != null) {
5302 for (int x = 0; x < ranks.Count; x++) {
5303 ArrayList IndexList = (ArrayList) ranks[x];
5304 VBFixIndexList (ref IndexList);
5309 public static void FixupArrayTypes (ArrayList vars)
5313 foreach (VariableDeclaration var in vars) {
5314 if (var.identifier.EndsWith(",")) {
5315 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
5316 var.identifier.LastIndexOf(",")) + "]";
5317 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
5318 var.type = new ComposedCast (var.type, (string) dims, var.Location);
5325 public Property BuildSimpleProperty (Expression p_type, string name,
5326 Field p_fld, int mod_flags,
5327 Attributes attrs, Location loc)
5330 Block get_block, set_block;
5331 Accessor acc_set, acc_get;
5332 StatementExpression a_set;
5337 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
5338 args = new Parameter [1];
5339 args [0] = implicit_value_parameter;
5341 Parameters set_params = new Parameters (args, null, loc);
5342 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
5343 (Expression) new SimpleName("value", loc), loc), loc);
5345 set_block = new Block (current_block, set_params, loc, Location.Null);
5346 set_block.AddStatement ((Statement) a_set);
5347 acc_set = new Accessor (set_block, attrs);
5350 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
5351 get_block = new Block (current_block, null, loc, Location.Null);
5352 get_block.AddStatement ((Statement) a_get);
5353 acc_get = new Accessor (get_block, attrs);
5355 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
5362 current_block = new Block (current_block, current_local_parameters,
5363 lexer.Location, Location.Null);
5370 while (current_block.Implicit)
5371 current_block = current_block.Parent;
5373 res = current_block;
5375 current_block.SetEndLocation (lexer.Location);
5376 current_block = current_block.Parent;
5381 void push_into_stack(int BlockStart, Location l)
5383 end_of_block.Push(BlockStart);
5384 loc_end_of_block.Push(l);
5387 void pop_out_of_stack(int BlockEnd, Location l)
5389 if(BlockEnd != Token.EOF) {
5390 int current = (int)end_of_block.Pop();
5391 Location current_loc = (Location)loc_end_of_block.Pop();
5392 if(BlockEnd != current) {
5393 // Block end is missing
5394 // eg: For 'Sub' BlockEnd should be 'End Sub'
5396 if(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2]) {
5397 while(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2])
5399 if(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2])
5400 Report.Error(error_end_blocks[current,0],current_loc,"'"+end_blocks[current,0]+"' is not having matching '"+end_blocks[current,1]+"'");
5401 current = (int)end_of_block.Pop();
5402 current_loc = (Location)loc_end_of_block.Pop();
5406 // Extra end is present, but works for lesser priority
5407 // (for priority see opt_end_block opt_block_types return values
5408 // eg: 'EndIf' without 'If' inside 'Sub'
5409 // Also certain other errors like 'Sub' having a 'End Module' etc
5410 // can be handled here
5412 if(error_end_blocks[BlockEnd,2] < error_end_blocks[current,2]) {
5413 Report.Error(error_end_blocks[BlockEnd,1],l,"'"+end_blocks[BlockEnd,1]+"' is not having a corresponding '"+end_blocks[BlockEnd,0]+"'");
5414 end_of_block.Push(current);
5415 loc_end_of_block.Push(current_loc);
5417 // Extra end is present but with equal priorty
5419 if((error_end_blocks[BlockEnd,2] == error_end_blocks[current,2]) && BlockEnd != current) {
5420 while((error_end_blocks[BlockEnd,2] == error_end_blocks[current,2]) && BlockEnd != current) {
5421 temp_block.Push(current);
5422 loc_temp_block.Push(current_loc);
5423 current = (int)end_of_block.Pop();
5424 current_loc = (Location)loc_end_of_block.Pop();
5427 if(BlockEnd == current) {
5428 while(temp_block.Count !=0)
5430 int lapse = (int) temp_block.Pop();
5431 Location lapse_location = (Location)loc_temp_block.Pop();
5432 Report.Error(error_end_blocks[lapse,0],lapse_location,"'"+end_blocks[lapse,0]+"' is not having matching '"+end_blocks[lapse,1]+"'");
5437 Report.Error(error_end_blocks[BlockEnd,1],l,"'"+end_blocks[BlockEnd,1]+"' is not having a corresponding '"+end_blocks[BlockEnd,0]+"'");
5438 end_of_block.Push(current);
5439 loc_end_of_block.Push(current_loc);
5440 while(temp_block.Count !=0) {
5441 int lapse = (int) temp_block.Pop();
5442 Location lapse_location = (Location)loc_temp_block.Pop();
5443 end_of_block.Push(lapse);
5444 loc_end_of_block.Push(lapse_location);
5451 while(end_of_block.Count !=0) {
5452 int lapse = (int) end_of_block.Pop();
5453 Location lapse_location = (Location)loc_end_of_block.Pop();
5454 Report.Error(error_end_blocks[lapse,0],lapse_location,"'"+end_blocks[lapse,0]+"' is not having matching '"+end_blocks[lapse,1]+"'");
5459 private void AddHandler (Expression evt_definition, Expression handler_exp)
5461 AddHandler (current_block, evt_definition, handler_exp);
5464 void CheckAttributeTarget (string a)
5468 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
5472 Location l = lexer.Location;
5473 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
5478 private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
5480 Location loc = lexer.Location;
5482 Statement addhnd = (Statement) new AddHandler (evt_id,
5485 b.AddStatement (addhnd);
5488 private void RaiseEvent (string evt_name, ArrayList args)
5490 Location loc = lexer.Location;
5492 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
5493 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
5494 current_block.AddStatement (s);
5497 private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
5499 Location loc = lexer.Location;
5501 Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
5504 b.AddStatement (rmhnd);
5508 // This method is used to get at the complete string representation of
5509 // a fully-qualified type name, hiding inside a MemberAccess ;-)
5510 // This is necessary because local_variable_type admits primary_expression
5511 // as the type of the variable. So we do some extra checking
5513 string GetQualifiedIdentifier (Expression expr)
5515 if (expr is SimpleName)
5516 return ((SimpleName)expr).Name;
5517 else if (expr is MemberAccess)
5518 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
5520 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
5524 private void RemoveHandler (Expression evt_definition, Expression handler_exp)
5526 RemoveHandler (current_block, evt_definition, handler_exp);
5529 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
5531 ConstructorInitializer ci = null;
5534 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
5535 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
5537 if (i.expr is BaseAccess) {
5538 BaseAccess ba = (BaseAccess) i.expr;
5539 if (ba.member == "New" || ba.member == ".ctor") {
5540 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
5544 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
5545 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
5553 void Error_ExpectingTypeName (Location l, Expression expr)
5555 if (expr is Invocation){
5556 Report.Error (1002, l, "; expected");
5558 Report.Error (-1, l, "Invalid Type definition");
5562 public static Expression SetLeftHandFlag (Expression expr) {
5563 if (expr is Invocation) {
5564 Invocation e = (Invocation) expr;
5565 e.IsLeftHand = true;
5567 } else if (expr is MemberAccess) {
5568 MemberAccess e = (MemberAccess) expr;
5569 e.IsLeftHand = true;
5576 public static Expression SetValueRequiredFlag (Expression expr) {
5577 if (expr is Invocation) {
5578 Invocation e = (Invocation) expr;
5579 e.IsRetvalRequired = true;
5583 if (expr is Binary) {
5584 Binary binary = (Binary) expr;
5585 binary.Left = SetValueRequiredFlag (binary.Left);
5586 binary.Right = SetValueRequiredFlag (binary.Right);
5589 if (expr is Unary) {
5590 Unary unary = (Unary) expr;
5591 unary.Expr = SetValueRequiredFlag (unary.Expr);
5597 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
5601 private void ReportError9998()
5603 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
5606 protected override int parse ()
5608 RootContext.InitializeImports(ImportsList);
5609 current_namespace = new Namespace (null, RootContext.RootNamespace);
5610 current_container = RootContext.Tree.Types;
5611 current_container.Namespace = current_namespace;
5612 oob_stack = new Stack ();
5613 switch_stack = new Stack ();
5614 expr_stack = new Stack ();
5615 tmp_blocks = new Stack();
5616 with_stack = new Stack();
5617 statement_stack = new Stack();
5618 end_of_block = new Stack ();
5619 loc_end_of_block = new Stack ();
5620 temp_block = new Stack();
5621 loc_temp_block = new Stack();
5623 allow_global_attribs = true;
5624 expecting_global_attribs = false;
5625 expecting_local_attribs = false;
5626 local_attrib_section_added = false;
5628 UseExtendedSyntax = name.EndsWith(".mbs");
5629 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
5630 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
5631 OptionCompareBinary = InitialOptionCompareBinary;
5633 lexer = new Tokenizer (input, name, defines);
5635 ifElseStateMachine = new IfElseStateMachine();
5636 tokenizerController = new TokenizerController(lexer);
5639 if (yacc_verbose_flag > 0)
5640 yyparse (lexer, new yydebug.yyDebugSimple ());
5646 catch(MBASException e) {
5647 Report.Error(e.code, e.loc, e.Message);
5649 catch (Exception e) {
5650 if (Report.Stacktrace)
5651 Console.WriteLine(e);
5652 Report.Error (29999, lexer.Location, "Parsing error");
5655 RootContext.VerifyImports();
5657 return Report.Errors;
5663 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
5665 catch(ApplicationException) {
5666 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5669 if(in_external_source)
5670 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
5672 if(in_marked_region > 0)
5673 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
5676 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
5679 tokenizerController.PositionTokenizerCursor(tok, expr);
5681 catch(ApplicationException) {
5682 tok = IfElseStateMachine.Token.EOF;
5684 ifElseStateMachine.HandleToken(tok);
5686 catch(ApplicationException) {
5687 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);