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 CaseInsensitiveHashtable constPreDir = new CaseInsensitiveHashtable();
253 public static CaseInsensitiveHashtable with_hash = new CaseInsensitiveHashtable();
255 static public bool InitialOptionExplicit = false;
256 static public bool InitialOptionStrict = false;
257 static public bool InitialOptionCompareBinary = true;
258 static public ArrayList ImportsList = null;
260 static public bool OptionExplicit;
261 static public bool OptionStrict;
262 static public bool OptionCompareBinary;
264 static public bool UseExtendedSyntax; // for ".mbs" files
266 bool implicit_modifiers;
268 public override string[] extensions()
270 string [] list = { ".vb", ".mbs" };
274 bool in_external_source = false;
275 int in_marked_region = 0;
277 TokenizerController tokenizerController;
278 IfElseStateMachine ifElseStateMachine;
281 public class IfElseStateMachine {
305 public static Hashtable errStrings = new Hashtable();
308 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
310 static IfElseStateMachine()
312 // FIXME: Fix both the error nos and the error strings.
313 // Currently the error numbers and the error strings are
314 // just placeholders for getting the state-machine going.
316 errStrings.Add(0, "");
317 errStrings.Add(30012, "#If must end with a matching #End If");
318 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
319 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
320 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
321 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
323 errTable[(int)State.START, (int)Token.IF] = 0;
324 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
325 errTable[(int)State.START, (int)Token.ELSE] = 30028;
326 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
327 errTable[(int)State.START, (int)Token.EOF] = 0;
329 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
330 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
331 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
332 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
333 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
335 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
336 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
337 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
338 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
339 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
341 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
342 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
343 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
344 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
345 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
347 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
348 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
349 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
350 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
351 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
354 public IfElseStateMachine()
358 stateStack = new Stack();
359 stateStack.Push(state);
362 // The parameter here need not be qualified with IfElseStateMachine
363 // But it hits a bug in mcs. So temporarily scoping it so that builds
366 public void HandleToken(IfElseStateMachine.Token tok)
368 err = (int) errTable[(int)state, (int)tok];
371 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
373 if(tok == Token.IF) {
374 stateStack.Push(state);
377 else if(tok == Token.ENDIF) {
378 state = (State)stateStack.Pop();
390 public string ErrString {
392 return (string) errStrings[err];
398 public class TokenizerController {
402 public bool CanAcceptTokens;
403 public bool CanSelectBlock;
410 public TokenizerController(Tokenizer lexer)
413 stateStack = new Stack();
415 currentState.CanAcceptTokens = true;
416 currentState.CanSelectBlock = true;
418 stateStack.Push(currentState);
423 return (State)stateStack.Peek();
427 public bool IsAcceptingTokens {
429 return currentState.CanAcceptTokens;
433 public void PositionCursorAtNextPreProcessorDirective()
435 lexer.PositionCursorAtNextPreProcessorDirective();
438 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
440 if(tok == IfElseStateMachine.Token.ENDIF) {
441 currentState = (State)stateStack.Pop();
443 if(currentState.CanAcceptTokens)
446 PositionCursorAtNextPreProcessorDirective();
451 if(tok == IfElseStateMachine.Token.IF) {
452 stateStack.Push(currentState);
454 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
455 currentState.CanSelectBlock = true;
458 if(parentState.CanAcceptTokens &&
459 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
461 currentState.CanAcceptTokens = true;
462 currentState.CanSelectBlock = false;
466 currentState.CanAcceptTokens = false;
467 PositionCursorAtNextPreProcessorDirective();
473 bool allow_global_attribs = true;
475 bool expecting_global_attribs = false;
476 bool expecting_local_attribs = false;
478 bool local_attrib_section_added = false;
482 %token NONE /* This token is never returned by our lexer */
483 %token ERROR // This is used not by the parser, but by the tokenizer.
487 *These are the MonoBASIC keywords
580 %token NOTINHERITABLE
581 %token NOTOVERRIDABLE
637 %token YIELD // MonoBASIC extension
641 /* MonoBASIC single character operators/punctuation. */
643 %token OPEN_BRACKET "["
644 %token CLOSE_BRACKET "]"
645 %token OPEN_PARENS "("
646 %token OPEN_BRACE "{"
647 %token CLOSE_BRACE "}"
648 %token CLOSE_PARENS ")"
662 %token OP_IDIV "\\" //FIXME: This should be "\"
664 %token EXCLAMATION "!"
667 %token LONGTYPECHAR "&"
669 %token SINGLETYPECHAR "!"
670 %token NUMBER_SIGN "#"
671 %token DOLAR_SIGN "$"
673 %token ATTR_ASSIGN ":="
675 /* MonoBASIC multi-character operators. */
680 //%token OP_MODULUS //"mod"
682 /* VB.NET 2003 new bit-shift operators */
683 %token OP_SHIFT_LEFT "<<"
684 %token OP_SHIFT_RIGHT ">>"
687 %token LITERAL_INTEGER "int literal"
688 %token LITERAL_SINGLE "float literal"
689 %token LITERAL_DOUBLE "double literal"
690 %token LITERAL_DECIMAL "decimal literal"
691 %token LITERAL_CHARACTER "character literal"
692 %token LITERAL_STRING "string literal"
693 %token LITERAL_DATE "datetime literal"
698 /* Add precedence rules to solve dangling else s/r conflict */
707 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
709 %left STAR DIV PERCENT
710 %right BITWISE_NOT CARRET UMINUS
711 %nonassoc OP_INC OP_DEC
713 %left OPEN_BRACKET OPEN_BRACE
718 %start compilation_unit
722 : logical_end_of_line
729 | logical_end_of_line pp_directive
733 : logical_end_of_line _mark_
734 opt_option_directives
735 opt_imports_directives
741 | logical_end_of_line _mark_
742 opt_option_directives
743 opt_imports_directives
751 opt_option_directives
758 | option_directives option_directive
762 : option_explicit_directive
763 | option_strict_directive
764 | option_compare_directive
765 | OPTION _mark_ logical_end_of_line
767 Report.Error(30206 ,(Location)$2, "Option must be followed by 'Compare' or 'Explicit' or 'Strict'");
769 | OPTION _mark_ IDENTIFIER logical_end_of_line
771 Report.Error(30206 ,(Location)$2, "Option must be followed by 'Compare' or 'Explicit' or 'Strict'");
801 option_explicit_directive
802 : OPTION EXPLICIT _mark_ on_off logical_end_of_line
804 if (!UseExtendedSyntax)
805 OptionExplicit = (bool)$4;
809 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
814 option_strict_directive
815 : OPTION STRICT _mark_ on_off logical_end_of_line
817 if (!UseExtendedSyntax)
818 OptionStrict = (bool)$4;
822 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
826 option_compare_directive
827 : OPTION COMPARE text_or_binary logical_end_of_line
829 OptionCompareBinary = (bool)$3;
840 | declarations declaration
844 : declaration_qualifiers
846 // FIXME: Need to check declaration qualifiers for multi-file compilation
847 // FIXME: Qualifiers cannot be applied to namespaces
848 allow_global_attribs = false;
850 namespace_declaration
851 |declaration_qualifiers _mark_
853 // FIXME: Need to check declaration qualifiers for multi-file compilation
854 allow_global_attribs = false;
856 type_spec_declaration
861 if ($4 is Class || $4 is Struct || $4 is Module ){
862 TypeContainer c = (TypeContainer) $4;
863 mod_flags = c.ModFlags;
868 if ((mod_flags & (Modifiers.PRIVATE)) != 0){
871 "Namespace elements cannot be explicitly " +
872 "declared private in '" + name + "'");
874 else if ((mod_flags & (Modifiers.PROTECTED)) != 0){
877 "Namespace elements cannot be explicitly " +
878 "declared protected in '" + name + "'");
893 : PERCENT { $$ = typeof (int); }
894 | LONGTYPECHAR { $$ = typeof (long); }
895 | AT_SIGN { $$ = typeof (decimal); }
896 | SINGLETYPECHAR { $$ = typeof (float); }
897 | NUMBER_SIGN { $$ = typeof (double); }
898 | DOLAR_SIGN { $$ = typeof (string); }
902 : /* empty */ { $$ = null; }
903 | type_character { $$ = $1; }
909 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
911 $$ = (($1).ToString ()) + "." + ($3.ToString ());
915 opt_imports_directives
922 | imports_directives imports_directive
926 : IMPORTS imports_terms logical_end_of_line
931 | imports_terms COMMA imports_term
935 : namespace_or_type_name
937 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
939 | identifier _mark_ ASSIGN namespace_or_type_name
941 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $4, (Location)$2);
943 | identifier _mark_ ASSIGN
945 Report.Error(30203, (Location)$2, "Alias Statement no complete: Expression Expected");
949 Report.Error(30203, (Location)$1, "No namespace imported: Expression Expected");
954 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
955 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
956 | OPEN_PARENS _mark_ opt_formal_parameter_list CLOSE_PARENS { $$ = $3; }
959 Report.Error(30203,(Location)$2, "Identifier Expected");
960 $$ = Parameters.EmptyReadOnlyParameters;
962 | OPEN_PARENS _mark_ opt_formal_parameter_list error
964 Report.Error(30198,(Location)$2, "'(' is not having a matching ')'");
967 | error _mark_ opt_formal_parameter_list CLOSE_PARENS
969 Report.Error(30205,(Location)$2, "')' is not having a matching '('");
979 local_attrib_section_added = false;
988 expecting_local_attribs = false;
989 expecting_global_attribs = false;
993 if (expecting_local_attribs) {
994 local_attrib_section_added = true;
995 allow_global_attribs = false;
997 $$ = new Attributes ((ArrayList) $1);
1000 if (expecting_global_attribs) {
1002 CodeGen.AddGlobalAttributes ((ArrayList) $1);
1005 expecting_local_attribs = false;
1006 expecting_global_attribs = false;
1008 | attribute_sections
1010 $$ = lexer.Location;
1016 ArrayList attrs = (ArrayList) $3;
1018 if (expecting_local_attribs) {
1019 if (local_attrib_section_added) {
1020 expecting_local_attribs = false;
1021 expecting_global_attribs = false;
1022 Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
1027 $$ = new Attributes (attrs);
1029 ((Attributes) $1).Add (attrs);
1031 local_attrib_section_added = true;
1032 allow_global_attribs = false;
1035 if (expecting_global_attribs) {
1037 CodeGen.AddGlobalAttributes ((ArrayList) $3);
1041 expecting_local_attribs = false;
1042 expecting_global_attribs = false;
1047 : OP_LT _mark_ attribute_list OP_GT opt_end_of_stmt
1051 if (expecting_global_attribs && !(bool) $5) {
1052 Report.Error (30205, (Location)$2, "End of statement expected");
1056 if (expecting_local_attribs) {
1058 Report.Error (32035, (Location)$2, "Use a line continuation after the attribute specifier to apply it to the following statement.");
1069 : /* empty */ { $$ = false; }
1070 | end_of_stmt { $$ = true; }
1076 ArrayList attrs = null;
1078 attrs = new ArrayList ();
1083 | attribute_list COMMA attribute
1085 ArrayList attrs = null;
1088 attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
1097 : namespace_or_type_name
1099 $$ = lexer.Location;
1101 opt_attribute_arguments
1105 if (expecting_global_attribs)
1106 Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
1108 expecting_local_attribs = true;
1109 $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
1112 | attribute_target_specifier
1114 $$ = lexer.Location;
1117 namespace_or_type_name
1119 $$ = lexer.Location;
1121 opt_attribute_arguments
1125 string attribute_target = (string) $1;
1126 if (attribute_target != "assembly" && attribute_target != "module") {
1127 Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
1130 if (!allow_global_attribs) {
1131 Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
1135 if (expecting_local_attribs) {
1136 Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
1140 expecting_global_attribs = true;
1141 $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
1145 attribute_target_specifier
1146 : ASSEMBLY { $$ = "assembly"; }
1147 | MODULE { $$ = "module"; }
1148 | namespace_or_type_name
1152 opt_attribute_arguments
1153 : /* empty */ { $$ = null; }
1154 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
1160 opt_attribute_arguments_list
1162 | attribute_arguments_list
1165 attribute_arguments_list
1166 : positional_argument_list
1168 ArrayList args = new ArrayList ();
1173 | positional_argument_list COMMA named_argument_list
1175 ArrayList args = new ArrayList ();
1181 | named_argument_list
1183 ArrayList args = new ArrayList ();
1191 positional_argument_list
1192 : constant_expression
1194 ArrayList args = new ArrayList ();
1195 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
1199 | positional_argument_list COMMA constant_expression
1201 ArrayList args = (ArrayList) $1;
1202 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
1211 ArrayList args = new ArrayList ();
1216 | named_argument_list COMMA named_argument
1218 ArrayList args = (ArrayList) $1;
1226 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
1228 $$ = new DictionaryEntry (
1230 new Argument ((Expression) $3, Argument.AType.Expression));
1234 namespace_declaration
1235 : NAMESPACE _mark_ qualified_identifier logical_end_of_line
1237 push_into_stack((int)Start_block.NAMESPACE, (Location)$2);
1238 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
1244 pop_out_of_stack((int)$7, lexer.Location);
1248 current_namespace = current_namespace.Parent;
1252 declaration_qualifiers
1256 current_attributes = (Attributes) $1;
1257 current_modifiers = (int) $2;
1261 type_spec_declaration
1263 | module_declaration
1264 | interface_declaration
1265 | delegate_declaration
1266 | struct_declaration
1271 : CLASS identifier _mark_ end_of_stmt opt_inherits opt_implements
1273 // Module members are static by default, but Class *can't* be declared static
1274 // so we must fix it, if mbas was the one actually responsible for this
1275 // instead of triggering an error.
1276 push_into_stack((int)Start_block.CLASS, (Location)$3);
1278 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1279 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1284 name = MakeName ((string) $2);
1285 new_class = new Class (current_container, name, current_modifiers,
1286 (Attributes) current_attributes, (Location)$3);
1288 current_container = new_class;
1289 current_container.Namespace = current_namespace;
1290 RootContext.Tree.RecordDecl (name, new_class);
1292 opt_class_member_declarations
1295 pop_out_of_stack((int)$9, lexer.Location);
1299 Class new_class = (Class) current_container;
1301 ArrayList bases = (ArrayList) $5;
1303 ArrayList ifaces = (ArrayList) $6;
1304 if (ifaces != null){
1306 bases.AddRange(ifaces);
1310 new_class.Bases = bases;
1312 current_container = current_container.Parent;
1313 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1320 : /* empty */ { $$ = null; }
1321 | INHERITS type_list end_of_stmt { $$ = $2; }
1325 : /* empty */ { $$ = null; }
1326 | IMPLEMENTS type_list end_of_stmt { $$ = $2; }
1330 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1331 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1336 | modifiers modifier
1341 if ((m1 & m2) != 0) {
1342 Location l = lexer.Location;
1343 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1345 $$ = (int) (m1 | m2);
1350 : PUBLIC { $$ = Modifiers.PUBLIC; }
1351 | PROTECTED { $$ = Modifiers.PROTECTED; }
1352 | PRIVATE { $$ = Modifiers.PRIVATE; }
1353 | SHARED { $$ = Modifiers.STATIC; }
1354 | FRIEND { $$ = Modifiers.INTERNAL; }
1355 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1356 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1357 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1358 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1359 | OVERLOADS { $$ = Modifiers.NEW; }
1360 | SHADOWS { $$ = Modifiers.SHADOWS; }
1361 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1362 | READONLY { $$ = Modifiers.READONLY; }
1363 | DEFAULT { $$ = Modifiers.DEFAULT; }
1364 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1368 : MODULE _mark_ identifier logical_end_of_line
1370 push_into_stack((int)Start_block.MODULE, (Location)$2);
1373 name = MakeName((string) $3);
1374 new_module = new Module(current_container,
1376 current_modifiers, // already checks then
1377 (Attributes) current_attributes,
1379 current_container = new_module;
1380 current_container.Namespace = current_namespace;
1381 RootContext.Tree.RecordDecl(name, new_module);
1383 opt_module_member_declarations
1386 pop_out_of_stack((int)$7, lexer.Location);
1390 Module new_module = (Module)current_container;
1392 current_container = current_container.Parent;
1393 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1395 TypeManager.AddStandardModule(new_module);
1401 opt_module_member_declarations
1403 | module_member_declarations
1406 module_member_declarations
1407 : module_member_declaration
1408 | module_member_declarations module_member_declaration
1411 module_member_declaration
1415 current_attributes = (Attributes) $1;
1416 current_modifiers = ((int)$2) | Modifiers.STATIC;
1417 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1418 implicit_modifiers = (!explicit_static);
1420 module_member_declarator
1422 implicit_modifiers = false;
1427 module_member_declarator
1428 : constructor_declaration
1429 | method_declaration
1431 Method method = (Method) $1;
1432 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1435 | withevents_declaration /* This is a field but must be treated specially, see below */
1436 | constant_declaration
1437 | property_declaration
1439 | type_spec_declaration
1442 constant_declaration
1443 : CONST constant_declarators end_of_stmt
1445 // Module members are static by default, but constants *can't* be declared static
1446 // so we must fix it, if mbas was the one actually responsible for this
1447 // instead of triggering an error.
1448 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1449 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1451 int mod = (int) current_modifiers;
1453 // Structure members are Public by default
1454 if ((current_container is Struct) && (mod == 0))
1455 mod = Modifiers.PUBLIC;
1457 ArrayList consts = (ArrayList) $2;
1458 if(consts.Count > 0)
1460 VariableDeclaration.FixupTypes ((ArrayList) $2);
1461 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1463 foreach (VariableDeclaration var in (ArrayList) $2){
1464 Location l = var.Location;
1465 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1466 (Expression)var.expression_or_array_initializer,
1467 mod, (Attributes) null, l);
1469 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1475 opt_class_member_declarations
1477 | class_member_declarations
1480 class_member_declarations
1481 : class_member_declaration
1482 | class_member_declarations class_member_declaration
1485 class_member_declaration
1489 current_attributes = (Attributes) $1;
1490 current_modifiers = (int) $2;
1492 class_member_declarator
1498 class_member_declarator
1499 : constructor_declaration
1500 | method_declaration
1502 Method method = (Method) $1;
1503 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1506 | constant_declaration
1507 | property_declaration
1509 | withevents_declaration /* This is a field but must be treated specially, see below */
1510 | type_spec_declaration
1517 | must_override_declaration
1520 must_override_declaration
1521 : must_override_sub_declaration
1522 | must_override_func_declaration
1525 must_override_sub_declaration
1526 : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause _mark_ logical_end_of_line
1528 if (current_container is Module)
1529 Report.Error (30433, (Location)$6, "Methods in a Module cannot be declared 'MustOverride'.");
1531 if (current_container is Struct)
1532 Report.Error (435, (Location)$6, "Methods in a Structure cannot be declared 'MustOverride'.");
1534 current_modifiers |= Modifiers.ABSTRACT;
1536 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1537 (Parameters) $4, null, (ArrayList) $5, (Location)$6);
1539 if (!(current_container is Class))
1540 Report.Error (9999, (Location)$6, "THIS SHOULD NEVER HAPPEN!");
1547 must_override_func_declaration
1548 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
1550 Expression ftype = ($7 == null) ? (($4 == null) ? TypeManager.
1551 system_object_expr : (Expression) TypeManager.TypeToCoreTypeExpr ((Type) $4) ) : (Expression) $7;
1553 if (current_container is Module)
1554 Report.Error (30433, (Location)$6,"Methods in a Module cannot be declared 'MustOverride'.");
1556 if (current_container is Struct)
1557 Report.Error (435, (Location)$6,"Methods in a Structure cannot be declared 'MustOverride'.");
1559 current_modifiers |= Modifiers.ABSTRACT;
1561 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1562 (string) $3,(Parameters) $5, null, (ArrayList) $8,
1565 if (!(current_container is Class))
1566 Report.Error (9999, (Location)$6,"THIS SHOULD NEVER HAPPEN!");
1573 : SUB identifier _mark_ opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1575 push_into_stack((int)Start_block.SUB, (Location)$3);
1576 current_local_parameters = (Parameters) $4;
1577 start_method_block((string) $2);
1579 // Structure members are Public by default
1580 if ((current_container is Struct) && (current_modifiers == 0))
1581 current_modifiers = Modifiers.PUBLIC;
1587 pop_out_of_stack((int)$10, lexer.Location);
1591 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1592 (Parameters) current_local_parameters, (Attributes) current_attributes,
1593 (ArrayList) $6, (Location)$3);
1595 method.Block = (Block) end_block();
1597 if ( ((MethodBlock) method.Block).onerror != null ) {
1598 method.Block = ((MethodBlock) method.Block).onerror;
1603 // we have event handlers to take care of
1605 ArrayList list = (ArrayList) $5;
1606 Location loc = (Location)$3;
1608 foreach (Expression handles_exp in list) {
1609 if (handles_exp is MemberAccess) {
1610 string evt_def = ((MemberAccess)handles_exp).ToString();
1611 int pos = evt_def.LastIndexOf (".");
1612 string evt_target = evt_def.Substring (0, pos);
1615 if (current_container.Properties != null) {
1616 foreach (Property p in current_container.Properties) {
1617 if (p.Name == evt_target) {
1620 Statement addhnd = (Statement) new AddHandler (handles_exp,
1621 DecomposeQI((string) $2, loc),
1624 current_container.AddEventHandler (addhnd);
1632 Report.Error(30506, (Location)$3,
1633 evt_target + " is not declared with WithEvents");
1635 } else if (handles_exp is BaseAccess) {
1636 Statement addhnd = (Statement) new AddHandler (handles_exp,
1637 DecomposeQI((string) $2, loc),
1640 current_container.AddEventHandler (addhnd);
1648 : FUNCTION identifier opt_type_character
1649 opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
1651 push_into_stack((int)Start_block.FUNCTION, (Location)$5);
1652 current_local_parameters = (Parameters) $4;
1653 start_method_block((string) $2);
1655 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) TypeManager.TypeToCoreTypeExpr ((Type) $3) ) : (Expression) $6;
1657 // Structure members are Public by default
1658 if ((current_container is Struct) && (current_modifiers == 0))
1659 current_modifiers = Modifiers.PUBLIC;
1660 // Add local var declaration
1662 ArrayList retval = new ArrayList ();
1663 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, (Location)$5));
1664 Block implicit_block = declare_local_variables ((Expression) ftype, retval, (Location)$5);
1665 implicit_block.GetVariableInfo((string) $2).Used = true;
1670 pop_out_of_stack((int)$11, lexer.Location);
1674 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) TypeManager.TypeToCoreTypeExpr ((Type) $3) ) : (Expression) $6;
1676 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1677 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1678 (ArrayList) $7, (Location)$5);
1679 method.Block = end_block();
1685 : STRUCTURE _mark_ identifier end_of_stmt
1686 opt_implement_clause
1688 push_into_stack((int)Start_block.STRUCTURE, (Location)$2);
1690 string full_struct_name = MakeName ((string) $3);
1692 // Module members are static by default, but structures *can't* be declared static
1693 // so we must fix it, if mbas was the one actually responsible for this
1694 // instead of triggering an error.
1695 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1696 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1698 new_struct = new Struct (current_container, full_struct_name,
1699 (int) current_modifiers,
1700 (Attributes) current_attributes, (Location)$2);
1701 current_container = new_struct;
1702 current_container.Namespace = current_namespace;
1703 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1705 opt_struct_member_declarations
1707 Struct new_struct = (Struct) current_container;
1710 new_struct.Bases = (ArrayList) $5;
1712 current_container = current_container.Parent;
1713 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1718 pop_out_of_stack((int)$9, lexer.Location);
1723 opt_struct_member_declarations
1725 | struct_member_declarations
1728 struct_member_declarations
1729 : struct_member_declaration
1730 | struct_member_declarations struct_member_declaration
1733 struct_member_declaration
1735 struct_member_declarator
1738 struct_member_declarator
1740 | constant_declaration
1741 | constructor_declaration
1742 | method_declaration
1744 Method method = (Method) $1;
1745 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1747 | property_declaration
1749 | type_spec_declaration
1752 * This is only included so we can flag error 575:
1753 * destructors only allowed on class types
1755 //| destructor_declaration
1759 : EVENT identifier _mark_ AS type opt_implement_clause logical_end_of_line
1761 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $5, (Location)$3);
1763 Event e = new Event ((Expression) $5, var.identifier,
1764 null, current_modifiers,
1765 current_attributes, (ArrayList) $6,
1768 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1770 | EVENT identifier _mark_ opt_params opt_implement_clause logical_end_of_line
1772 string delName = null;
1775 delName = (string) $2;
1776 delName = delName + "EventHandler";
1777 int modifiers = (implicit_modifiers) ? (current_modifiers & ~ (Modifiers.STATIC) ): current_modifiers;
1778 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1779 (current_container, TypeManager.system_void_expr,
1780 (int) modifiers, MakeName(delName), (Parameters) $4,
1781 (Attributes) current_attributes, (Location)$3);
1783 del.Namespace = current_namespace;
1784 CheckDef (current_container.AddDelegate (del), del.Name, (Location)$3);
1786 ArrayList impls = (ArrayList) $5;
1787 if (impls.Count > 1) {
1788 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1789 "' can not be implemented with Event '" +
1790 (string) $2 + "', since it's delegate type does not match " +
1791 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1792 Report.Error (31407, (Location)$3, expstr);
1794 Expression impl = (Expression) impls[0];
1795 delName = impl.ToString();
1796 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1797 delName = delName + "EventHandler";
1800 Event e = new Event (DecomposeQI (delName, (Location)$3),
1802 null, current_modifiers,
1803 current_attributes, (ArrayList) $5,
1806 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1811 : ENUM _mark_ identifier opt_type_spec logical_end_of_line
1812 opt_enum_member_declarations
1814 push_into_stack((int)Start_block.ENUM, (Location)$2);
1815 Location enum_location = (Location)$2;
1816 string full_name = MakeName ((string) $3);
1817 Expression enum_type = ($4 == null) ? TypeManager.system_int32_expr : (Expression) $4;
1818 ArrayList enum_members = (ArrayList) $6;
1820 if (enum_members.Count == 0)
1821 Report.Error (30280, enum_location,
1822 "Enum can not have empty member list");
1824 // Module members are static by default, but enums *can't* be declared static
1825 // so we must fix it if mbas was the one actually responsible for this
1826 // instead of triggering an error.
1827 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1828 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1830 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1831 (int) current_modifiers, full_name,
1832 (Attributes) current_attributes, enum_location);
1834 foreach (VariableDeclaration ev in enum_members) {
1835 Location loc = (Location) ev.Location;
1837 CheckDef (e.AddEnumMember (ev.identifier,
1838 (Expression) ev.expression_or_array_initializer,
1839 loc, ev.OptAttributes), ev.identifier, loc);
1842 e.Namespace = current_namespace;
1844 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1845 RootContext.Tree.RecordDecl (full_name, e);
1850 pop_out_of_stack((int)$8,lexer.Location);
1855 opt_enum_member_declarations
1856 : /* empty */ { $$ = new ArrayList (); }
1857 | enum_member_declarations { $$ = $1; }
1860 enum_member_declarations
1861 : enum_member_declaration
1863 ArrayList l = new ArrayList ();
1868 | enum_member_declarations enum_member_declaration
1870 ArrayList l = (ArrayList) $1;
1878 enum_member_declaration
1879 : opt_attributes identifier _mark_ logical_end_of_line
1881 $$ = new VariableDeclaration ((string) $2, null, (Location)$3, (Attributes) $1);
1883 | opt_attributes identifier
1885 $$ = lexer.Location;
1887 ASSIGN expression logical_end_of_line
1889 $$ = new VariableDeclaration ((string) $2, (Expression)$5, (Location)$3, (Attributes) $1);
1893 interface_declaration
1894 : INTERFACE _mark_ identifier logical_end_of_line
1896 push_into_stack((int)Start_block.INTERFACE, (Location)$2);
1897 Interface new_interface;
1898 string full_interface_name = MakeName ((string) $3);
1900 int modifiers = (implicit_modifiers) ? (current_modifiers & ~ (Modifiers.STATIC) ) : current_modifiers;
1901 new_interface = new Interface (current_container, full_interface_name, modifiers,
1902 (Attributes) current_attributes, (Location)$2);
1903 current_interface = new_interface;
1904 new_interface.Namespace = current_namespace;
1905 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1910 Interface new_interface = (Interface) current_interface;
1913 new_interface.Bases = (ArrayList) $6;
1915 current_interface = null;
1917 CheckDef (current_container.AddInterface (new_interface),new_interface.Name, new_interface.Location);
1921 pop_out_of_stack((int)$9, lexer.Location);
1927 : /* empty */ { $$ = null; }
1933 | interface_bases interface_base
1935 ArrayList bases = (ArrayList) $1;
1936 bases.AddRange ((ArrayList) $2);
1942 : INHERITS type_list logical_end_of_line { $$ = $2; }
1946 : opt_interface_member_declarations
1947 | opt_interface_declaration
1950 opt_interface_declaration
1951 : INTERFACE _mark_ identifier logical_end_of_line
1953 push_into_stack((int)Start_block.INTERFACE, (Location)$2);
1954 Interface new_interface;
1955 string full_interface_name = MakeName ((string) $3);
1957 int modifiers = (implicit_modifiers) ? (current_modifiers & ~ (Modifiers.STATIC) ) : current_modifiers;
1958 new_interface = new Interface (current_interface, full_interface_name, modifiers,
1959 (Attributes) current_attributes, (Location)$2);
1961 CheckDef (current_interface.AddInterface (new_interface),new_interface.Name, new_interface.Location);
1963 current_interface = new_interface;
1965 new_interface.Namespace = current_namespace;
1966 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1971 Interface new_interface = (Interface) current_interface;
1974 new_interface.Bases = (ArrayList) $6;
1978 current_interface = (Interface)current_interface.Parent;
1980 pop_out_of_stack((int)$9, lexer.Location);
1988 opt_interface_member_declarations
1990 | interface_member_declarations
1993 interface_member_declarations
1994 : interface_member_declaration
1995 | interface_member_declarations interface_member_declaration
1998 interface_member_declaration
2002 current_attributes = (Attributes) $1;
2003 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
2005 interface_member_declarator
2011 interface_member_declarator
2012 : interface_method_declaration
2014 Method m = (Method) $1;
2015 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
2017 | interface_property_declaration
2018 | interface_event_declaration
2021 interface_method_declaration
2022 : SUB identifier opt_params _mark_ logical_end_of_line
2024 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
2025 (Parameters) $3, current_attributes, null, (Location)$4);
2029 | FUNCTION identifier opt_type_character opt_params _mark_ opt_type_with_ranks logical_end_of_line
2031 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.
2032 system_object_expr : (Expression) TypeManager.TypeToCoreTypeExpr ((Type) $3) ) : (Expression) $6;
2034 Method method = new Method ((Expression) ftype, (int) current_modifiers,
2035 (string) $2,(Parameters) $4, current_attributes, null,
2042 interface_property_declaration
2043 : PROPERTY identifier _mark_ opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
2045 Expression ftype = ($6 == null) ? (($4 == null) ?
2046 TypeManager.system_object_expr : (Expression) TypeManager.TypeToCoreTypeExpr ((Type) $4) ) : (Expression) $6;
2048 if ( OptionStrict && ($4 == null) && ($6 == null) ) {
2049 Report.Error (30210,
2051 "Option Strict On requires all function and property "+
2052 "declarations to have an 'As' clause or a type character.");
2055 current_local_parameters = (Parameters) $5;
2056 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2057 get_parameters = current_local_parameters.Copy ((Location)$3);
2058 set_parameters = current_local_parameters.Copy ((Location)$3);
2060 Parameter implicit_value_parameter = new Parameter (
2061 ftype, "Value", Parameter.Modifier.NONE, null);
2063 set_parameters.AppendParameter (implicit_value_parameter);
2067 get_parameters = Parameters.EmptyReadOnlyParameters;
2068 set_parameters = new Parameters (null, null ,(Location)$3);
2070 Parameter implicit_value_parameter = new Parameter (
2071 ftype, "Value", Parameter.Modifier.NONE, null);
2073 set_parameters.AppendParameter (implicit_value_parameter);
2075 lexer.PropertyParsing = true;
2077 Accessor get_block = new Accessor (null, null);
2079 Accessor set_block = null;
2081 if ((current_modifiers & Modifiers.READONLY) == 0)
2082 set_block = new Accessor (null, null);
2084 int modifiers = (implicit_modifiers) ? (current_modifiers & ~ (Modifiers.STATIC) ): current_modifiers;
2085 Property prop = new Property ((Expression) ftype, (string) $2, modifiers,
2086 get_block, set_block, current_attributes, (Location)$3,
2087 null, get_parameters, set_parameters, null);
2089 CheckDef (current_interface.AddProperty (prop), prop.Name, (Location)$3);
2091 get_implicit_value_parameter_type = null;
2092 set_implicit_value_parameter_type = null;
2093 get_parameters = null;
2094 set_parameters = null;
2095 current_local_parameters = null;
2099 interface_event_declaration
2100 : EVENT identifier AS _mark_ type logical_end_of_line
2102 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $5, (Location)$4);
2104 Event e = new Event ((Expression) $5, var.identifier,
2105 null, current_modifiers,
2106 current_attributes, (Location)$4);
2108 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2111 | EVENT identifier opt_params _mark_ logical_end_of_line
2113 string delName = (string) $2;
2114 delName = delName + "EventHandler";
2115 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
2116 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
2117 (current_container, TypeManager.system_void_expr,
2118 (int) delModifiers, MakeName(delName), (Parameters) $3,
2119 (Attributes) current_attributes, (Location)$4);
2121 del.Namespace = current_namespace;
2122 CheckDef (current_interface.AddDelegate (del), del.Name, (Location)$4);
2124 Event e = new Event (DecomposeQI (delName, (Location)$4),
2126 null, current_modifiers,
2127 current_attributes, (Location)$4);
2129 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2133 property_declaration
2134 : abstract_propery_declaration
2135 | non_abstract_propery_declaration
2138 abstract_propery_declaration
2139 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters _mark_ opt_type_with_ranks logical_end_of_line
2141 Expression ftype = ($7 == null) ? (($4 == null) ?
2142 TypeManager.system_object_expr : (Expression) TypeManager.TypeToCoreTypeExpr ((Type) $4) ) : (Expression) $7;
2144 if (current_container is Module)
2145 Report.Error (30503, (Location) $6 , "Properties in a Module cannot be declared 'MustOverride'.");
2147 if (current_container is Struct)
2148 Report.Error (435, (Location) $6 ,"Methods in a Structure cannot be declared 'MustOverride'.");
2150 if ( OptionStrict && ($4 == null) && ($7 == null) ) {
2151 Report.Error (30210,
2153 "Option Strict On requires all function and property "+
2154 "declarations to have an 'As' clause or a type character.");
2157 current_modifiers |= Modifiers.ABSTRACT;
2159 current_local_parameters = (Parameters) $5;
2160 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2161 get_parameters = current_local_parameters.Copy (lexer.Location);
2162 set_parameters = current_local_parameters.Copy (lexer.Location);
2164 Parameter implicit_value_parameter = new Parameter (
2165 ftype, "Value", Parameter.Modifier.NONE, null);
2167 set_parameters.AppendParameter (implicit_value_parameter);
2171 get_parameters = Parameters.EmptyReadOnlyParameters;
2172 set_parameters = new Parameters (null, null ,lexer.Location);
2174 Parameter implicit_value_parameter = new Parameter (
2175 ftype, "Value", Parameter.Modifier.NONE, null);
2177 set_parameters.AppendParameter (implicit_value_parameter);
2179 lexer.PropertyParsing = true;
2181 Accessor get_block = new Accessor (null, null);
2182 Accessor set_block = new Accessor (null, null);
2184 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
2185 get_block, set_block, current_attributes, lexer.Location,
2186 null, get_parameters, set_parameters, null);
2188 if (!(current_container is Class))
2189 Report.Error (9999, (Location) $6, "THIS SHOULD NEVER HAPPEN!");
2191 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
2193 get_implicit_value_parameter_type = null;
2194 set_implicit_value_parameter_type = null;
2195 get_parameters = null;
2196 set_parameters = null;
2197 current_local_parameters = null;
2202 non_abstract_propery_declaration
2203 : PROPERTY identifier
2205 opt_property_parameters
2208 opt_implement_clause
2210 push_into_stack((int)Start_block.PROPERTY, (Location)$5);
2211 if ((current_modifiers & Modifiers.DEFAULT) > 0) {
2212 if (current_container.DefaultPropName != null
2213 && current_container.DefaultPropName != (string) $2)
2214 Report.Error (30359,
2216 "Type '" + current_container.Name +
2217 "' cannot have more than one 'Default Property' ");
2219 current_container.DefaultPropName = (string) $2;
2222 if ( OptionStrict && ($3 == null) && ($6 == null) ) {
2223 Report.Error (30210,
2225 "Option Strict On requires all function and property "+
2226 "declarations to have an 'As' clause or a type character.");
2230 get_implicit_value_parameter_type =
2231 ($6 == null) ? (($3 == null) ?
2232 TypeManager.system_object_expr : (Expression) TypeManager.TypeToCoreTypeExpr ((Type) $3) ): (Expression) $6;
2233 get_implicit_value_parameter_name = (string) $2;
2235 current_local_parameters = (Parameters) $4;
2236 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2237 get_parameters = current_local_parameters.Copy ((Location)$5);
2238 set_parameters = current_local_parameters.Copy ((Location)$5);
2242 get_parameters = Parameters.EmptyReadOnlyParameters;
2243 set_parameters = new Parameters (null, null ,(Location)$5);
2245 lexer.PropertyParsing = true;
2250 accessor_declarations
2253 pop_out_of_stack((int)$11,lexer.Location);
2257 lexer.PropertyParsing = false;
2260 Pair pair = (Pair) $10;
2262 Accessor get_block = null;
2263 Accessor set_block = null;
2265 if (pair.First != null){
2266 get_block = (Accessor) pair.First;
2269 if (pair.Second != null) {
2270 set_block = (Accessor) pair.Second;
2273 Location loc = (Location) $5 ;
2275 // Structure members are Public by default
2276 if ((current_container is Struct) && (current_modifiers == 0))
2277 current_modifiers = Modifiers.PUBLIC;
2279 prop = new Property ((Expression) get_implicit_value_parameter_type,
2280 (string) $2, current_modifiers, get_block, set_block,
2281 current_attributes, loc, set_implicit_value_parameter_name,
2282 get_parameters, set_parameters, (ArrayList) $7);
2284 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
2285 get_implicit_value_parameter_type = null;
2286 set_implicit_value_parameter_type = null;
2287 get_parameters = null;
2288 set_parameters = null;
2289 current_local_parameters = null;
2293 opt_property_parameters
2296 $$ = Parameters.EmptyReadOnlyParameters;
2298 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2304 opt_implement_clause
2309 | IMPLEMENTS implement_clause_list
2315 implement_clause_list
2316 : qualified_identifier
2318 ArrayList impl_list = new ArrayList ();
2319 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
2322 | implement_clause_list COMMA qualified_identifier
2324 ArrayList impl_list = (ArrayList) $1;
2325 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
2331 accessor_declarations
2332 : get_accessor_declaration opt_set_accessor_declaration
2334 $$ = new Pair ($1, $2);
2336 | set_accessor_declaration opt_get_accessor_declaration
2338 $$ = new Pair ($2, $1);
2342 opt_get_accessor_declaration
2343 : /* empty */ { $$ = null; }
2344 | get_accessor_declaration
2347 opt_set_accessor_declaration
2348 : /* empty */ { $$ = null; }
2349 | set_accessor_declaration
2352 get_accessor_declaration
2353 : opt_attributes GET _mark_ logical_end_of_line
2355 push_into_stack((int)Start_block.GET, (Location)$3);
2356 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
2357 Report.Error (30023, (Location)$3, "'WriteOnly' properties cannot have a 'Get' accessor");
2359 current_local_parameters = get_parameters;
2361 lexer.PropertyParsing = false;
2364 // Add local var declaration
2366 ArrayList retval = new ArrayList ();
2367 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, (Location)$3));
2368 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
2373 pop_out_of_stack((int)$7,lexer.Location);
2377 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2378 current_local_parameters = null;
2379 lexer.PropertyParsing = true;
2383 set_accessor_declaration
2384 : opt_attributes SET opt_set_parameter _mark_ logical_end_of_line
2386 push_into_stack((int)Start_block.SET, (Location)$4);
2387 if ((current_modifiers & Modifiers.READONLY) != 0)
2388 Report.Error (30022,
2390 "'ReadOnly' properties cannot have a 'Set' accessor");
2392 Parameter implicit_value_parameter = new Parameter (
2393 set_implicit_value_parameter_type,
2394 set_implicit_value_parameter_name,
2395 Parameter.Modifier.NONE, null);
2397 current_local_parameters = set_parameters;
2398 current_local_parameters.AppendParameter (implicit_value_parameter);
2401 lexer.PropertyParsing = false;
2406 pop_out_of_stack((int)$8,lexer.Location);
2411 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2412 current_local_parameters = null;
2413 lexer.PropertyParsing = true;
2420 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2421 set_implicit_value_parameter_name = "Value";
2423 |OPEN_PARENS CLOSE_PARENS
2425 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2426 set_implicit_value_parameter_name = "Value";
2428 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2430 Parameter.Modifier pm = (Parameter.Modifier)$2;
2431 if ((pm | Parameter.Modifier.VAL) != 0)
2432 Report.Error (31065,
2434 "Set cannot have a paremeter modifier other than 'ByVal'");
2436 set_implicit_value_parameter_type = (Expression) $4;
2438 if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
2439 Report.Error (31064,
2441 "Set value parameter type can not be different from property type");
2444 set_implicit_value_parameter_name = (string) $3;
2446 set_implicit_value_parameter_name = "Value";
2452 variable_declarators end_of_stmt
2454 int mod = (int) current_modifiers;
2456 VariableDeclaration.FixupTypes ((ArrayList) $2);
2457 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2459 if (current_container is Module)
2460 mod = mod | Modifiers.STATIC;
2462 // Structure members are Public by default
2463 if ((current_container is Struct) && (mod == 0))
2464 mod = Modifiers.PUBLIC;
2466 if ((mod & Modifiers.Accessibility) == 0)
2467 mod |= Modifiers.PRIVATE;
2469 foreach (VariableDeclaration var in (ArrayList) $2){
2470 Location l = var.Location;
2471 Field field = new Field (var.type, mod, var.identifier,
2472 var.expression_or_array_initializer,
2473 (Attributes) null, l);
2475 CheckDef (current_container.AddField (field), field.Name, l);
2480 withevents_declaration
2481 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2483 // Module members are static by default, but delegates *can't* be declared static
2484 // so we must fix it, if mbas was the one actually responsible for this
2485 // instead of triggering an error.
2486 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2487 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2489 /* WithEvents Fields must be resolved into properties
2490 with a bit of magic behind the scenes */
2492 VariableDeclaration.FixupTypes ((ArrayList) $3);
2494 foreach (VariableDeclaration var in (ArrayList) $3) {
2495 // 1 - We create a private field
2496 Location l = var.Location;
2498 if ((current_modifiers & Modifiers.STATIC) > 0)
2499 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2501 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2502 var.expression_or_array_initializer,
2503 (Attributes) null, l);
2505 CheckDef (current_container.AddField (field), field.Name, l);
2507 // 2 - Public property
2509 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2510 field, (int) current_modifiers,
2511 (Attributes) current_attributes, l);
2513 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2523 delegate_declaration
2524 : DELEGATE SUB _mark_
2525 identifier OPEN_PARENS
2526 opt_formal_parameter_list
2530 Location l = (Location)$3;
2531 // Module members are static by default, but delegates *can't* be declared static
2532 // so we must fix it, if mbas was the one actually responsible for this
2533 // instead of triggering an error.
2534 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2535 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2537 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2538 TypeManager.system_void_expr,
2539 (int) current_modifiers,
2540 MakeName ((string) $4), (Parameters) $6,
2541 (Attributes) current_attributes, l);
2543 del.Namespace = current_namespace;
2544 CheckDef (current_container.AddDelegate (del), del.Name, l);
2546 | DELEGATE FUNCTION _mark_
2547 identifier OPEN_PARENS
2548 opt_formal_parameter_list
2549 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2551 Location l = (Location)$3;
2553 // Module members are static by default, but delegates *can't* be declared static
2554 // so we must fix it, if mbas was the one actually responsible for this
2555 // instead of triggering an error.
2556 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2557 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2559 Expression ftype = ($8 == null) ? TypeManager.system_object_expr : (Expression) $8;
2561 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2563 ftype, (int) current_modifiers, MakeName ((string) $4),
2564 (Parameters) $6, (Attributes) current_attributes, l);
2566 del.Namespace = current_namespace;
2567 CheckDef (current_container.AddDelegate (del), del.Name, l);
2572 : /* empty */ { $$ = null; }
2573 | HANDLES evt_handler_list { $$ = $2; }
2579 ArrayList list = new ArrayList ();
2583 | evt_handler_list COMMA evt_handler
2585 ((ArrayList) $1).Add ($3);
2592 : qualified_identifier _mark_
2594 $$ = (Expression) DecomposeQI ((string)$1, (Location)$2);
2600 | ME DOT qualified_identifier _mark_
2602 $$ = (Expression) DecomposeQI ((string)$3, (Location)$4);
2604 /*| MYBASE DOT qualified_identifier
2606 // FIXME: this is blatantly wrong and crash-prone
2607 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2611 constructor_declaration
2612 : SUB _mark_ NEW opt_params logical_end_of_line
2614 push_into_stack((int)Start_block.SUB, (Location)$2);
2615 current_local_parameters = (Parameters) $4;
2617 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, (Location)$2);
2622 Constructor c = (Constructor) $1;
2623 c.Block = (Block) end_block();
2625 //To support "Sub New()" add default modifier "public"
2627 if(current_modifiers ==0)
2628 current_modifiers = Modifiers.PUBLIC;
2629 c.ModFlags = (int) current_modifiers;
2630 c.OptAttributes = current_attributes;
2632 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2634 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2635 current_local_parameters = null;
2639 pop_out_of_stack((int)$9, lexer.Location);
2644 opt_formal_parameter_list
2647 $$ = Parameters.EmptyReadOnlyParameters;
2649 | formal_parameter_list
2652 //Parameter p = ((Parameters) $1).FixedParameters[0];
2656 formal_parameter_list
2659 ArrayList pars_list = (ArrayList) $1;
2660 Parameter [] pars = null;
2661 Parameter array_parameter = null;
2662 int non_array_count = pars_list.Count;
2663 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2664 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2665 non_array_count = pars_list.Count - 1;
2667 foreach (Parameter par in pars_list)
2668 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2669 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2670 non_array_count = 0;
2671 array_parameter = null;
2674 if (non_array_count > 0) {
2675 pars = new Parameter [non_array_count];
2676 pars_list.CopyTo (0, pars, 0, non_array_count);
2678 $$ = new Parameters (pars, array_parameter, lexer.Location);
2685 ArrayList pars = new ArrayList ();
2690 | parameters COMMA parameter
2692 ArrayList pars = (ArrayList) $1;
2701 opt_parameter_modifier
2702 identifier _mark_ opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2704 Parameter.Modifier pm = (Parameter.Modifier)$2;
2705 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2708 if (opt_parm && ($8 == null))
2709 Report.Error (30812, (Location)$4, "Optional parameters must have a default value");
2711 if (!opt_parm && ($8 != null))
2712 Report.Error (32024, (Location)$4, "Non-Optional parameters should not have a default value");
2714 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2715 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2716 Report.Error (30667, (Location)$4, "ParamArray parameters must be ByVal");
2719 if ((pm & Parameter.Modifier.REF) !=0)
2720 pm |= Parameter.Modifier.ISBYREF;
2722 TypeExpr tc_expr = TypeManager.TypeToCoreTypeExpr ((Type) $5);
2723 if (tc_expr != null && $7 != null && tc_expr != $7)
2724 Report.Error (30302, (Location)$4, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2726 ptype = (Expression)(($7 == null) ? ((tc_expr == null) ? TypeManager.system_object_expr : tc_expr) : $7);
2728 string t = ptype.ToString ();
2729 if (t.IndexOf('[') >= 0)
2730 Report.Error (31087, (Location)$4, "Array types specified in too many places");
2732 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $6, true, (Location)$4), (Location)$4);
2734 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2735 Report.Error (30050, (Location)$4, "ParamArray parameters must be an array type");
2736 $$ = new Parameter (ptype, (string) $3, pm,
2737 (Attributes) $1, (Expression) $8, opt_parm);
2741 opt_parameter_modifier
2742 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2743 | parameter_modifiers { $$ = $1; }
2747 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2748 | parameter_modifier { $$ = $1; }
2752 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2753 | BYVAL { $$ = Parameter.Modifier.VAL; }
2754 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2755 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2760 | statement_list end_of_stmt
2765 | statement_list end_of_stmt
2771 | declaration_statement
2773 if ($1 != null && (Block) $1 != current_block){
2774 current_block.AddStatement ((Statement) $1);
2775 current_block = (Block) $1;
2778 | embedded_statement
2781 current_block.AddStatement ((Statement) $1);
2784 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2786 AddHandler ((Expression) $2, (Expression) $5);
2788 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2790 RemoveHandler ((Expression) $2, (Expression) $5);
2792 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2794 RaiseEvent ((string) $2, (ArrayList) $3);
2796 /* | array_handling_statement */
2797 /* | empty_statement */
2800 current_block.AddStatement ((Statement) $1);
2805 : END_EOL {$$ = new End (lexer.Location);}
2809 opt_raise_event_args
2810 : /* empty */ { $$ = null; }
2811 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2828 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2830 if (!current_block.AddLabel ((string) $1, labeled,lexer.Location)){
2831 Location l = lexer.Location;
2832 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2834 current_block.AddStatement (labeled);
2838 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2840 if (!current_block.AddLabel ((string) $1, labeled,lexer.Location)){
2841 Location l = lexer.Location;
2842 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2844 current_block.AddStatement (labeled);
2850 : expression_statement
2851 | selection_statement
2852 | iteration_statement
2854 | on_error_statement
2855 | synclock_statement
2857 | array_handling_statement
2864 $$ = new EmptyStatement ();
2870 : ERROR _mark_ expression {
2872 Expression primary_expression = DecomposeQI ("Microsoft.VisualBasic.CompilerServices.ProjectData.CreateProjectError", (Location) $2 );
2874 Argument error_number = new Argument ((Expression) $3, Argument.AType.Expression);
2875 ArrayList args = new ArrayList();
2876 args.Add(error_number);
2878 Invocation CreateProjectErrorInvoke = new Invocation (primary_expression, args, (Location)$2);
2879 $$ = new Throw (CreateProjectErrorInvoke ,(Location)$2);
2884 // : WITH _mark_ expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2885 : WITH _mark_ qualified_identifier end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2887 Expression e = DecomposeQI ((string) $3, (Location)$2);
2888 push_into_stack((int)Start_block.WITH, (Location)$2);
2890 string temp = Convert.ToString(e);
2891 with_hash.Add(temp,e);
2898 pop_out_of_stack((int)$7,lexer.Location);
2899 Block b = end_block();
2907 array_handling_statement
2913 : REDIM _mark_ opt_preserve redim_clauses
2915 ArrayList list = (ArrayList) $4;
2916 ReDim r = new ReDim (list, (bool) $3, (Location)$2);
2922 : /* empty */ { $$ = false; }
2923 | PRESERVE { $$ = true; }
2929 ArrayList clauses = new ArrayList ();
2934 | redim_clauses COMMA redim_clause
2936 ArrayList clauses = (ArrayList) ($1);
2944 : invocation_expression opt_type_spec
2946 Invocation i = (Invocation) $1;
2947 RedimClause rc = new RedimClause (i.expr, i.Arguments, (Expression) $2);
2953 : ERASE erase_clauses
2955 ArrayList list = (ArrayList) $2;
2956 foreach(Expression e in list)
2958 Erase r = new Erase (e, lexer.Location);
2967 ArrayList clauses = new ArrayList ();
2972 | erase_clauses COMMA erase_clause
2974 ArrayList clauses = (ArrayList) ($1);
2982 : primary_expression
2987 | continue_statement
2988 | */return_statement
2999 Block block = current_block;
3001 while( current_block.Parent != null )
3002 current_block = current_block.Parent;
3004 $$ = new Goto (current_block, (string) $2, lexer.Location);
3006 current_block = block;
3007 current_block.SetEndLocation(lexer.Location);
3012 : THROW _mark_ opt_expression
3014 $$ = new Throw ((Expression) $3, (Location)$2);
3021 $$ = new Exit ((ExitType)$2, lexer.Location);
3026 : DO { $$ = ExitType.DO; }
3027 | FOR { $$ = ExitType.FOR; }
3028 | WHILE { $$ = ExitType.WHILE; }
3029 | SELECT { $$ = ExitType.SELECT; }
3030 | SUB { $$ = ExitType.SUB; }
3031 | FUNCTION { $$ = ExitType.FUNCTION; }
3032 | PROPERTY { $$ = ExitType.PROPERTY; }
3033 | TRY { $$ = ExitType.TRY; }
3036 : RETURN opt_expression
3038 $$ = new Return ((Expression) $2, lexer.Location);
3050 : FOR EACH identifier _mark_ opt_type_spec IN
3051 expression end_of_stmt
3053 Location l = (Location)$4;
3054 push_into_stack((int)Start_block.FOR, l);
3055 LocalVariableReference v = null;
3061 VariableDeclaration decl = new VariableDeclaration ((string) $3,
3062 (Expression) $5, null, (Location)$4, null);
3064 vi = current_block.AddVariable (
3065 (Expression) $5, decl.identifier, current_local_parameters, decl.Location);
3068 if (decl.expression_or_array_initializer is Expression)
3069 expr = (Expression) decl.expression_or_array_initializer;
3070 else if (decl.expression_or_array_initializer == null)
3074 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3075 expr = new ArrayCreation ((Expression) $5, "", init, decl.Location);
3078 v = new LocalVariableReference (current_block, decl.identifier, l);
3082 Assign a = new Assign (v, expr, decl.Location);
3083 current_block.AddStatement (new StatementExpression (a, (Location)$4));
3088 vi = current_block.GetVariableInfo ((string) $3);
3091 // Get a reference to this variable.
3092 v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
3096 ArrayList VarDeclarations = new ArrayList ();
3097 VarDeclarations.Add (new VariableDeclaration ("$FOREACH$" + (string) $3, null, l, (string) $3));
3098 ArrayList decl = new ArrayList ();
3099 decl.AddRange (VarDeclarations);
3101 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", l), decl);
3103 Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, l);
3105 if(current_block.Used)
3107 current_block.AddStatement ((Statement) b);
3111 //Mark these variables as Used
3112 vi = current_block.GetVariableInfo ("$FOREACH$" + (string) $3);
3113 //vi.Type = DecomposeQI ((String)$3, l);
3115 v = new LocalVariableReference (current_block,"$FOREACH$" + (string) $3, l, vi, false);
3126 pop_out_of_stack((int)$11,lexer.Location);
3128 _mark_ opt_identifier
3130 string s = $3.ToString();
3133 s1 = $14.ToString();
3134 if (s1 != "" && s != s1)
3136 Report.Error(30070, (Location)$13, "Next Control Variable '"+s1+"' does not match with For Loop control variable '"+s+"'");
3138 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
3139 Block foreach_block = end_block();
3142 f = new Foreach (null, v, (Expression) $7, foreach_block, (Location)$4);
3146 current_block.AddStatement (f);
3152 if (foreach_block.HasLabeledStatement && !foreach_block.HasGotoStatement)
3153 Report.Error(30757, foreach_block.Parent.Parent.EndLocation, "'Goto "+foreach_block.LabelName+"' is not valid because '"+foreach_block.LabelName+"' is inside a 'For' or 'ForEach' statement that does not contain this statement.");
3158 : YIELD expression _mark_
3160 if (!UseExtendedSyntax)
3166 if (iterator_container == null){
3167 Report.Error (204, (Location)$3, "yield statement can only be used within a method, operator or property");
3170 iterator_container.SetYields ();
3171 $$ = new Yield ((Expression) $2, (Location)$3);
3176 if (!UseExtendedSyntax)
3182 if (iterator_container == null){
3183 Report.Error (204, (Location)$3, "yield statement can only be used within a method, operator or property");
3186 iterator_container.SetYields ();
3187 $$ = new YieldBreak ((Location)$3);
3193 : SYNCLOCK _mark_ expression end_of_stmt
3195 push_into_stack((int)Start_block.SYNCLOCK, (Location)$2);
3201 pop_out_of_stack((int)$7,lexer.Location);
3202 $$ = new Lock ((Expression) $3, (Statement) (Block) end_block(), (Location)$2);
3212 : TRY _mark_ end_of_stmt
3214 push_into_stack((int)Start_block.TRY, (Location)$2);
3215 try_top=(Location)$2;
3221 tmp_catch_clauses = (ArrayList) $6;
3226 /*FIXME: Try block without a end try is throwing error at a wrong place*/
3229 _mark_ opt_end_block
3231 pop_out_of_stack((int)$3,lexer.Location);
3233 ArrayList s = new ArrayList ();
3235 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
3242 // Now s contains the list of specific catch clauses
3243 // and g contains the general one.
3244 Block b = end_block();
3246 $$ = new Try ((Block) b, s, g, null, try_top);
3253 tmp_block = end_block();
3260 _mark_ opt_end_block
3262 pop_out_of_stack((int)$8,lexer.Location);
3264 ArrayList s = new ArrayList ();
3265 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
3267 if (catch_list != null){
3268 foreach (Catch cc in catch_list) {
3276 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), try_top);
3282 : /* empty */ { $$ = null; }
3289 ArrayList l = new ArrayList ();
3294 | catch_clauses catch_clause
3296 ArrayList l = (ArrayList) $1;
3304 : /* empty */ { $$ = null; }
3309 : /* empty */ { $$ = null; }
3310 | WHEN boolean_expression
3317 : CATCH opt_catch_args opt_when _mark_ end_of_stmt
3319 Expression type = null;
3323 DictionaryEntry cc = (DictionaryEntry) $2;
3324 type = (Expression) cc.Key;
3325 id = (string) cc.Value;
3328 ArrayList one = new ArrayList ();
3329 Location loc = (Location)$4;
3331 one.Add (new VariableDeclaration (id, type, loc));
3334 current_block = new Block (current_block);
3335 Block b = declare_local_variables (type, one, loc);
3340 opt_statement_list {
3341 Expression type = null;
3343 Block b_catch = current_block;
3346 DictionaryEntry cc = (DictionaryEntry) $2;
3347 type = (Expression) cc.Key;
3348 id = (string) cc.Value;
3352 // FIXME: I can change this for an assignment.
3354 while (current_block != (Block) $1)
3355 current_block = current_block.Parent;
3358 $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, (Location)$4);
3363 : /* empty */ { $$ = null; }
3368 : identifier AS _mark_ type
3370 $$ = new DictionaryEntry ($4, $1);
3372 | error _mark_ AS type
3374 Report.Error(30203, (Location)$2, "Identifier Expected");
3377 | identifier AS _mark_ error
3379 Report.Error(30182, (Location)$3, "Type Expected");
3385 : ON ERROR GOTO MINUS _mark_ LITERAL_INTEGER //ON ERROR GOTO -1
3386 {// This should disables the exception in the current procedure.
3388 Location l = (Location) $5;
3390 if ( $6.ToString() == "1" )
3392 Block method_block = current_block;
3394 while ( !(method_block is MethodBlock) && (method_block.Parent != null) )
3395 method_block = method_block.Parent;
3397 // call Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()
3398 // This call will be created in all kinds of on error goto ( 0, -1, label )
3399 Expression clearerrors = DecomposeQI ("Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError", l);
3400 StatementExpression stex = new StatementExpression (
3401 (ExpressionStatement) new Invocation (clearerrors, null, l),
3403 current_block.AddStatement ((Statement) stex );
3405 String var2 = "$ONERROR$2";//Loc_1 -Int-
3407 // This Assignment must be emited only if the method have a statement like ON ERROR GOTO label.
3408 // $ONERROR$2 = 0 (this Variable is created in a on error goto label stmt)
3409 // This variable will be used in a filter block to disable de exception, if the method have a statement like ON ERROR GOTO label.
3411 Expression var = DecomposeQI (var2, l);
3412 Expression value = new IntLiteral (0);
3414 StatementExpression assign = new StatementExpression( ((ExpressionStatement) new Assign (var, value, l)), l);
3416 if( ((MethodBlock) method_block).onerror != null ) //There is an On_Error Statement created.
3417 current_block.AddStatement ( (Statement) assign );
3418 else // Mark this assignment as pending, if exists an ON ERROR GOTO LABEL statement after this.
3420 if ( ((MethodBlock) method_block).Pending_Assigns == null )
3421 ((MethodBlock) method_block).Pending_Assigns = new ArrayList();
3423 Pending_Assign pa = new Pending_Assign(current_block, (Statement) assign, current_block.statements.Count );
3424 ((MethodBlock) method_block).Pending_Assigns.Add(pa) ;
3429 Report.Error (30203, l, "Identifier expected.");
3434 | ON ERROR GOTO _mark_ label_name
3436 Location l = (Location) $4;
3437 Block old_current = current_block;
3438 Block method_block = current_block;
3440 while ( !(method_block is MethodBlock) && (method_block.Parent != null) )
3441 method_block = method_block.Parent;
3443 // call Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()
3444 // This call will be created in all kinds of on error goto ( 0, -1, label )
3445 Expression clearerrors = DecomposeQI ("Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError", l);
3446 StatementExpression stex = new StatementExpression (
3447 (ExpressionStatement) new Invocation (clearerrors, null, l),
3449 current_block.AddStatement ((Statement) stex );
3451 if ( $5.ToString() == "0") // ON ERROR GOTO 0
3452 {// This should disables error handling in the current procedure.
3454 String var1 = "$ONERROR$1";//Loc_0 -Int- Number of Label.
3456 // This Assignment must be emited only if the method have a statement like ON ERROR GOTO label.
3457 // $ONERROR$1 = 0 (this Variable is created in a on error goto label stmt)
3458 // This variable will be used in a filter block to disable error handling, if the method have a statement like ON ERROR GOTO label.
3460 Expression var = DecomposeQI (var1, l);
3461 Expression value = new IntLiteral (0);
3463 StatementExpression assign = new StatementExpression( ((ExpressionStatement) new Assign (var, value, l)), l);
3465 if( ((MethodBlock) method_block).onerror != null ) //There is an On_Error Statement created.
3466 current_block.AddStatement ( (Statement) assign );
3467 else // Mark this assignment as pending, if exists an ON ERROR GOTO LABEL statement after this.
3469 if ( ((MethodBlock) method_block).Pending_Assigns == null )
3470 ((MethodBlock) method_block).Pending_Assigns = new ArrayList();
3472 Pending_Assign pa = new Pending_Assign(current_block, (Statement) assign, current_block.statements.Count );
3473 ((MethodBlock) method_block).Pending_Assigns.Add(pa) ;
3476 else // ON ERROR GOTO LABEL
3477 {// This should Enables the error-handling routine that starts at the line specified in the required line argument.
3479 String var1 = "$ONERROR$1";//Loc_0 -Int-Number of Label.
3480 String var2 = "$ONERROR$2";//Loc_1 -Int-
3481 String var3 = "$ONERROR$3";//Loc_2 -System.Exception- Exception Object.
3483 VariableInfo vi = current_block.GetVariableInfo (var1);
3486 { // First On Error Statement
3487 // 1) Declare local variables to handle goto.
3488 // 1.1) Dim $ONERROR$01 (Variable Generated because on error stmt)
3489 // 1.2) Dim $ONERROR$02 (Variable Generated because on error stmt)
3490 // 1.3) Dim $ONERROR$03 (Variable Generated because on error stmt)
3491 // 2) Declare a Parent Block of Method_Block to handle the method_block stmts within a try stmt.
3492 // 3) Declere OnError stmt and mark its block as Parent of method_block.
3493 // 4) Assign the pending assignments if they exist.
3495 Block block = new Block( method_block.Parent, null,
3496 lexer.Location, Location.Null);
3498 //Cleaning the variables created in a top block(these variables already were created in method_block)
3499 block.Variables.Clear();
3501 // Dim $ONERROR$01 As Integer (Variable Genearted because on error stmt)
3502 // Dim $ONERROR$02 As Integer (Variable Genearted because on error stmt)
3503 // Dim $ONERROR$03 As System.Exception (Variable Genearted because on error stmt)
3504 ArrayList VarDeclarations = new ArrayList ();
3505 VarDeclarations.Add (new VariableDeclaration (var1, TypeManager.system_int32_expr, null, l, null));
3506 VarDeclarations.Add (new VariableDeclaration (var2, TypeManager.system_int32_expr, null, l, null));
3507 VarDeclarations.Add (new VariableDeclaration (var3, DecomposeQI("System.Exception", l), null, l, null));
3508 ArrayList decl = new ArrayList ();
3509 decl.AddRange (VarDeclarations);
3511 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", l), decl);
3512 current_block = block;
3513 declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, l);
3515 //Mark these variables as Used
3516 vi = current_block.GetVariableInfo (var1);
3518 vi = current_block.GetVariableInfo (var2);
3520 vi = current_block.GetVariableInfo (var3);
3523 current_block = old_current;
3525 Statement stmt = new On_Error( method_block, l );
3526 block.AddStatement(stmt);
3527 block.AddChild(method_block);
3528 // This will make on_error block as Parent of method_block
3529 // This is needed because an implicit insertion of a try outside of method_block statements.
3530 ((MethodBlock) method_block).onerror = block;
3531 method_block.Parent = block;
3533 //This adds the pendinding assignments of any on error goto 0 or -1 before the first ON ERROR GOTO LABEL statement.
3534 if ( ((MethodBlock) method_block).Pending_Assigns != null )
3536 foreach ( Pending_Assign pa in ((MethodBlock) method_block).Pending_Assigns )
3538 ((MethodBlock) method_block).Pending_Assigns.Clear();
3542 int targetnumber = 0;
3544 foreach ( Statement s in ((MethodBlock) method_block).onerror.statements )
3546 if ( s is On_Error )
3548 targetnumber = ((On_Error) s).AddTarget( (string) $5 );
3553 // $ONERROR$1 = targetnumber + 1 (this Variable already was created in a on error stmt)
3554 // This variable will be used in a switch to indicate de used label
3555 // and to indicate the exit in a comparison with false.
3557 Expression var = DecomposeQI (var1, l);
3558 Expression value = new IntLiteral (targetnumber + 1);
3560 StatementExpression assign = new StatementExpression( ((ExpressionStatement) new Assign (var, value, l)), l);
3561 current_block.AddStatement ( (Statement) assign );
3566 | ON ERROR _mark_ RESUME NEXT
3567 { //Control goes to the statement immediately following the statement
3568 //where the error occurred and execution continues from that point.
3574 : DO _mark_ opt_do_construct end_of_stmt
3576 push_into_stack((int)Start_block.DO, (Location)$2);
3582 pop_out_of_stack((int)$7,lexer.Location);
3584 _mark_ opt_do_construct
3586 Expression t_before = (Expression) $3;
3587 Expression t_after = (Expression) $10;
3590 if ((t_before != null) && (t_after != null))
3591 Report.Error (30238, (Location)$9, "'Loop' cannot have a condition if matching 'Do' has one.");
3593 if ((t_before == null) && (t_after == null))
3594 t = new BoolLiteral (true);
3596 t = (t_before != null) ? t_before : t_after;
3598 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
3600 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
3601 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
3602 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, (Location)$2);
3604 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, (Location)$2);
3609 : /* empty */ { $$ = null; }
3610 | while_or_until boolean_expression
3612 do_type = (DoOptions)$1;
3613 $$ = (Expression) $2;
3618 : WHILE { $$ = DoOptions.WHILE; }
3619 | UNTIL { $$ = DoOptions.UNTIL; }
3625 push_into_stack((int)Start_block.WHILE, lexer.Location);
3627 oob_stack.Push (lexer.Location);
3629 boolean_expression end_of_stmt
3633 Location l = (Location) oob_stack.Pop ();
3634 pop_out_of_stack((int)$6,lexer.Location);
3635 Block b = end_block();
3636 Expression e = (Expression) $3;
3637 $$ = new While ((Expression) e, (Statement) b, l);
3642 : FOR _mark_ identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
3645 push_into_stack((int)Start_block.FOR, (Location)$2);
3649 ArrayList VarDeclaration = new ArrayList ();
3650 VarDeclaration.Add (new VariableDeclaration ((string) $3,
3651 (Expression) $4, null, (Location)$2, null));
3653 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), VarDeclaration);
3654 Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location)$2);
3662 pop_out_of_stack((int)$13,lexer.Location);
3664 _mark_ opt_identifier
3666 string s = $3.ToString();
3669 s1 = $16.ToString();
3670 if (s1 != "" && s != s1) {
3671 Report.Error(30070, (Location)$15, "Next Control Variable '"+s1+"' does not match with For Loop control variable '"+s+"'");
3674 Block inner_statement = end_block();
3675 if (!inner_statement.HasGotoStatement && inner_statement.HasLabeledStatement)
3676 Report.Error(30757, inner_statement.Parent.EndLocation, "'Goto "+inner_statement.LabelName+"' is not valid because '"+inner_statement.LabelName+"' is inside a 'For' or 'ForEach' statement that does not contain this statement.");
3677 Location l = (Location)$2;
3678 Expression for_var = (Expression) DecomposeQI ((string)$3, l);
3680 For f = new For (for_var, (Expression) $6, (Expression) $8, (Expression) $9, inner_statement, l);
3683 current_block.AddStatement (f);
3692 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
3693 | STEP expression { $$ = $2; }
3702 : if_statement_open opt_then end_of_stmt opt_statement_list
3704 push_into_stack((int)Start_block.IF, (Location)$1);
3710 | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
3714 Location l = (Location) oob_stack.Pop ();
3715 tmp_expr = (Expression)expr_stack.Pop();
3716 $$ = new If ((Expression) tmp_expr, end_block(), l);
3720 Location l = (Location) oob_stack.Pop ();
3721 tmp_expr = (Expression)expr_stack.Pop();
3722 tmp_block = (Block) tmp_blocks.Pop ();
3723 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3726 | if_statement_open THEN else_pre_embedded_statement
3728 Location l = (Location) oob_stack.Pop ();
3729 tmp_expr = (Expression)expr_stack.Pop();
3730 tmp_block = (Block) tmp_blocks.Pop ();
3731 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3735 pre_embedded_statement
3736 : embedded_statement
3739 current_block.AddStatement ((Statement) $1);
3743 opt_else_pre_embedded_statement
3745 | else_pre_embedded_statement
3748 else_pre_embedded_statement
3751 Block bl = end_block();
3752 tmp_blocks.Push(bl);
3756 | ELSE embedded_statement
3758 Block bl = end_block();
3759 tmp_blocks.Push(bl);
3763 current_block.AddStatement ((Statement) $2);
3767 /*FIXME:if without end if not working. Error line shown is nor correct*/
3771 oob_stack.Push (lexer.Location);
3776 tmp_expr = (Expression) $4;
3777 expr_stack.Push(tmp_expr);
3791 Location l = (Location) oob_stack.Pop ();
3792 pop_out_of_stack((int)$1,lexer.Location);
3793 Expression expr = (Expression)expr_stack.Pop();
3794 $$ = new If ((Expression) expr, (Statement) end_block(), l);
3799 Block bl = end_block();
3800 tmp_blocks.Push(bl);
3806 Location l = (Location) oob_stack.Pop ();
3807 pop_out_of_stack((int)$5,lexer.Location);
3808 tmp_expr = (Expression)expr_stack.Pop();
3809 tmp_block = (Block) tmp_blocks.Pop();
3810 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
3813 opt_elseif boolean_expression opt_then
3815 tmp_expr = (Expression) $2;
3816 expr_stack.Push(tmp_expr);
3817 tmp_block = end_block();
3818 tmp_blocks.Push(tmp_block);
3821 end_of_stmt opt_statement_list
3822 else_if_statement_rest
3824 Statement stmt = (Statement) statement_stack.Pop();
3825 Block bl = (Block) tmp_blocks.Pop();
3826 Expression expr = (Expression)expr_stack.Pop();
3827 Location l = (Location) oob_stack.Pop ();
3828 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3833 else_if_statement_rest
3837 Block bl = end_block();
3838 tmp_blocks.Push(bl);
3844 Location l = (Location) oob_stack.Pop ();
3845 pop_out_of_stack((int)$5,lexer.Location);
3847 Expression expr = (Expression)expr_stack.Pop();
3848 Block bl = (Block)tmp_blocks.Pop();
3849 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3850 statement_stack.Push(stmt);
3853 opt_elseif boolean_expression opt_then
3855 expr_stack.Push((Expression) $2);
3856 Block bl = end_block();
3857 tmp_blocks.Push(bl);
3860 end_of_stmt opt_statement_list
3861 else_if_statement_rest
3863 Location l = (Location) oob_stack.Pop ();
3865 Statement tmp_stmt = (Statement)statement_stack.Pop();
3866 Block bl = (Block) tmp_blocks.Pop();
3867 Expression expr = (Expression)expr_stack.Pop();
3868 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3869 statement_stack.Push(stmt);
3874 Location l = (Location) oob_stack.Pop ();
3875 pop_out_of_stack((int)$1,lexer.Location);
3877 Expression expr = (Expression)expr_stack.Pop();
3878 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3879 statement_stack.Push(stmt);
3883 /*FIXME:Select without an expression is showing a parser error instead of a expression missing error*/
3886 _mark_ opt_case expression end_of_stmt
3888 push_into_stack((int)Start_block.SELECT, (Location)$2);
3889 oob_stack.Push (lexer.Location);
3890 switch_stack.Push (current_block);
3895 pop_out_of_stack((int)$8,lexer.Location);
3896 current_block = (Block) switch_stack.Pop ();
3897 $$ = new Switch ((Expression) $4, (ArrayList) $7, (Location) oob_stack.Pop ());
3902 : /* empty */ { $$ = null; }
3903 | case_sections { $$ = $1; }
3907 : case_sections case_section
3909 ArrayList sections = (ArrayList) $1;
3916 ArrayList sections = new ArrayList ();
3930 : CASE case_clauses ends
3936 //Block topmost = current_block;
3937 Block topmost = end_block();
3939 while (topmost.Implicit)
3940 topmost = topmost.Parent;
3942 // FIXME: This is a horrible hack which MUST go
3943 topmost.statements.Add (new Break (lexer.Location));
3944 $$ = new SwitchSection ((ArrayList) $2, topmost);
3947 /* FIXME: we should somehow flag an error
3948 (BC30321 'Case' cannot follow a 'Case Else'
3949 in the same 'Select' statement.)
3950 if Case Else is not the last of the Case clauses
3957 //Block topmost = current_block;
3958 Block topmost = end_block();
3960 while (topmost.Implicit)
3961 topmost = topmost.Parent;
3963 // FIXME: This is a horrible hack which MUST go
3964 topmost.statements.Add (new Break (lexer.Location));
3966 ArrayList a = new ArrayList();
3967 a.Add (new SwitchLabel (null, SwitchLabel.LabelType.Else, Binary.Operator.TOP, lexer.Location));
3968 $$ = new SwitchSection ((ArrayList) a, topmost);
3975 ArrayList labels = new ArrayList ();
3979 | case_clauses COMMA case_clause
3981 ArrayList labels = (ArrayList) ($1);
3989 : opt_is comparison_operator expression
3991 $$ = new SwitchLabel ((Expression) $3, SwitchLabel.LabelType.Operator, (Binary.Operator) $2, lexer.Location);
3995 $$ = new SwitchLabel ((Expression) $1, SwitchLabel.LabelType.Label, Binary.Operator.TOP, lexer.Location);
3997 | expression TO expression
3999 $$ = new SwitchLabel ((Expression) $1, (Expression) $3, SwitchLabel.LabelType.Range,
4000 Binary.Operator.TOP, lexer.Location);
4013 $$ = Binary.Operator.LessThan;
4017 $$ = Binary.Operator.GreaterThan;
4021 $$ = Binary.Operator.GreaterThanOrEqual;
4025 $$ = Binary.Operator.LessThanOrEqual;
4029 $$ = Binary.Operator.Inequality;
4033 $$ = Binary.Operator.Equality;
4042 expression_statement
4043 : statement_expression
4050 statement_expression
4051 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
4052 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
4053 | qualified_identifier {
4054 Expression e = Parser.DecomposeQI ((string)$1, lexer.Location);
4055 e = new Invocation (e, new ArrayList (), lexer.Location);
4056 $$ = new StatementExpression ((ExpressionStatement) e, lexer.Location);
4058 | assignment_expression
4061 $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);
4067 object_creation_expression
4068 : NEW type OPEN_PARENS _mark_ opt_argument_list CLOSE_PARENS
4070 $$ = new New ((Expression) $2, (ArrayList) $5, (Location)$4);
4074 $$ = new New ((Expression) $2, new ArrayList(), (Location)$3);
4078 array_creation_expression
4079 : object_creation_expression opt_rank_specifiers _mark_ array_initializer
4082 ArrayList dims = new ArrayList();
4084 if (n.Arguments != null) {
4085 foreach (Argument a in n.Arguments) {
4090 Expression atype = n.RequestedType;
4093 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, (Location)$3), (Location)$3);
4095 ArrayList init = (ArrayList) $4;
4096 if (init.Count == 0)
4099 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
4100 VariableDeclaration.VBFixIndexList (ref dims);
4101 $$ = new ArrayCreation (atype, dims, "", init, (Location)$3);
4105 string rank = VariableDeclaration.BuildRank (dims);
4106 $$ = new ArrayCreation (atype, rank, (ArrayList) $4, (Location)$3);
4108 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
4113 : object_creation_expression
4114 | array_creation_expression
4117 declaration_statement
4118 : _mark_ local_variable_declaration
4121 DictionaryEntry de = (DictionaryEntry) $2;
4122 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location)$1);
4125 | local_constant_declaration
4128 DictionaryEntry de = (DictionaryEntry) $1;
4130 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
4133 | STATIC _mark_ opt_dim_stmt variable_declarators
4135 //Static variables may not be declared in structures.
4136 if (($4 != null) && !(current_container is Struct)) {
4137 Block block = current_block ;
4139 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), $4);
4141 int mod = (int) current_modifiers;
4143 VariableDeclaration.FixupTypes ((ArrayList) de.Value);
4144 VariableDeclaration.FixupArrayTypes ((ArrayList) de.Value);
4146 if (current_container is Module)
4147 mod = mod | Modifiers.STATIC;
4149 if ((mod & Modifiers.Accessibility) == 0)
4150 mod |= Modifiers.PRIVATE;
4152 foreach (VariableDeclaration var in (ArrayList) de.Value){
4153 Location l = var.Location;
4154 Field field = new Field (var.type, mod, var.identifier,
4155 var.expression_or_array_initializer,
4158 while ( !(block is MethodBlock) && (block.Parent != null) )
4159 block = block.Parent;
4161 field.Name = @"$STATIC$" + ((MethodBlock) block).MethodName + @"$" + ((Location) $2).Row + @"$" + field.Name;
4162 CheckDef (current_container.AddField (field), field.Name, l);
4163 var.Alias = field.Name;
4165 //To do initialization only once.
4166 if( var.expression_or_array_initializer != null ) { //Like: Static a as Integer = 10
4168 //Declare StaticLocalInitFlag Field.
4169 Expression init = DecomposeQI ("Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag", l);
4170 init = (Expression) new New (init, null, l);
4172 Field field_init = new Field ( ((New)init).RequestedType , mod, var.identifier, init, null, l);
4173 field_init.Name = field.Name+@"$Init";
4174 CheckDef (current_container.AddField (field_init), field_init.Name, l);
4176 //Declare If statement, to verify if the static variable was initialized.
4177 //If( ((Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag) localStaticvar).State != 1)
4178 Expression left = DecomposeQI (field_init.Name + ".State", l);
4179 Expression right = (Expression) new IntLiteral (1);
4180 Expression boolean_expression = new Binary (Binary.Operator.Inequality, left, right, l);
4181 boolean_expression = SetValueRequiredFlag (boolean_expression);
4185 left = DecomposeQI (field_init.Name, l);
4186 ArrayList list = new ArrayList ();
4187 list.Add ( new Argument (left, Argument.AType.Expression) );
4189 left = DecomposeQI ("System.Threading.Monitor.Enter", l);
4190 StatementExpression stex = new StatementExpression (
4191 (ExpressionStatement)new Invocation (left, list, l),
4193 current_block.AddStatement ((Statement) stex );
4199 //IF ( localStaticvar$Init.State == 0 )
4200 left = DecomposeQI (field_init.Name + ".State", l);
4201 right = (Expression) new IntLiteral (0);
4202 Expression boolean_expression2 = new Binary (Binary.Operator.Equality, left, right, l);
4203 boolean_expression2 = SetValueRequiredFlag (boolean_expression2);
4206 // localStaticvar$Init.State = 1
4207 left = DecomposeQI (field_init.Name + ".State", l);
4208 right = (Expression) new IntLiteral (2);
4209 ExpressionStatement assign = (ExpressionStatement) new Assign (left, right, l);
4210 stex = new StatementExpression (assign, l);
4211 current_block.AddStatement ((Statement) stex );
4213 // localStaticvar = initvalue
4214 left = DecomposeQI (field.Name, l);
4215 assign = (ExpressionStatement) new Assign (left, (Expression) var.expression_or_array_initializer , l);
4216 stex = new StatementExpression (assign, l);
4217 current_block.AddStatement ((Statement) stex );
4219 var.expression_or_array_initializer = null;
4222 tmp_block = end_block();
4225 //IF ( localStaticvar$Init.State == 2 )
4226 left = DecomposeQI (field_init.Name + ".State", l);
4227 right = (Expression) new IntLiteral (2);
4228 Expression boolean_expression3 = new Binary (Binary.Operator.Equality, left, right, l);
4229 boolean_expression3 = SetValueRequiredFlag (boolean_expression3);
4232 //THROW New Microsoft.VisualBasic.CompilerServices.IncompleteInitialization()
4233 left = DecomposeQI ("Microsoft.VisualBasic.CompilerServices.IncompleteInitialization", l);
4234 left = (Expression) new New (left, null, l);
4235 Statement stmt = (Statement) new Throw (left, l);
4236 current_block.AddStatement (stmt);
4239 stmt = (Statement) new If (boolean_expression3, (Statement) end_block(), l);
4240 current_block.AddStatement (stmt);
4243 stmt = (Statement) new If (boolean_expression2, (Statement) tmp_block, (Statement) end_block(), l);
4244 current_block.AddStatement (stmt);
4247 tmp_block = end_block();
4251 // ((Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag) localStaticvar).State = 1
4252 left = DecomposeQI (field_init.Name + ".State", l);
4253 right = (Expression) new IntLiteral (1);
4254 assign = (ExpressionStatement) new Assign (left, right, l);
4255 stex = new StatementExpression (assign, l);
4256 current_block.AddStatement ((Statement) stex );
4258 // System.Threading.Monitor.Exit( field$Init )
4259 left = DecomposeQI (field_init.Name, l);
4261 list.Add ( new Argument (left, Argument.AType.Expression) );
4262 left = DecomposeQI ("System.Threading.Monitor.Exit", l);
4263 stex = new StatementExpression (
4264 (ExpressionStatement)new Invocation (left, list, l),
4266 current_block.AddStatement ((Statement) stex );
4269 stmt = (Statement) new Try ((Block) tmp_block, new ArrayList(), null, (Block) end_block(), l);
4270 current_block.AddStatement (stmt);
4273 stmt = (Statement) new If (boolean_expression, (Statement) end_block(), l);
4274 current_block.AddStatement (stmt);
4278 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location) $2);
4281 if (current_container is Struct)
4282 Report.Error ( 31400, (Location)$2,"Local variables within structures methods can't be declared 'Static'.");
4288 local_variable_declaration
4289 : DIM _mark_ variable_declarators
4291 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), $3);
4296 local_constant_declaration
4297 : CONST constant_declarators
4300 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
4306 constant_declarators
4307 : constant_declarator
4309 ArrayList decl = new ArrayList ();
4315 | constant_declarators COMMA constant_declarator
4317 ArrayList decls = (ArrayList) $1;
4326 : _mark_ variable_name opt_type_decl opt_variable_initializer
4328 VarName vname = (VarName) $2;
4329 string varname = (string) vname.Name;
4330 current_rank_specifiers = (ArrayList) vname.Rank;
4331 object varinit = $4;
4333 if (varinit == null)
4335 30438, (Location)$1, "Constant should have a value"
4338 if (vname.Type != null && $3 != null)
4340 30302, (Location)$1,
4341 "Type character cannot be used with explicit type declaration" );
4343 Expression vartype = ($3 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $3;
4345 if (current_rank_specifiers != null)
4347 Report.Error (30424, (Location)$1, "Constant doesn't support array");
4351 $$ = new VariableDeclaration (varname, vartype, varinit, (Location)$1, null);
4355 variable_declarators
4356 : variable_declarator
4358 ArrayList decl = new ArrayList ();
4359 decl.AddRange ((ArrayList) $1);
4362 | variable_declarators COMMA variable_declarator
4364 ArrayList decls = (ArrayList) $1;
4365 decls.AddRange ((ArrayList) $3);
4371 : _mark_ variable_names opt_type_decl opt_variable_initializer
4373 ArrayList names = (ArrayList) $2;
4374 object varinit = $4;
4375 ArrayList VarDeclarations = new ArrayList();
4377 ArrayList a_dims = null;
4379 if ((names.Count > 1) && (varinit != null))
4381 30671, (Location)$1,
4382 "Multiple variables with single type can not have " +
4383 "a explicit initialization" );
4386 foreach (VarName vname in names)
4388 string varname = (string) vname.Name;
4389 current_rank_specifiers = (ArrayList) vname.Rank;
4393 if (VariableDeclaration.IsArrayDecl (this) && $3.ToString().IndexOf('[') >= 0)
4395 31087, (Location)$1,
4396 "Array modifiers can not specified on both a variable and its type" );
4398 if(vname.Type != null && $3 != null)
4400 30302, (Location)$1,
4401 "Type character cannot be used with explicit type declaration" );
4403 // Some checking is required for particularly weird declarations
4404 // like Dim a As Integer(,)
4406 vartype = (Expression) ((Pair) $3).First;
4408 /*if ($4 != null && $4 is ArrayList)
4409 Report.Error (205, "End of statement expected.");*/
4411 ArrayList args = (ArrayList) ((Pair) $3).Second;
4412 if (current_rank_specifiers != null)
4413 Report.Error (31087, (Location)$1,
4414 "Array types specified in too many places");
4416 if (VariableDeclaration.IndexesSpecifiedInRank (args))
4417 Report.Error (30638, (Location)$1,"Array bounds cannot appear in type specifiers.");
4419 current_rank_specifiers = new ArrayList ();
4420 current_rank_specifiers.Add (args);
4423 vartype = ($3 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $3;
4425 // if the variable is an array with explicit bound
4426 // and having explicit initialization throw exception
4427 if (current_rank_specifiers != null && varinit != null)
4429 bool broken = false;
4430 foreach (ArrayList exprs in current_rank_specifiers)
4432 foreach (Expression expr in exprs)
4434 if (!((Expression)expr is EmptyExpression ))
4437 30672, (Location)$1,
4438 "Array declared with explicit bound " +
4439 " can not have explicit initialization");
4450 Check for a declaration like Dim a(2) or Dim a(2,3)
4451 If this is the case, we must generate an ArrayCreationExpression
4452 and, in case, add the initializer after the array has been created.
4454 if (VariableDeclaration.IsArrayDecl (this)) {
4455 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
4456 a_dims = (ArrayList) current_rank_specifiers;
4457 VariableDeclaration.VBFixIndexLists (ref a_dims);
4458 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, (Location)$1);
4460 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, (Location)$1), (Location)$1);
4463 if (vartype is New) {
4464 if (varinit != null) {
4465 Report.Error (30205, (Location)$1, "End of statement expected");
4471 vartype = ((New)vartype).RequestedType;
4474 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, (Location)$1, null));
4476 $$ = VarDeclarations;
4483 ArrayList list = new ArrayList ();
4487 | variable_names COMMA variable_name
4489 ArrayList list = (ArrayList) $1;
4496 : identifier opt_type_character opt_array_name_modifier
4498 $$ = new VarName ($1, TypeManager.TypeToCoreTypeExpr ((Type) $2), $3);
4510 $$ = (Expression) $2;
4513 Report.Error(30182, lexer.Location, "Identifier Expected");
4521 | AS type _mark_ rank_specifiers
4525 Report.Error(30182, (Location)$3, "Identifier Expected");
4529 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$4, true, (Location)$3), (Location)$3);
4534 : opt_type_with_ranks
4540 New n = new New ((Expression)$3, null, lexer.Location);
4541 $$ = (Expression) n;
4543 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
4545 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
4546 $$ = (Expression) n;
4548 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
4550 ArrayList args = new ArrayList();
4551 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
4554 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
4555 $$ = (Expression) n;
4559 opt_array_name_modifier
4560 : /* empty */ { $$ = null; }
4561 | array_type_modifier { $$ = $1; }
4565 : rank_specifiers { $$ = $1; }
4568 opt_variable_initializer
4569 : /* empty */ { $$ = null; }
4570 | ASSIGN variable_initializer { $$ = $2; }
4573 variable_initializer
4576 Expression etmp = (Expression) $1;
4577 etmp = SetValueRequiredFlag (etmp);
4588 : OPEN_BRACE CLOSE_BRACE
4590 ArrayList list = new ArrayList ();
4593 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
4595 $$ = (ArrayList) $2;
4599 variable_initializer_list
4600 : variable_initializer
4602 ArrayList list = new ArrayList ();
4606 | variable_initializer_list COMMA variable_initializer
4608 ArrayList list = (ArrayList) $1;
4629 ArrayList rs = new ArrayList();
4633 | rank_specifiers rank_specifier
4635 ArrayList rs = (ArrayList) $1;
4642 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
4651 ArrayList ds = new ArrayList();
4652 ds.Add (new EmptyExpression());
4657 ArrayList ds = new ArrayList();
4658 ds.Add ((Expression) $1);
4661 | opt_dim_specifiers COMMA expression
4663 ArrayList ds = (ArrayList) $1;
4664 ds.Add ((Expression) $3);
4667 | opt_dim_specifiers COMMA
4669 ArrayList ds = (ArrayList) $1;
4670 ds.Add (new EmptyExpression());
4677 | literal type_character
4681 Constant literal = (Constant) $1;
4682 Type literal_type = literal.GetValue ().GetType ();
4683 Type typechar = (Type) $2;
4685 if (literal_type == typechar)
4686 //no conversion required
4689 if (literal_type == typeof (bool)) {
4690 Report.Error (30687, lexer.Location, "Keyword cannot have a type character.");
4694 if (literal_type == typeof (DateTime) || literal_type == typeof (char) || literal_type == typeof (string) || typechar == typeof (string) ) {
4695 Report.Error (30037, lexer.Location, "Character is not valid");
4699 if (literal_type == typeof (int) || literal_type == typeof (short) || literal_type == typeof (long)) {
4701 $$ = ConvertLiteral (literal, typechar);
4703 if (literal_type == typeof (float) || literal_type == typeof (double) || literal_type == typeof (decimal)) {
4705 if (typechar == typeof (int))
4706 Report.Error (30037, lexer.Location, "Character is not valid.");
4708 if (typechar == typeof (long))
4709 Report.Error (30201, lexer.Location, "Expression expected.");
4712 $$ = ConvertLiteral (literal, typechar);
4713 }/* FIXME: throw error here? */
4715 | parenthesized_expression
4718 | qualified_identifier opt_type_character _mark_
4720 Expression left = DecomposeQI ((string) $1, (Location) $3);
4722 $$ = new DecoratedIdentifier (left, (Type) $2);
4726 | get_type_expression
4728 | invocation_expression
4733 { Report.Error(30201,(Location)$2,"Expression expected"); $$ = (Expression)null;}
4740 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
4741 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
4742 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
4743 | NOTHING { $$ = NullLiteral.Null; }
4747 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
4748 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
4749 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
4754 object v = lexer.Value;
4757 $$ = new IntLiteral ((Int32)v);
4758 else if (v is short)
4759 $$ = new ShortLiteral ((Int16)v);
4761 $$ = new LongLiteral ((Int64)v);
4763 Console.WriteLine ("Unexpected result from scanner");
4769 : TRUE { $$ = new BoolLiteral (true); }
4770 | FALSE { $$ = new BoolLiteral (false); }
4773 parenthesized_expression
4774 : OPEN_PARENS expression CLOSE_PARENS
4779 : primary_expression DOT _mark_ identifier
4782 string id_name = (string)$4;
4783 if (id_name.ToUpper() == "NEW")
4785 $$ = new MemberAccess ((Expression) $1, id_name, (Location)$3);
4789 if (with_stack.Count > 0) {
4790 Expression e = (Expression) with_stack.Peek();
4791 $$ = new MemberAccess (e, (string) $4, (Location)$3);
4799 /* | primary_expression DOT _mark_ NEW
4801 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", (Location)$3);
4803 | predefined_type DOT _mark_ identifier
4806 $$ = new MemberAccess ((Expression) $1, (string) $4, (Location)$3);
4809 if (with_stack.Count > 0) {
4810 Expression e = (Expression) with_stack.Peek();
4811 $$ = new MemberAccess (e, (string) $4, (Location)$3);
4825 invocation_expression
4826 // To support Mid$()
4827 : primary_expression opt_dolar_sign OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
4830 Location l = (Location)$5;
4831 Report.Error (1, l, "THIS IS CRAZY");
4833 $$ = new Invocation ((Expression) $1, (ArrayList) $4, (Location)$5);
4834 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($4 != null) ? ((ArrayList) $4).Count : 0);
4836 | CALL primary_expression OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
4839 Location l = (Location)$5;
4840 Report.Error (1, l, "THIS IS CRAZY");
4842 $$ = new Invocation ((Expression) $2, (ArrayList) $3, (Location)$5);
4843 // Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
4845 | primary_expression EXCLAMATION _mark_ identifier // FIXME : This should be identifier-or-keyword
4848 Location l = (Location)$3;
4849 Report.Error (1, l, "THIS IS CRAZY");
4852 ArrayList args = new ArrayList ();
4853 Expression etmp = new StringLiteral ((string)$4);
4855 args.Add (new Argument (etmp, Argument.AType.Expression));
4856 $$ = new Invocation ((Expression) $1, args, (Location)$3);
4866 : MYBASE DOT IDENTIFIER
4868 string id_name = (string) $3;
4869 if (id_name.ToUpper() == "NEW")
4871 $$ = new BaseAccess (id_name, lexer.Location);
4875 $$ = new BaseAccess ("New", lexer.Location);
4883 The 'argument' rule returns an 'empty' argument
4884 of type NoArg (used for default arguments in invocations)
4885 if no arguments are actually passed.
4887 If there is only one argument and it is o type NoArg,
4888 we return a null (empty) list
4890 ArrayList args = (ArrayList) $1;
4891 if (args.Count == 1 &&
4892 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
4902 ArrayList list = new ArrayList ();
4906 | argument_list COMMA argument
4908 ArrayList list = (ArrayList) $1;
4917 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
4919 | BYREF variable_reference
4921 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
4925 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
4927 | ADDRESSOF expression
4929 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
4931 | identifier ATTR_ASSIGN expression
4933 $$ = new Argument ((string) $1, (Expression) $3, Argument.AType.Expression);
4938 : expression {/* note ("section 5.4"); */ $$ = $1; }
4943 : conditional_xor_expression { $$ = $1; }
4944 /*| assignment_expression*/
4955 $$ = new This (current_block, lexer.Location);
4959 $$ = new This (This.TypeOfAccess.MyClass, current_block, lexer.Location);
4964 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
4968 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
4970 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
4972 | cast_operator OPEN_PARENS expression CLOSE_PARENS
4974 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
4979 : CBOOL { $$ = TypeManager.system_boolean_expr; }
4980 | CBYTE { $$ = TypeManager.system_byte_expr; }
4981 | CCHAR { $$ = TypeManager.system_char_expr; }
4982 | CDATE { $$ = TypeManager.system_date_expr; }
4983 | CDBL { $$ = TypeManager.system_double_expr; }
4984 | CDEC { $$ = TypeManager.system_decimal_expr; }
4985 | CINT { $$ = TypeManager.system_int32_expr; }
4986 | CLNG { $$ = TypeManager.system_int64_expr; }
4987 | COBJ { $$ = TypeManager.system_object_expr; }
4988 | CSHORT { $$ = TypeManager.system_int16_expr; }
4989 | CSNG { $$ = TypeManager.system_single_expr; }
4990 | CSTR { $$ = TypeManager.system_string_expr; }
4994 : GETTYPE OPEN_PARENS _mark_ type CLOSE_PARENS
4996 $$ = new TypeOf ((Expression) $4, (Location)$3);
5000 exponentiation_expression
5001 : prefixed_unary_expression
5002 | exponentiation_expression OP_EXP _mark_ prefixed_unary_expression
5004 $$ = new Binary (Binary.Operator.Exponentiation,
5005 (Expression) $1, (Expression) $4, (Location)$3);
5009 prefixed_unary_expression
5010 : primary_expression
5011 | PLUS _mark_ prefixed_unary_expression
5013 //FIXME: Is this rule correctly defined ?
5014 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $3, (Location)$2);
5016 | MINUS _mark_ prefixed_unary_expression
5018 //FIXME: Is this rule correctly defined ?
5019 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $3, (Location)$2);
5023 multiplicative_expression
5024 : exponentiation_expression
5025 | multiplicative_expression STAR _mark_ prefixed_unary_expression
5027 $$ = new Binary (Binary.Operator.Multiply,
5028 (Expression) $1, (Expression) $4, (Location)$3);
5030 | multiplicative_expression DIV _mark_ prefixed_unary_expression
5032 $$ = new Binary (Binary.Operator.Division,
5033 (Expression) $1, (Expression) $4, (Location)$3);
5037 integer_division_expression
5038 : multiplicative_expression
5039 | integer_division_expression OP_IDIV _mark_ multiplicative_expression
5041 //FIXME: Is this right ?
5042 $$ = new Binary (Binary.Operator.IntDivision,
5043 (Expression) $1, (Expression) $4, (Location)$3);
5048 : integer_division_expression
5049 | mod_expression MOD _mark_ integer_division_expression
5051 $$ = new Binary (Binary.Operator.Modulus,
5052 (Expression) $1, (Expression) $4, (Location)$3);
5058 | additive_expression PLUS _mark_ mod_expression
5060 $$ = new Binary (Binary.Operator.Addition,
5061 (Expression) $1, (Expression) $4, (Location)$3);
5063 | additive_expression MINUS _mark_ mod_expression
5065 $$ = new Binary (Binary.Operator.Subtraction,
5066 (Expression) $1, (Expression) $4, (Location)$3);
5071 : additive_expression
5072 | concat_expression OP_CONCAT _mark_ additive_expression
5074 // FIXME: This should only work for String expressions
5075 // We probably need to use something from the runtime
5076 $$ = new StringConcat((Location)$3,
5077 (Expression) $1, (Expression) $4);
5084 | shift_expression OP_SHIFT_LEFT _mark_ concat_expression
5086 $$ = new Binary(Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, (Location)$3);
5088 | shift_expression OP_SHIFT_RIGHT _mark_ concat_expression
5090 $$ = new Binary(Binary.Operator.RightShift, (Expression) $1, (Expression) $4, (Location)$3);
5094 relational_expression
5096 | relational_expression LIKE _mark_ shift_expression
5098 $$ = new Binary (Binary.Operator.Like,
5099 (Expression) $1, (Expression) $4, (Location)$3);
5101 | relational_expression ASSIGN _mark_ shift_expression
5103 $$ = new Binary (Binary.Operator.Equality,
5104 (Expression) $1, (Expression) $4, (Location)$3);
5106 | relational_expression OP_NE _mark_ shift_expression
5108 $$ = new Binary (Binary.Operator.Inequality,
5109 (Expression) $1, (Expression) $4, (Location)$3);
5111 | relational_expression OP_LT _mark_ shift_expression
5113 $$ = new Binary (Binary.Operator.LessThan,
5114 (Expression) $1, (Expression) $4, (Location)$3);
5116 | relational_expression OP_GT _mark_ shift_expression
5118 $$ = new Binary (Binary.Operator.GreaterThan,
5119 (Expression) $1, (Expression) $4, (Location)$3);
5121 | relational_expression OP_LE _mark_ shift_expression
5123 $$ = new Binary (Binary.Operator.LessThanOrEqual,
5124 (Expression) $1, (Expression) $4, (Location)$3);
5126 | relational_expression OP_GE _mark_ shift_expression
5128 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
5129 (Expression) $1, (Expression) $4, (Location)$3);
5131 | relational_expression IS _mark_ shift_expression
5133 $$ = new Binary (Binary.Operator.Is,
5134 (Expression) $1, (Expression) $4, (Location)$3);
5136 | TYPEOF shift_expression _mark_ IS type
5138 //FIXME: Is this rule correctly defined ?
5139 $$ = new Is ((Expression) $2, (Expression) $5, (Location)$3);
5144 : relational_expression
5145 | NOT _mark_ negation_expression
5147 //FIXME: Is this rule correctly defined ?
5148 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $3, (Location)$2);
5152 conditional_and_expression
5153 : negation_expression
5154 | conditional_and_expression AND _mark_ negation_expression
5156 $$ = new Binary (Binary.Operator.BitwiseAnd,
5157 (Expression) $1, (Expression) $4, (Location)$3);
5159 | conditional_and_expression ANDALSO _mark_ negation_expression
5160 { // FIXME: this is likely to be broken
5161 $$ = new Binary (Binary.Operator.LogicalAnd,
5162 (Expression) $1, (Expression) $4, (Location)$3);
5166 conditional_or_expression
5167 : conditional_and_expression
5168 | conditional_or_expression OR _mark_ conditional_and_expression
5170 $$ = new Binary (Binary.Operator.BitwiseOr,
5171 (Expression) $1, (Expression) $4, (Location)$3);
5173 | conditional_or_expression ORELSE _mark_ conditional_and_expression
5174 { // FIXME: this is likely to be broken
5175 $$ = new Binary (Binary.Operator.LogicalOr,
5176 (Expression) $1, (Expression) $4, (Location)$3);
5180 conditional_xor_expression
5181 : conditional_or_expression
5182 | conditional_xor_expression XOR _mark_ conditional_or_expression
5184 $$ = new Binary (Binary.Operator.ExclusiveOr,
5185 (Expression) $1, (Expression) $4, (Location)$3);
5189 assignment_expression
5190 : prefixed_unary_expression ASSIGN _mark_ expression
5192 // $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$3);
5196 // Avoid re-assignment of object inside with block
5197 // TODO : Similarly do for other assignments
5199 if (with_stack.Count > 0) {
5200 Expression estack = (Expression) $1;
5202 string tempstring = Convert.ToString(estack);
5204 if(with_hash.Contains(tempstring))
5207 $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$3);
5212 $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$3);
5216 | prefixed_unary_expression OP_EXP ASSIGN _mark_ expression
5218 Location l = (Location)$4;
5219 $$ = new CompoundAssign (
5220 Binary.Operator.Exponentiation, (Expression) $1, (Expression) $5, l);
5222 | prefixed_unary_expression STAR ASSIGN _mark_ expression
5224 Location l = (Location)$4;
5225 $$ = new CompoundAssign (
5226 Binary.Operator.Multiply, (Expression) $1, (Expression) $5, l);
5228 | prefixed_unary_expression DIV ASSIGN _mark_ expression
5230 Location l = (Location)$4;
5231 $$ = new CompoundAssign (
5232 Binary.Operator.Division, (Expression) $1, (Expression) $5, l);
5234 | prefixed_unary_expression PLUS ASSIGN _mark_ expression
5236 Location l = (Location)$4;
5237 $$ = new CompoundAssign (
5238 Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
5240 | prefixed_unary_expression MINUS ASSIGN _mark_ expression
5242 Location l = (Location)$4;
5243 $$ = new CompoundAssign (
5244 Binary.Operator.Subtraction, (Expression) $1, (Expression) $5, l);
5246 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN _mark_ expression
5248 Location l = (Location)$4;
5249 $$ = new CompoundAssign (
5250 Binary.Operator.LeftShift, (Expression) $1, (Expression) $5, l);
5252 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN _mark_ expression
5254 Location l = (Location)$4;
5255 $$ = new CompoundAssign (
5256 Binary.Operator.RightShift, (Expression) $1, (Expression) $5, l);
5258 | prefixed_unary_expression OP_CONCAT ASSIGN _mark_ expression
5260 Location l = (Location)$4;
5262 // FIXME should be strings only
5263 $$ = new CompoundAssign (
5264 Binary.Operator.Concat, (Expression) $1, (Expression) $5, l);
5266 | prefixed_unary_expression ASSIGN ADDRESSOF _mark_ expression
5268 ArrayList args = new ArrayList();
5269 Expression expr = (Expression) $5;
5270 expr = SetAddressOf (expr);
5271 Argument arg = new Argument (expr, Argument.AType.Expression);
5274 New n = new New ((Expression) $1, (ArrayList) args, (Location)$4);
5275 n.isDelegate = true;
5276 $$ = new Assign ((Expression) $1, (Expression) n, (Location)$4);
5287 Expression expr = (Expression) $1;
5288 expr = SetValueRequiredFlag (expr);
5294 : namespace_or_type_name
5296 $$ = DecomposeQI ((string) $1, lexer.Location);
5305 ArrayList types = new ArrayList ();
5310 | type_list COMMA type
5312 ArrayList types = (ArrayList) $1;
5319 namespace_or_type_name
5320 : qualified_identifier
5324 : OBJECT { $$ = TypeManager.system_object_expr; }
5330 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
5331 | DATE { $$ = TypeManager.system_date_expr; }
5332 | CHAR { $$ = TypeManager.system_char_expr; }
5333 | STRING { $$ = TypeManager.system_string_expr; }
5339 | floating_point_type
5340 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
5345 | BYTE { $$ = TypeManager.system_byte_expr; }
5346 | SHORT { $$ = TypeManager.system_int16_expr; }
5347 | INTEGER { $$ = TypeManager.system_int32_expr; }
5348 | LONG { $$ = TypeManager.system_int64_expr; }
5352 : SINGLE { $$ = TypeManager.system_single_expr; }
5353 | DOUBLE { $$ = TypeManager.system_double_expr; }
5356 directive_expression
5357 : constant_expression _mark_ //FIXME: Fix for binary expression
5359 Expression exp = (Expression) $1;
5360 if (exp is SimpleName) {
5361 string key = ((SimpleName)exp).Name;
5362 if(constPreDir.Contains(key)) {
5363 $$ = new BoolLiteral ((bool)constPreDir [key]);
5367 object o = ((Constant) exp).GetValue ();
5368 bool temp = Convert.ToBoolean(o);
5369 $$ = new BoolLiteral ((bool)temp);
5370 // Report.Error (30580, (Location)$2, "value of Const used is not set");
5376 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS _mark_ EOL
5378 if(tokenizerController.IsAcceptingTokens)
5380 if(in_external_source)
5381 Report.Error (30580, (Location)$8, "#ExternalSource directives may not be nested");
5383 in_external_source = true;
5385 lexer.EffectiveSource = (string) $4;
5386 lexer.EffectiveLine = (int) $6;
5390 | HASH IDENTIFIER LITERAL_STRING _mark_ EOL
5392 if(tokenizerController.IsAcceptingTokens)
5394 if(!($2 as string).ToLower().Equals("region"))
5395 Report.Error (30205, (Location)$4, "Invalid Pre-processor directive");
5402 | HASH END IDENTIFIER _mark_ EOL
5404 if(tokenizerController.IsAcceptingTokens)
5406 if( ($3 as string).ToLower().Equals("externalsource")) {
5407 if(!in_external_source)
5408 Report.Error (30578, (Location)$4, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
5410 in_external_source = false;
5411 lexer.EffectiveSource = lexer.Source;
5412 lexer.EffectiveLine = lexer.Line;
5415 else if(($3 as string).ToLower().Equals("region")) {
5416 if(in_marked_region > 0)
5419 Report.Error (30205, (Location)$4, "'#End Region' must be preceded by a matching '#Region'");
5422 Report.Error (29999, (Location)$4, "Unrecognized Pre-Processor statement");
5426 | HASH CONST IDENTIFIER ASSIGN constant_expression _mark_ EOL
5429 Expression express = (Expression) $5;
5430 if (express is Binary) {
5434 object o = ((Constant) express).GetValue ();
5435 bool temp = Convert.ToBoolean(o);
5437 string key = Convert.ToString($3);
5439 if (constPreDir.Contains(key))
5440 constPreDir[key] = temp;
5442 constPreDir.Add($3,temp);
5447 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
5450 ifElseStateMachine.HandleToken(tok);
5452 catch(ApplicationException) {
5453 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
5456 directive_expression opt_then EOL
5458 //FIXME: Fix for constant expression
5460 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$5);
5462 | HASH opt_elseif _mark_
5464 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
5466 ifElseStateMachine.HandleToken(tok);
5468 catch(ApplicationException) {
5469 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
5472 directive_expression opt_then EOL
5474 //FIXME: Fix for constant expression
5476 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$5);
5480 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
5482 ifElseStateMachine.HandleToken(tok);
5484 catch(ApplicationException) {
5485 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
5490 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
5492 | HASH END IF _mark_
5494 /*FIXME: IF without ENDIF not working properly. Error line is not diplayed properly*/
5496 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
5498 ifElseStateMachine.HandleToken(tok);
5500 catch(ApplicationException) {
5501 throw new MBASException(ifElseStateMachine.Error, (Location)$4, ifElseStateMachine.ErrString);
5506 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
5508 | HASH error _mark_ EOL
5510 if(tokenizerController.IsAcceptingTokens)
5511 Report.Error(29999, (Location)$3, "Unrecognized Pre-Processor statement");
5513 Report.Warning (29999, (Location)$3,"Unrecognized Pre-Processor statement");
5518 // Utility rule to save location information
5521 { $$ = lexer.Location; if (yyToken == Token.EOL) { $$ = new Location (lexer.Location.Row - 1, lexer.Location.Col); } }
5524 // Changed to accept "Else If" also along with "ElseIf"
5530 // Changed so as to check if every block is closed or not...
5579 /*In case of any new end block please add it here.. after END_GET as single token... and please continue the numbering from 17...*/
5587 public Tokenizer Lexer {
5593 public static Expression DecomposeQI (string name, Location loc)
5597 if (name.IndexOf ('.') == -1) {
5598 return new SimpleName (name, loc);
5600 int pos = name.LastIndexOf (".");
5601 string left = name.Substring (0, pos);
5602 string right = name.Substring (pos + 1);
5604 o = DecomposeQI (left, loc);
5606 return new MemberAccess (o, right, loc);
5610 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
5612 Block implicit_block;
5613 ArrayList inits = null;
5616 // We use the `Used' property to check whether statements
5617 // have been added to the current block. If so, we need
5618 // to create another block to contain the new declaration
5619 // otherwise, as an optimization, we use the same block to
5620 // add the declaration.
5622 // FIXME: A further optimization is to check if the statements
5623 // that were added were added as part of the initialization
5624 // below. In which case, no other statements have been executed
5625 // and we might be able to reduce the number of blocks for
5626 // situations like this:
5628 // int j = 1; int k = j + 1;
5631 VariableDeclaration.FixupTypes (variable_declarators);
5633 if (current_block.Used) {
5634 implicit_block = new Block (current_block, true, loc, Location.Null);
5635 implicit_block.AddChildVariableNames (current_block);
5637 implicit_block = current_block;
5639 foreach (VariableDeclaration decl in variable_declarators){
5640 Expression type = decl.type;
5641 if (decl.Alias != null) {
5642 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, loc, decl.Alias) != null) {
5643 if (decl.expression_or_array_initializer != null){
5645 inits = new ArrayList ();
5651 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, loc) != null) {
5652 if (decl.expression_or_array_initializer != null){
5654 inits = new ArrayList ();
5662 return implicit_block;
5664 foreach (VariableDeclaration decl in inits){
5667 Expression type = decl.type;
5669 if ((decl.expression_or_array_initializer is Expression) ||
5670 (decl.expression_or_array_initializer is New)) {
5671 expr = (Expression) decl.expression_or_array_initializer;
5673 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
5675 expr = new ArrayCreation (type, "", init, decl.Location);
5678 LocalVariableReference var;
5679 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
5681 assign = new Assign (var, expr, decl.Location);
5683 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
5686 return implicit_block;
5689 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
5691 Block implicit_block;
5692 VariableDeclaration.FixupTypes (variable_declarators);
5694 if (current_block.Used)
5695 implicit_block = new Block (current_block, true);
5697 implicit_block = current_block;
5699 foreach (VariableDeclaration decl in variable_declarators){
5700 Expression type = decl.type;
5701 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
5702 current_local_parameters, decl.Location);
5705 return implicit_block;
5713 public VarName (object n, object t, object r)
5723 // A class used to pass around variable declarations and constants
5725 public class VariableDeclaration {
5726 public string identifier;
5727 public string Alias;
5729 public object expression_or_array_initializer;
5730 public Location Location;
5731 public Attributes OptAttributes;
5732 public Expression type;
5733 public ArrayList dims;
5735 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs, string Alias) : this
5736 (id, TypeManager.system_object_expr, eoai, l, opt_attrs, Alias)
5740 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
5741 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
5745 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, (Attributes) null)
5749 public VariableDeclaration (string id, object eoai, Location l, string Alias) : this (id, eoai, l, (Attributes) null, Alias)
5753 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs, string Alias)
5755 this.identifier = id;
5756 this.expression_or_array_initializer = eoai;
5758 this.OptAttributes = opt_attrs;
5764 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
5765 : this (id, t, eoai, l, opt_attrs, null)
5769 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, (Attributes) null)
5773 public VariableDeclaration (string id, Expression t, Location l, string Alias) : this (id, t, null, l, (Attributes) null, Alias)
5777 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
5779 // FIXME : This is broken: only the first rank is parsed
5780 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
5783 public static void FixupTypes (ArrayList vars)
5785 int varcount = vars.Count;
5786 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
5788 if (last_var.type == null)
5789 last_var.type = TypeManager.system_object_expr;
5791 Expression cur_type = last_var.type;
5792 int n = varcount - 1;
5795 VariableDeclaration var = (VariableDeclaration) vars[n--];
5796 if (var.type == null)
5797 var.type = cur_type;
5799 cur_type = var.type;
5803 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
5807 if (IndexList != null) {
5808 foreach (Expression e in IndexList)
5809 if (!(e is EmptyExpression)) {
5818 public static bool IndexesSpecified (ArrayList ranks)
5822 if (ranks != null) {
5823 foreach (ArrayList IndexList in ranks) {
5824 if (IndexesSpecifiedInRank (IndexList)) {
5833 public static string StripDims (string varname, ref string d)
5835 string res = varname;
5838 if (varname.IndexOf("[") >= 0) {
5839 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
5840 res = varname.Substring(0, varname.IndexOf("["));
5846 public static string StripDims (string varname)
5850 return (StripDims(varname, ref dres));
5853 public static string StripIndexesFromDims (string dims)
5855 StringBuilder sb = new StringBuilder();
5857 foreach (char c in dims)
5858 if (c == ',' || c == ']' || c == '[')
5861 return sb.ToString();
5864 public static string BuildRank (ArrayList rank)
5867 return BuildRank(rank, out allEmpty);
5870 public static string BuildRank (ArrayList rank, out bool allEmpty)
5877 foreach (object e in rank) {
5878 if (!(e is EmptyExpression))
5889 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
5893 bool allEmpty = true;
5894 foreach (ArrayList rank in rank_specifiers) {
5896 res = BuildRank (rank, out tmp) + res;
5900 if (!allEmpty && mustBeEmpty)
5901 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
5906 public static void VBFixIndexList (ref ArrayList IndexList)
5908 if (IndexList != null) {
5909 for (int x = 0; x < IndexList.Count; x++) {
5910 Expression e = (Expression) IndexList[x];
5911 if (!(e is EmptyExpression)) {
5912 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
5918 public static bool IsArrayDecl (Parser t)
5920 // return (varname.IndexOf("[") >= 0);
5921 return (t.current_rank_specifiers != null);
5924 public static void VBFixIndexLists (ref ArrayList ranks)
5926 if (ranks != null) {
5927 for (int x = 0; x < ranks.Count; x++) {
5928 ArrayList IndexList = (ArrayList) ranks[x];
5929 VBFixIndexList (ref IndexList);
5934 public static void FixupArrayTypes (ArrayList vars)
5938 foreach (VariableDeclaration var in vars) {
5939 if (var.identifier.EndsWith(",")) {
5940 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
5941 var.identifier.LastIndexOf(",")) + "]";
5942 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
5943 var.type = new ComposedCast (var.type, (string) dims, var.Location);
5950 public Property BuildSimpleProperty (Expression p_type, string name,
5951 Field p_fld, int mod_flags,
5952 Attributes attrs, Location loc)
5955 Block get_block, set_block;
5956 Accessor acc_set, acc_get;
5957 StatementExpression a_set;
5962 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
5963 args = new Parameter [1];
5964 args [0] = implicit_value_parameter;
5966 Parameters set_params = new Parameters (args, null, loc);
5967 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
5968 (Expression) new SimpleName("value", loc), loc), loc);
5970 set_block = new Block (current_block, set_params, loc, Location.Null);
5971 set_block.AddStatement ((Statement) a_set);
5972 acc_set = new Accessor (set_block, attrs);
5975 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
5976 get_block = new Block (current_block, null, loc, Location.Null);
5977 get_block.AddStatement ((Statement) a_get);
5978 acc_get = new Accessor (get_block, attrs);
5980 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
5987 current_block = new Block (current_block, current_local_parameters,
5988 lexer.Location, Location.Null);
5991 void start_method_block (string Name)
5993 current_block = new MethodBlock (current_block, current_local_parameters,
5994 lexer.Location, Location.Null, Name);
6001 while (current_block.Implicit)
6002 current_block = current_block.Parent;
6004 res = current_block;
6006 current_block.SetEndLocation (lexer.Location);
6007 current_block = current_block.Parent;
6012 void push_into_stack(int BlockStart, Location l)
6014 end_of_block.Push(BlockStart);
6015 loc_end_of_block.Push(l);
6018 void pop_out_of_stack(int BlockEnd, Location l)
6020 if(BlockEnd != Token.EOF) {
6021 int current = (int)end_of_block.Pop();
6022 Location current_loc = (Location)loc_end_of_block.Pop();
6023 if(BlockEnd != current) {
6024 // Block end is missing
6025 // eg: For 'Sub' BlockEnd should be 'End Sub'
6027 if(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2]) {
6028 while(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2])
6030 if(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2])
6031 Report.Error(error_end_blocks[current,0],current_loc,"'"+end_blocks[current,0]+"' is not having matching '"+end_blocks[current,1]+"'");
6032 current = (int)end_of_block.Pop();
6033 current_loc = (Location)loc_end_of_block.Pop();
6037 // Extra end is present, but works for lesser priority
6038 // (for priority see opt_end_block opt_block_types return values
6039 // eg: 'EndIf' without 'If' inside 'Sub'
6040 // Also certain other errors like 'Sub' having a 'End Module' etc
6041 // can be handled here
6043 if(error_end_blocks[BlockEnd,2] < error_end_blocks[current,2]) {
6044 Report.Error(error_end_blocks[BlockEnd,1],l,"'"+end_blocks[BlockEnd,1]+"' is not having a corresponding '"+end_blocks[BlockEnd,0]+"'");
6045 end_of_block.Push(current);
6046 loc_end_of_block.Push(current_loc);
6048 // Extra end is present but with equal priorty
6050 if((error_end_blocks[BlockEnd,2] == error_end_blocks[current,2]) && BlockEnd != current) {
6051 while((error_end_blocks[BlockEnd,2] == error_end_blocks[current,2]) && BlockEnd != current) {
6052 temp_block.Push(current);
6053 loc_temp_block.Push(current_loc);
6054 current = (int)end_of_block.Pop();
6055 current_loc = (Location)loc_end_of_block.Pop();
6058 if(BlockEnd == current) {
6059 while(temp_block.Count !=0)
6061 int lapse = (int) temp_block.Pop();
6062 Location lapse_location = (Location)loc_temp_block.Pop();
6063 Report.Error(error_end_blocks[lapse,0],lapse_location,"'"+end_blocks[lapse,0]+"' is not having matching '"+end_blocks[lapse,1]+"'");
6068 Report.Error(error_end_blocks[BlockEnd,1],l,"'"+end_blocks[BlockEnd,1]+"' is not having a corresponding '"+end_blocks[BlockEnd,0]+"'");
6069 end_of_block.Push(current);
6070 loc_end_of_block.Push(current_loc);
6071 while(temp_block.Count !=0) {
6072 int lapse = (int) temp_block.Pop();
6073 Location lapse_location = (Location)loc_temp_block.Pop();
6074 end_of_block.Push(lapse);
6075 loc_end_of_block.Push(lapse_location);
6082 while(end_of_block.Count !=0) {
6083 int lapse = (int) end_of_block.Pop();
6084 Location lapse_location = (Location)loc_end_of_block.Pop();
6085 Report.Error(error_end_blocks[lapse,0],lapse_location,"'"+end_blocks[lapse,0]+"' is not having matching '"+end_blocks[lapse,1]+"'");
6090 private void AddHandler (Expression evt_definition, Expression handler_exp)
6092 AddHandler (current_block, evt_definition, handler_exp);
6096 void CheckAttributeTarget (string a)
6100 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
6104 Location l = lexer.Location;
6105 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
6111 private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
6113 Location loc = lexer.Location;
6115 Statement addhnd = (Statement) new AddHandler (evt_id,
6118 b.AddStatement (addhnd);
6121 private void RaiseEvent (string evt_name, ArrayList args)
6123 Location loc = lexer.Location;
6124 Expression qi = DecomposeQI (evt_name, loc);
6126 Invocation evt_call = new Invocation (qi, args, lexer.Location);
6127 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
6129 Binary bin = new Binary (Binary.Operator.Is, qi, (Expression) NullLiteral.Null, loc);
6130 If if_s = new If (bin, new EmptyStatement (), s, loc);
6132 current_block.AddStatement (if_s);
6135 private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
6137 Location loc = lexer.Location;
6139 Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
6142 b.AddStatement (rmhnd);
6145 private Constant ConvertLiteral (Constant literal, Type target_type)
6147 if (literal.GetValue ().GetType () == target_type)
6148 //no conversion required
6151 if (target_type == typeof (float))
6152 return new FloatLiteral ((float) literal.ConvertToFloat ().Value);
6154 if (target_type == typeof (decimal))
6155 return new DecimalLiteral ((decimal) literal.ConvertToDecimal ().Value);
6157 if (target_type == typeof (double))
6158 return new DoubleLiteral ((double) literal.ConvertToDouble ().Value);
6160 if (target_type == typeof (long))
6161 return new LongLiteral ((Int64) literal.ConvertToLong ().Value);
6163 if (target_type == typeof (int))
6164 return new IntLiteral ((Int32) literal.ConvertToInt ().Value);
6166 /* FIXME: throw error? */
6171 // This method is used to get at the complete string representation of
6172 // a fully-qualified type name, hiding inside a MemberAccess ;-)
6173 // This is necessary because local_variable_type admits primary_expression
6174 // as the type of the variable. So we do some extra checking
6176 string GetQualifiedIdentifier (Expression expr)
6178 if (expr is SimpleName)
6179 return ((SimpleName)expr).Name;
6180 else if (expr is MemberAccess)
6181 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
6183 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
6187 private void RemoveHandler (Expression evt_definition, Expression handler_exp)
6189 RemoveHandler (current_block, evt_definition, handler_exp);
6192 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
6194 ConstructorInitializer ci = null;
6197 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
6198 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
6200 if (i.expr is BaseAccess) {
6201 BaseAccess ba = (BaseAccess) i.expr;
6202 if (ba.member == "New" || ba.member == ".ctor") {
6203 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
6207 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
6208 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
6217 void Error_ExpectingTypeName (Location l, Expression expr)
6219 if (expr is Invocation){
6220 Report.Error (1002, l, "; expected");
6222 Report.Error (-1, l, "Invalid Type definition");
6227 public static Expression SetLeftHandFlag (Expression expr) {
6228 if (expr is Invocation) {
6229 Invocation e = (Invocation) expr;
6230 e.IsLeftHand = true;
6232 } else if (expr is MemberAccess) {
6233 MemberAccess e = (MemberAccess) expr;
6234 e.IsLeftHand = true;
6241 public static Expression SetValueRequiredFlag (Expression expr) {
6242 if (expr is Invocation) {
6243 Invocation e = (Invocation) expr;
6244 e.IsRetvalRequired = true;
6248 if (expr is Binary) {
6249 Binary binary = (Binary) expr;
6250 binary.Left = SetValueRequiredFlag (binary.Left);
6251 binary.Right = SetValueRequiredFlag (binary.Right);
6254 if (expr is Unary) {
6255 Unary unary = (Unary) expr;
6256 unary.Expr = SetValueRequiredFlag (unary.Expr);
6262 public static Expression SetAddressOf (Expression expr) {
6263 if (expr is SimpleName) {
6264 SimpleName sname = expr as SimpleName;
6265 sname.IsAddressOf = true;
6268 if (expr is MemberAccess) {
6269 MemberAccess ma = expr as MemberAccess;
6270 ma.IsAddressOf = true;
6277 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
6282 private void ReportError9998()
6284 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
6287 protected override int parse ()
6289 RootContext.InitializeImports(ImportsList);
6290 current_namespace = new Namespace (null, RootContext.RootNamespace);
6291 current_container = RootContext.Tree.Types;
6292 current_container.Namespace = current_namespace;
6293 oob_stack = new Stack ();
6294 switch_stack = new Stack ();
6295 expr_stack = new Stack ();
6296 tmp_blocks = new Stack();
6297 with_stack = new Stack();
6298 statement_stack = new Stack();
6299 end_of_block = new Stack ();
6300 loc_end_of_block = new Stack ();
6301 temp_block = new Stack();
6302 loc_temp_block = new Stack();
6304 allow_global_attribs = true;
6305 expecting_global_attribs = false;
6306 expecting_local_attribs = false;
6307 local_attrib_section_added = false;
6309 UseExtendedSyntax = name.EndsWith(".mbs");
6310 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
6311 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
6312 OptionCompareBinary = InitialOptionCompareBinary;
6314 lexer = new Tokenizer (input, name, defines);
6316 ifElseStateMachine = new IfElseStateMachine();
6317 tokenizerController = new TokenizerController(lexer);
6320 if (yacc_verbose_flag > 0)
6321 yyparse (lexer, new yydebug.yyDebugSimple ());
6327 catch(MBASException e) {
6328 Report.Error(e.code, e.loc, e.Message);
6330 catch (Exception e) {
6331 if (Report.Stacktrace)
6332 Console.WriteLine(e);
6333 Report.Error (29999, lexer.Location, "Parsing error");
6336 RootContext.VerifyImports();
6338 return Report.Errors;
6344 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
6346 catch(ApplicationException) {
6347 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
6350 if(in_external_source)
6351 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
6353 if(in_marked_region > 0)
6354 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
6357 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
6360 tokenizerController.PositionTokenizerCursor(tok, expr);
6362 catch(ApplicationException) {
6363 tok = IfElseStateMachine.Token.EOF;
6365 ifElseStateMachine.HandleToken(tok);
6367 catch(ApplicationException) {
6368 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);