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 static public bool InitialOptionExplicit = false;
251 static public bool InitialOptionStrict = false;
252 static public bool InitialOptionCompareBinary = true;
253 static public ArrayList ImportsList = null;
257 bool OptionCompareBinary;
259 static public bool UseExtendedSyntax; // for ".mbs" files
261 bool implicit_modifiers;
263 public override string[] extensions()
265 string [] list = { ".vb", ".mbs" };
269 bool in_external_source = false;
270 int in_marked_region = 0;
272 TokenizerController tokenizerController;
273 IfElseStateMachine ifElseStateMachine;
276 public class IfElseStateMachine {
300 public static Hashtable errStrings = new Hashtable();
303 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
305 static IfElseStateMachine()
307 // FIXME: Fix both the error nos and the error strings.
308 // Currently the error numbers and the error strings are
309 // just placeholders for getting the state-machine going.
311 errStrings.Add(0, "");
312 errStrings.Add(30012, "#If must end with a matching #End If");
313 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
314 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
315 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
316 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
318 errTable[(int)State.START, (int)Token.IF] = 0;
319 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
320 errTable[(int)State.START, (int)Token.ELSE] = 30028;
321 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
322 errTable[(int)State.START, (int)Token.EOF] = 0;
324 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
325 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
326 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
327 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
328 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
330 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
331 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
332 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
333 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
334 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
336 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
337 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
338 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
339 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
340 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
342 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
343 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
344 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
345 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
346 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
349 public IfElseStateMachine()
353 stateStack = new Stack();
354 stateStack.Push(state);
357 // The parameter here need not be qualified with IfElseStateMachine
358 // But it hits a bug in mcs. So temporarily scoping it so that builds
361 public void HandleToken(IfElseStateMachine.Token tok)
363 err = (int) errTable[(int)state, (int)tok];
366 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
368 if(tok == Token.IF) {
369 stateStack.Push(state);
372 else if(tok == Token.ENDIF) {
373 state = (State)stateStack.Pop();
385 public string ErrString {
387 return (string) errStrings[err];
393 public class TokenizerController {
397 public bool CanAcceptTokens;
398 public bool CanSelectBlock;
405 public TokenizerController(Tokenizer lexer)
408 stateStack = new Stack();
410 currentState.CanAcceptTokens = true;
411 currentState.CanSelectBlock = true;
413 stateStack.Push(currentState);
418 return (State)stateStack.Peek();
422 public bool IsAcceptingTokens {
424 return currentState.CanAcceptTokens;
428 public void PositionCursorAtNextPreProcessorDirective()
430 lexer.PositionCursorAtNextPreProcessorDirective();
433 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
435 if(tok == IfElseStateMachine.Token.ENDIF) {
436 currentState = (State)stateStack.Pop();
438 if(currentState.CanAcceptTokens)
441 PositionCursorAtNextPreProcessorDirective();
446 if(tok == IfElseStateMachine.Token.IF) {
447 stateStack.Push(currentState);
449 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
450 currentState.CanSelectBlock = true;
453 if(parentState.CanAcceptTokens &&
454 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
456 currentState.CanAcceptTokens = true;
457 currentState.CanSelectBlock = false;
461 currentState.CanAcceptTokens = false;
462 PositionCursorAtNextPreProcessorDirective();
468 bool allow_global_attribs = true;
470 bool expecting_global_attribs = false;
471 bool expecting_local_attribs = false;
473 bool local_attrib_section_added = false;
477 %token NONE /* This token is never returned by our lexer */
478 %token ERROR // This is used not by the parser, but by the tokenizer.
482 *These are the MonoBASIC keywords
575 %token NOTINHERITABLE
576 %token NOTOVERRIDABLE
632 %token YIELD // MonoBASIC extension
636 /* MonoBASIC single character operators/punctuation. */
638 %token OPEN_BRACKET "["
639 %token CLOSE_BRACKET "]"
640 %token OPEN_PARENS "("
641 %token OPEN_BRACE "{"
642 %token CLOSE_BRACE "}"
643 %token CLOSE_PARENS ")"
657 %token OP_IDIV "\\" //FIXME: This should be "\"
659 %token EXCLAMATION "!"
662 %token LONGTYPECHAR "&"
664 %token SINGLETYPECHAR "!"
665 %token NUMBER_SIGN "#"
666 %token DOLAR_SIGN "$"
668 %token ATTR_ASSIGN ":="
670 /* MonoBASIC multi-character operators. */
675 //%token OP_MODULUS //"mod"
677 /* VB.NET 2003 new bit-shift operators */
678 %token OP_SHIFT_LEFT "<<"
679 %token OP_SHIFT_RIGHT ">>"
682 %token LITERAL_INTEGER "int literal"
683 %token LITERAL_SINGLE "float literal"
684 %token LITERAL_DOUBLE "double literal"
685 %token LITERAL_DECIMAL "decimal literal"
686 %token LITERAL_CHARACTER "character literal"
687 %token LITERAL_STRING "string literal"
688 %token LITERAL_DATE "datetime literal"
692 /* Add precedence rules to solve dangling else s/r conflict */
701 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
703 %left STAR DIV PERCENT
704 %right BITWISE_NOT CARRET UMINUS
705 %nonassoc OP_INC OP_DEC
707 %left OPEN_BRACKET OPEN_BRACE
712 %start compilation_unit
716 : logical_end_of_line
723 | logical_end_of_line pp_directive
727 : logical_end_of_line _mark_
728 opt_option_directives
729 opt_imports_directives
735 | logical_end_of_line _mark_
736 opt_option_directives
737 opt_imports_directives
745 opt_option_directives
752 | option_directives option_directive
756 : option_explicit_directive
757 | option_strict_directive
758 | option_compare_directive
759 | OPTION _mark_ logical_end_of_line
761 Report.Error(30206 ,(Location)$2, "Option must be followed by 'Compare' or 'Explicit' or 'Strict'");
763 | OPTION _mark_ IDENTIFIER logical_end_of_line
765 Report.Error(30206 ,(Location)$2, "Option must be followed by 'Compare' or 'Explicit' or 'Strict'");
795 option_explicit_directive
796 : OPTION EXPLICIT _mark_ on_off logical_end_of_line
798 if (!UseExtendedSyntax)
799 OptionExplicit = (bool)$4;
803 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
808 option_strict_directive
809 : OPTION STRICT _mark_ on_off logical_end_of_line
811 if (!UseExtendedSyntax)
812 OptionStrict = (bool)$4;
816 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
820 option_compare_directive
821 : OPTION COMPARE text_or_binary logical_end_of_line
823 OptionCompareBinary = (bool)$3;
834 | declarations declaration
838 : declaration_qualifiers
840 // FIXME: Need to check declaration qualifiers for multi-file compilation
841 // FIXME: Qualifiers cannot be applied to namespaces
842 allow_global_attribs = false;
844 namespace_declaration
845 |declaration_qualifiers _mark_
847 // FIXME: Need to check declaration qualifiers for multi-file compilation
848 allow_global_attribs = false;
850 type_spec_declaration
855 if ($4 is Class || $4 is Struct || $4 is Module ){
856 TypeContainer c = (TypeContainer) $4;
857 mod_flags = c.ModFlags;
862 if ((mod_flags & (Modifiers.PRIVATE)) != 0){
865 "Namespace elements cannot be explicitly " +
866 "declared private in '" + name + "'");
868 else if ((mod_flags & (Modifiers.PROTECTED)) != 0){
871 "Namespace elements cannot be explicitly " +
872 "declared protected in '" + name + "'");
887 : PERCENT { $$ = TypeManager.system_int32_expr; }
888 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
889 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
890 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
891 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
892 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
896 : /* empty */ { $$ = null; }
897 | type_character { $$ = $1; }
903 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
905 $$ = (($1).ToString ()) + "." + ($3.ToString ());
909 opt_imports_directives
916 | imports_directives imports_directive
920 : IMPORTS imports_terms logical_end_of_line
925 | imports_terms COMMA imports_term
929 : namespace_or_type_name
931 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
933 | identifier _mark_ ASSIGN namespace_or_type_name
935 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $4, (Location)$2);
937 | identifier _mark_ ASSIGN
939 Report.Error(30203, (Location)$2, "Alias Statement no complete: Expression Expected");
943 Report.Error(30203, (Location)$1, "No namespace imported: Expression Expected");
948 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
949 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
950 | OPEN_PARENS _mark_ opt_formal_parameter_list CLOSE_PARENS { $$ = $3; }
953 Report.Error(30203,(Location)$2, "Identifier Expected");
954 $$ = Parameters.EmptyReadOnlyParameters;
956 | OPEN_PARENS _mark_ opt_formal_parameter_list error
958 Report.Error(30198,(Location)$2, "'(' is not having a matching ')'");
961 | error _mark_ opt_formal_parameter_list CLOSE_PARENS
963 Report.Error(30205,(Location)$2, "')' is not having a matching '('");
973 local_attrib_section_added = false;
982 expecting_local_attribs = false;
983 expecting_global_attribs = false;
987 if (expecting_local_attribs) {
988 local_attrib_section_added = true;
989 allow_global_attribs = false;
991 $$ = new Attributes ((ArrayList) $1);
994 if (expecting_global_attribs) {
996 CodeGen.AddGlobalAttributes ((ArrayList) $1);
999 expecting_local_attribs = false;
1000 expecting_global_attribs = false;
1002 | attribute_sections
1004 $$ = lexer.Location;
1010 ArrayList attrs = (ArrayList) $3;
1012 if (expecting_local_attribs) {
1013 if (local_attrib_section_added) {
1014 expecting_local_attribs = false;
1015 expecting_global_attribs = false;
1016 Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
1021 $$ = new Attributes (attrs);
1023 ((Attributes) $1).Add (attrs);
1025 local_attrib_section_added = true;
1026 allow_global_attribs = false;
1029 if (expecting_global_attribs) {
1031 CodeGen.AddGlobalAttributes ((ArrayList) $3);
1035 expecting_local_attribs = false;
1036 expecting_global_attribs = false;
1041 : OP_LT _mark_ attribute_list OP_GT opt_end_of_stmt
1045 if (expecting_global_attribs && !(bool) $5) {
1046 Report.Error (30205, (Location)$2, "End of statement expected");
1050 if (expecting_local_attribs) {
1052 Report.Error (32035, (Location)$2, "Use a line continuation after the attribute specifier to apply it to the following statement.");
1063 : /* empty */ { $$ = false; }
1064 | end_of_stmt { $$ = true; }
1070 ArrayList attrs = null;
1072 attrs = new ArrayList ();
1077 | attribute_list COMMA attribute
1079 ArrayList attrs = null;
1082 attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
1091 : namespace_or_type_name
1093 $$ = lexer.Location;
1095 opt_attribute_arguments
1099 if (expecting_global_attribs)
1100 Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
1102 expecting_local_attribs = true;
1103 $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
1106 | attribute_target_specifier
1108 $$ = lexer.Location;
1111 namespace_or_type_name
1113 $$ = lexer.Location;
1115 opt_attribute_arguments
1119 string attribute_target = (string) $1;
1120 if (attribute_target != "assembly" && attribute_target != "module") {
1121 Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
1124 if (!allow_global_attribs) {
1125 Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
1129 if (expecting_local_attribs) {
1130 Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
1134 expecting_global_attribs = true;
1135 $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
1139 attribute_target_specifier
1140 : ASSEMBLY { $$ = "assembly"; }
1141 | MODULE { $$ = "module"; }
1142 | namespace_or_type_name
1146 opt_attribute_arguments
1147 : /* empty */ { $$ = null; }
1148 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
1154 opt_attribute_arguments_list
1156 | attribute_arguments_list
1159 attribute_arguments_list
1160 : positional_argument_list
1162 ArrayList args = new ArrayList ();
1167 | positional_argument_list COMMA named_argument_list
1169 ArrayList args = new ArrayList ();
1175 | named_argument_list
1177 ArrayList args = new ArrayList ();
1185 positional_argument_list
1186 : constant_expression
1188 ArrayList args = new ArrayList ();
1189 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
1193 | positional_argument_list COMMA constant_expression
1195 ArrayList args = (ArrayList) $1;
1196 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
1205 ArrayList args = new ArrayList ();
1210 | named_argument_list COMMA named_argument
1212 ArrayList args = (ArrayList) $1;
1220 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
1222 $$ = new DictionaryEntry (
1224 new Argument ((Expression) $3, Argument.AType.Expression));
1228 namespace_declaration
1229 : NAMESPACE _mark_ qualified_identifier logical_end_of_line
1231 push_into_stack((int)Start_block.NAMESPACE, (Location)$2);
1232 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
1238 pop_out_of_stack((int)$7, lexer.Location);
1242 current_namespace = current_namespace.Parent;
1246 declaration_qualifiers
1250 current_attributes = (Attributes) $1;
1251 current_modifiers = (int) $2;
1255 type_spec_declaration
1257 | module_declaration
1258 | interface_declaration
1259 | delegate_declaration
1260 | struct_declaration
1265 : CLASS identifier _mark_ end_of_stmt opt_inherits opt_implements
1267 // Module members are static by default, but Class *can't* be declared static
1268 // so we must fix it, if mbas was the one actually responsible for this
1269 // instead of triggering an error.
1270 push_into_stack((int)Start_block.CLASS, (Location)$3);
1272 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1273 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1278 name = MakeName ((string) $2);
1279 new_class = new Class (current_container, name, current_modifiers,
1280 (Attributes) current_attributes, (Location)$3);
1282 current_container = new_class;
1283 current_container.Namespace = current_namespace;
1284 RootContext.Tree.RecordDecl (name, new_class);
1286 opt_class_member_declarations
1289 pop_out_of_stack((int)$9, lexer.Location);
1293 Class new_class = (Class) current_container;
1295 ArrayList bases = (ArrayList) $5;
1297 ArrayList ifaces = (ArrayList) $6;
1298 if (ifaces != null){
1300 bases.AddRange(ifaces);
1304 new_class.Bases = bases;
1306 current_container = current_container.Parent;
1307 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1314 : /* empty */ { $$ = null; }
1315 | INHERITS type_list end_of_stmt { $$ = $2; }
1319 : /* empty */ { $$ = null; }
1320 | IMPLEMENTS type_list end_of_stmt { $$ = $2; }
1324 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1325 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1330 | modifiers modifier
1335 if ((m1 & m2) != 0) {
1336 Location l = lexer.Location;
1337 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1339 $$ = (int) (m1 | m2);
1344 : PUBLIC { $$ = Modifiers.PUBLIC; }
1345 | PROTECTED { $$ = Modifiers.PROTECTED; }
1346 | PRIVATE { $$ = Modifiers.PRIVATE; }
1347 | SHARED { $$ = Modifiers.STATIC; }
1348 | FRIEND { $$ = Modifiers.INTERNAL; }
1349 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1350 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1351 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1352 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1353 | OVERLOADS { $$ = Modifiers.NEW; }
1354 | SHADOWS { $$ = Modifiers.SHADOWS; }
1355 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1356 | READONLY { $$ = Modifiers.READONLY; }
1357 | DEFAULT { $$ = Modifiers.DEFAULT; }
1358 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1362 : MODULE _mark_ identifier logical_end_of_line
1364 push_into_stack((int)Start_block.MODULE, (Location)$2);
1367 name = MakeName((string) $3);
1368 new_module = new Module(current_container,
1370 current_modifiers, // already checks then
1371 (Attributes) current_attributes,
1373 current_container = new_module;
1374 current_container.Namespace = current_namespace;
1375 RootContext.Tree.RecordDecl(name, new_module);
1377 opt_module_member_declarations
1380 pop_out_of_stack((int)$7, lexer.Location);
1384 Module new_module = (Module)current_container;
1386 current_container = current_container.Parent;
1387 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1389 TypeManager.AddStandardModule(new_module);
1395 opt_module_member_declarations
1397 | module_member_declarations
1400 module_member_declarations
1401 : module_member_declaration
1402 | module_member_declarations module_member_declaration
1405 module_member_declaration
1409 current_attributes = (Attributes) $1;
1410 current_modifiers = ((int)$2) | Modifiers.STATIC;
1411 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1412 implicit_modifiers = (!explicit_static);
1414 module_member_declarator
1416 implicit_modifiers = false;
1421 module_member_declarator
1422 : constructor_declaration
1423 | method_declaration
1425 Method method = (Method) $1;
1426 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1429 | withevents_declaration /* This is a field but must be treated specially, see below */
1430 | constant_declaration
1431 | property_declaration
1433 | type_spec_declaration
1436 constant_declaration
1437 : CONST constant_declarators end_of_stmt
1439 // Module members are static by default, but constants *can't* be declared static
1440 // so we must fix it, if mbas was the one actually responsible for this
1441 // instead of triggering an error.
1442 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1443 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1445 int mod = (int) current_modifiers;
1447 // Structure members are Public by default
1448 if ((current_container is Struct) && (mod == 0))
1449 mod = Modifiers.PUBLIC;
1451 ArrayList consts = (ArrayList) $2;
1452 if(consts.Count > 0)
1454 VariableDeclaration.FixupTypes ((ArrayList) $2);
1455 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1457 foreach (VariableDeclaration var in (ArrayList) $2){
1458 Location l = var.Location;
1459 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1460 (Expression)var.expression_or_array_initializer,
1461 mod, (Attributes) null, l);
1463 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1469 opt_class_member_declarations
1471 | class_member_declarations
1474 class_member_declarations
1475 : class_member_declaration
1476 | class_member_declarations class_member_declaration
1479 class_member_declaration
1483 current_attributes = (Attributes) $1;
1484 current_modifiers = (int) $2;
1486 class_member_declarator
1492 class_member_declarator
1493 : constructor_declaration
1494 | method_declaration
1496 Method method = (Method) $1;
1497 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1500 | constant_declaration
1501 | property_declaration
1503 | withevents_declaration /* This is a field but must be treated specially, see below */
1504 | type_spec_declaration
1511 | must_override_declaration
1514 must_override_declaration
1515 : must_override_sub_declaration
1516 | must_override_func_declaration
1519 must_override_sub_declaration
1520 : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause _mark_ logical_end_of_line
1522 if (current_container is Module)
1523 Report.Error (30433, (Location)$6, "Methods in a Module cannot be declared 'MustOverride'.");
1525 if (current_container is Struct)
1526 Report.Error (435, (Location)$6, "Methods in a Structure cannot be declared 'MustOverride'.");
1528 current_modifiers |= Modifiers.ABSTRACT;
1530 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1531 (Parameters) $4, null, (ArrayList) $5, (Location)$6);
1533 if (!(current_container is Class))
1534 Report.Error (9999, (Location)$6, "THIS SHOULD NEVER HAPPEN!");
1541 must_override_func_declaration
1542 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
1544 Expression ftype = ($7 == null) ? (($4 == null) ? TypeManager.
1545 system_object_expr : (Expression) $4 ) : (Expression) $7;
1547 if (current_container is Module)
1548 Report.Error (30433, (Location)$6,"Methods in a Module cannot be declared 'MustOverride'.");
1550 if (current_container is Struct)
1551 Report.Error (435, (Location)$6,"Methods in a Structure cannot be declared 'MustOverride'.");
1553 current_modifiers |= Modifiers.ABSTRACT;
1555 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1556 (string) $3,(Parameters) $5, null, (ArrayList) $8,
1559 if (!(current_container is Class))
1560 Report.Error (9999, (Location)$6,"THIS SHOULD NEVER HAPPEN!");
1567 : SUB identifier _mark_ opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1569 push_into_stack((int)Start_block.SUB, (Location)$3);
1570 current_local_parameters = (Parameters) $4;
1573 // Structure members are Public by default
1574 if ((current_container is Struct) && (current_modifiers == 0))
1575 current_modifiers = Modifiers.PUBLIC;
1581 pop_out_of_stack((int)$10, lexer.Location);
1585 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1586 (Parameters) current_local_parameters, (Attributes) current_attributes,
1587 (ArrayList) $6, (Location)$3);
1589 method.Block = (Block) end_block();
1593 // we have an event handler to take care of
1595 Expression handles_exp = (Expression) $5;
1596 Location loc = (Location)$3;
1598 if (handles_exp is MemberAccess) {
1599 string evt_def = ((MemberAccess)$5).ToString();
1600 int pos = evt_def.LastIndexOf (".");
1601 string evt_target = evt_def.Substring (0, pos);
1604 if (current_container.Properties != null) {
1605 foreach (Property p in current_container.Properties) {
1606 if (p.Name == evt_target) {
1609 Statement addhnd = (Statement) new AddHandler ((Expression) $5,
1610 DecomposeQI((string) $2, loc),
1613 current_container.AddEventHandler (addhnd);
1621 Report.Error(30506, (Location)$3,
1622 evt_target + " is not declared with WithEvents");
1624 } else if (handles_exp is BaseAccess) {
1625 Statement addhnd = (Statement) new AddHandler ((Expression) $5,
1626 DecomposeQI((string) $2, loc),
1629 current_container.AddEventHandler (addhnd);
1637 : FUNCTION identifier opt_type_character
1638 opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
1640 push_into_stack((int)Start_block.FUNCTION, (Location)$5);
1641 current_local_parameters = (Parameters) $4;
1644 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
1646 // Structure members are Public by default
1647 if ((current_container is Struct) && (current_modifiers == 0))
1648 current_modifiers = Modifiers.PUBLIC;
1649 // Add local var declaration
1651 ArrayList retval = new ArrayList ();
1652 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, (Location)$5));
1653 declare_local_variables ((Expression) ftype, retval, (Location)$5);
1658 pop_out_of_stack((int)$11, lexer.Location);
1662 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
1664 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1665 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1666 (ArrayList) $7, (Location)$5);
1667 method.Block = end_block();
1673 : STRUCTURE _mark_ identifier end_of_stmt
1674 opt_implement_clause
1676 push_into_stack((int)Start_block.STRUCTURE, (Location)$2);
1678 string full_struct_name = MakeName ((string) $3);
1680 // Module members are static by default, but structures *can't* be declared static
1681 // so we must fix it, if mbas was the one actually responsible for this
1682 // instead of triggering an error.
1683 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1684 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1686 new_struct = new Struct (current_container, full_struct_name,
1687 (int) current_modifiers,
1688 (Attributes) current_attributes, (Location)$2);
1689 current_container = new_struct;
1690 current_container.Namespace = current_namespace;
1691 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1693 opt_struct_member_declarations
1695 Struct new_struct = (Struct) current_container;
1698 new_struct.Bases = (ArrayList) $5;
1700 current_container = current_container.Parent;
1701 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1706 pop_out_of_stack((int)$9, lexer.Location);
1711 opt_struct_member_declarations
1713 | struct_member_declarations
1716 struct_member_declarations
1717 : struct_member_declaration
1718 | struct_member_declarations struct_member_declaration
1721 struct_member_declaration
1723 struct_member_declarator
1726 struct_member_declarator
1728 | constant_declaration
1729 | constructor_declaration
1730 | method_declaration
1732 Method method = (Method) $1;
1733 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1735 | property_declaration
1737 | type_spec_declaration
1740 * This is only included so we can flag error 575:
1741 * destructors only allowed on class types
1743 //| destructor_declaration
1747 : EVENT identifier _mark_ AS type opt_implement_clause logical_end_of_line
1749 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $5, (Location)$3);
1751 Event e = new Event ((Expression) $5, var.identifier,
1752 null, current_modifiers,
1753 current_attributes, (ArrayList) $6,
1756 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1758 | EVENT identifier _mark_ opt_params opt_implement_clause logical_end_of_line
1760 string delName = null;
1763 delName = (string) $2;
1764 delName = delName + "EventHandler";
1765 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1766 (current_container, TypeManager.system_void_expr,
1767 (int) current_modifiers, MakeName(delName), (Parameters) $4,
1768 (Attributes) current_attributes, (Location)$3);
1770 del.Namespace = current_namespace;
1771 CheckDef (current_container.AddDelegate (del), del.Name, (Location)$3);
1773 ArrayList impls = (ArrayList) $5;
1774 if (impls.Count > 1) {
1775 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1776 "' can not be implemented with Event '" +
1777 (string) $2 + "', since it's delegate type does not match " +
1778 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1779 Report.Error (31407, (Location)$3, expstr);
1781 Expression impl = (Expression) impls[0];
1782 delName = impl.ToString();
1783 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1784 delName = delName + "EventHandler";
1787 Event e = new Event (DecomposeQI (delName, (Location)$3),
1789 null, current_modifiers,
1790 current_attributes, (ArrayList) $5,
1793 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1798 : ENUM _mark_ identifier opt_type_spec logical_end_of_line
1799 opt_enum_member_declarations
1801 push_into_stack((int)Start_block.ENUM, (Location)$2);
1802 Location enum_location = (Location)$2;
1803 string full_name = MakeName ((string) $3);
1804 Expression enum_type = ($4 == null) ? TypeManager.system_int32_expr : (Expression) $4;
1805 ArrayList enum_members = (ArrayList) $6;
1807 if (enum_members.Count == 0)
1808 Report.Error (30280, enum_location,
1809 "Enum can not have empty member list");
1811 // Module members are static by default, but enums *can't* be declared static
1812 // so we must fix it if mbas was the one actually responsible for this
1813 // instead of triggering an error.
1814 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1815 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1817 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1818 (int) current_modifiers, full_name,
1819 (Attributes) current_attributes, enum_location);
1821 foreach (VariableDeclaration ev in enum_members) {
1822 Location loc = (Location) ev.Location;
1824 CheckDef (e.AddEnumMember (ev.identifier,
1825 (Expression) ev.expression_or_array_initializer,
1826 loc, ev.OptAttributes), ev.identifier, loc);
1829 e.Namespace = current_namespace;
1831 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1832 RootContext.Tree.RecordDecl (full_name, e);
1837 pop_out_of_stack((int)$8,lexer.Location);
1842 opt_enum_member_declarations
1843 : /* empty */ { $$ = new ArrayList (); }
1844 | enum_member_declarations { $$ = $1; }
1847 enum_member_declarations
1848 : enum_member_declaration
1850 ArrayList l = new ArrayList ();
1855 | enum_member_declarations enum_member_declaration
1857 ArrayList l = (ArrayList) $1;
1865 enum_member_declaration
1866 : opt_attributes identifier _mark_ logical_end_of_line
1868 $$ = new VariableDeclaration ((string) $2, null, (Location)$3, (Attributes) $1);
1870 | opt_attributes identifier
1872 $$ = lexer.Location;
1874 ASSIGN expression logical_end_of_line
1876 $$ = new VariableDeclaration ((string) $2, (Expression)$5, (Location)$3, (Attributes) $1);
1880 interface_declaration
1881 : INTERFACE _mark_ identifier logical_end_of_line
1883 push_into_stack((int)Start_block.INTERFACE, (Location)$2);
1884 Interface new_interface;
1885 string full_interface_name = MakeName ((string) $3);
1887 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1888 (Attributes) current_attributes, (Location)$2);
1889 if (current_interface != null) {
1890 Report.Error (-2, (Location)$2, "Internal compiler error: interface inside interface");
1892 current_interface = new_interface;
1893 new_interface.Namespace = current_namespace;
1894 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1899 Interface new_interface = (Interface) current_interface;
1902 new_interface.Bases = (ArrayList) $6;
1904 current_interface = null;
1905 CheckDef (current_container.AddInterface (new_interface),
1906 new_interface.Name, new_interface.Location);
1911 pop_out_of_stack((int)$9, lexer.Location);
1917 : /* empty */ { $$ = null; }
1923 | interface_bases interface_base
1925 ArrayList bases = (ArrayList) $1;
1926 bases.AddRange ((ArrayList) $2);
1932 : INHERITS type_list logical_end_of_line { $$ = $2; }
1936 : opt_interface_member_declarations
1939 opt_interface_member_declarations
1941 | interface_member_declarations
1944 interface_member_declarations
1945 : interface_member_declaration
1946 | interface_member_declarations interface_member_declaration
1949 interface_member_declaration
1953 current_attributes = (Attributes) $1;
1954 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
1956 interface_member_declarator
1962 interface_member_declarator
1963 : interface_method_declaration
1965 Method m = (Method) $1;
1966 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1968 | interface_property_declaration
1969 | interface_event_declaration
1972 interface_method_declaration
1973 : SUB identifier opt_params _mark_ logical_end_of_line
1975 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1976 (Parameters) $3, current_attributes, null, (Location)$4);
1980 | FUNCTION identifier opt_type_character opt_params _mark_ opt_type_with_ranks logical_end_of_line
1982 Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.
1983 system_object_expr : (Expression) $3 ) : (Expression) $6;
1985 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1986 (string) $2,(Parameters) $4, current_attributes, null,
1993 interface_property_declaration
1994 : PROPERTY identifier _mark_ opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1996 Expression ftype = ($6 == null) ? (($4 == null) ?
1997 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
1999 current_local_parameters = (Parameters) $5;
2000 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2001 get_parameters = current_local_parameters.Copy ((Location)$3);
2002 set_parameters = current_local_parameters.Copy ((Location)$3);
2004 Parameter implicit_value_parameter = new Parameter (
2005 ftype, "Value", Parameter.Modifier.NONE, null);
2007 set_parameters.AppendParameter (implicit_value_parameter);
2011 get_parameters = Parameters.EmptyReadOnlyParameters;
2012 set_parameters = new Parameters (null, null ,(Location)$3);
2014 Parameter implicit_value_parameter = new Parameter (
2015 ftype, "Value", Parameter.Modifier.NONE, null);
2017 set_parameters.AppendParameter (implicit_value_parameter);
2019 lexer.PropertyParsing = true;
2021 Accessor get_block = new Accessor (null, null);
2022 Accessor set_block = new Accessor (null, null);
2024 Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
2025 get_block, set_block, current_attributes, (Location)$3,
2026 null, get_parameters, set_parameters, null);
2028 CheckDef (current_interface.AddProperty (prop), prop.Name, (Location)$3);
2030 get_implicit_value_parameter_type = null;
2031 set_implicit_value_parameter_type = null;
2032 get_parameters = null;
2033 set_parameters = null;
2034 current_local_parameters = null;
2038 interface_event_declaration
2039 : EVENT identifier AS _mark_ type logical_end_of_line
2041 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $5, (Location)$4);
2043 Event e = new Event ((Expression) $5, var.identifier,
2044 null, current_modifiers,
2045 current_attributes, (Location)$4);
2047 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2050 | EVENT identifier opt_params _mark_ logical_end_of_line
2052 string delName = (string) $2;
2053 delName = delName + "EventHandler";
2054 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
2055 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
2056 (current_container, TypeManager.system_void_expr,
2057 (int) delModifiers, MakeName(delName), (Parameters) $3,
2058 (Attributes) current_attributes, (Location)$4);
2060 del.Namespace = current_namespace;
2061 CheckDef (current_interface.AddDelegate (del), del.Name, (Location)$4);
2063 Event e = new Event (DecomposeQI (delName, (Location)$4),
2065 null, current_modifiers,
2066 current_attributes, (Location)$4);
2068 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2072 property_declaration
2073 : abstract_propery_declaration
2074 | non_abstract_propery_declaration
2077 abstract_propery_declaration
2078 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters _mark_ opt_type_with_ranks logical_end_of_line
2080 Expression ftype = ($7 == null) ? (($4 == null) ?
2081 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $7;
2083 if (current_container is Module)
2084 Report.Error (30503, (Location) $6 , "Properties in a Module cannot be declared 'MustOverride'.");
2086 if (current_container is Struct)
2087 Report.Error (435, (Location) $6 ,"Methods in a Structure cannot be declared 'MustOverride'.");
2089 current_modifiers |= Modifiers.ABSTRACT;
2091 current_local_parameters = (Parameters) $5;
2092 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2093 get_parameters = current_local_parameters.Copy (lexer.Location);
2094 set_parameters = current_local_parameters.Copy (lexer.Location);
2096 Parameter implicit_value_parameter = new Parameter (
2097 ftype, "Value", Parameter.Modifier.NONE, null);
2099 set_parameters.AppendParameter (implicit_value_parameter);
2103 get_parameters = Parameters.EmptyReadOnlyParameters;
2104 set_parameters = new Parameters (null, null ,lexer.Location);
2106 Parameter implicit_value_parameter = new Parameter (
2107 ftype, "Value", Parameter.Modifier.NONE, null);
2109 set_parameters.AppendParameter (implicit_value_parameter);
2111 lexer.PropertyParsing = true;
2113 Accessor get_block = new Accessor (null, null);
2114 Accessor set_block = new Accessor (null, null);
2116 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
2117 get_block, set_block, current_attributes, lexer.Location,
2118 null, get_parameters, set_parameters, null);
2120 if (!(current_container is Class))
2121 Report.Error (9999, (Location) $6, "THIS SHOULD NEVER HAPPEN!");
2123 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
2125 get_implicit_value_parameter_type = null;
2126 set_implicit_value_parameter_type = null;
2127 get_parameters = null;
2128 set_parameters = null;
2129 current_local_parameters = null;
2134 non_abstract_propery_declaration
2135 : PROPERTY identifier
2137 opt_property_parameters
2140 opt_implement_clause
2142 push_into_stack((int)Start_block.PROPERTY, (Location)$5);
2143 if ((current_modifiers & Modifiers.DEFAULT) > 0) {
2144 if (current_container.DefaultPropName != null
2145 && current_container.DefaultPropName != (string) $2)
2146 Report.Error (30359,
2148 "Type '" + current_container.Name +
2149 "' cannot have more than one 'Default Property' ");
2151 current_container.DefaultPropName = (string) $2;
2154 get_implicit_value_parameter_type =
2155 ($6 == null) ? (($3 == null) ?
2156 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
2157 get_implicit_value_parameter_name = (string) $2;
2159 current_local_parameters = (Parameters) $4;
2160 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2161 get_parameters = current_local_parameters.Copy ((Location)$5);
2162 set_parameters = current_local_parameters.Copy ((Location)$5);
2166 get_parameters = Parameters.EmptyReadOnlyParameters;
2167 set_parameters = new Parameters (null, null ,(Location)$5);
2169 lexer.PropertyParsing = true;
2174 accessor_declarations
2177 pop_out_of_stack((int)$11,lexer.Location);
2181 lexer.PropertyParsing = false;
2184 Pair pair = (Pair) $10;
2186 Accessor get_block = null;
2187 Accessor set_block = null;
2189 if (pair.First != null){
2190 get_block = (Accessor) pair.First;
2193 if (pair.Second != null) {
2194 set_block = (Accessor) pair.Second;
2197 Location loc = (Location) $5 ;
2199 // Structure members are Public by default
2200 if ((current_container is Struct) && (current_modifiers == 0))
2201 current_modifiers = Modifiers.PUBLIC;
2203 prop = new Property ((Expression) get_implicit_value_parameter_type,
2204 (string) $2, current_modifiers, get_block, set_block,
2205 current_attributes, loc, set_implicit_value_parameter_name,
2206 get_parameters, set_parameters, (ArrayList) $7);
2208 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
2209 get_implicit_value_parameter_type = null;
2210 set_implicit_value_parameter_type = null;
2211 get_parameters = null;
2212 set_parameters = null;
2213 current_local_parameters = null;
2217 opt_property_parameters
2220 $$ = Parameters.EmptyReadOnlyParameters;
2222 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2228 opt_implement_clause
2233 | IMPLEMENTS implement_clause_list
2239 implement_clause_list
2240 : qualified_identifier
2242 ArrayList impl_list = new ArrayList ();
2243 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
2246 | implement_clause_list COMMA qualified_identifier
2248 ArrayList impl_list = (ArrayList) $1;
2249 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
2255 accessor_declarations
2256 : get_accessor_declaration opt_set_accessor_declaration
2258 $$ = new Pair ($1, $2);
2260 | set_accessor_declaration opt_get_accessor_declaration
2262 $$ = new Pair ($2, $1);
2266 opt_get_accessor_declaration
2267 : /* empty */ { $$ = null; }
2268 | get_accessor_declaration
2271 opt_set_accessor_declaration
2272 : /* empty */ { $$ = null; }
2273 | set_accessor_declaration
2276 get_accessor_declaration
2277 : opt_attributes GET _mark_ logical_end_of_line
2279 push_into_stack((int)Start_block.GET, (Location)$3);
2280 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
2281 Report.Error (30023, (Location)$3, "'WriteOnly' properties cannot have a 'Get' accessor");
2283 current_local_parameters = get_parameters;
2285 lexer.PropertyParsing = false;
2288 // Add local var declaration
2290 ArrayList retval = new ArrayList ();
2291 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, (Location)$3));
2292 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
2297 pop_out_of_stack((int)$7,lexer.Location);
2301 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2302 current_local_parameters = null;
2303 lexer.PropertyParsing = true;
2307 set_accessor_declaration
2308 : opt_attributes SET opt_set_parameter _mark_ logical_end_of_line
2310 push_into_stack((int)Start_block.SET, (Location)$4);
2311 if ((current_modifiers & Modifiers.READONLY) != 0)
2312 Report.Error (30022,
2314 "'ReadOnly' properties cannot have a 'Set' accessor");
2316 Parameter implicit_value_parameter = new Parameter (
2317 set_implicit_value_parameter_type,
2318 set_implicit_value_parameter_name,
2319 Parameter.Modifier.NONE, null);
2321 current_local_parameters = set_parameters;
2322 current_local_parameters.AppendParameter (implicit_value_parameter);
2325 lexer.PropertyParsing = false;
2330 pop_out_of_stack((int)$8,lexer.Location);
2335 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2336 current_local_parameters = null;
2337 lexer.PropertyParsing = true;
2344 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2345 set_implicit_value_parameter_name = "Value";
2347 |OPEN_PARENS CLOSE_PARENS
2349 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2350 set_implicit_value_parameter_name = "Value";
2352 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2354 Parameter.Modifier pm = (Parameter.Modifier)$2;
2355 if ((pm | Parameter.Modifier.VAL) != 0)
2356 Report.Error (31065,
2358 "Set cannot have a paremeter modifier other than 'ByVal'");
2360 set_implicit_value_parameter_type = (Expression) $4;
2362 if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
2363 Report.Error (31064,
2365 "Set value parameter type can not be different from property type");
2368 set_implicit_value_parameter_name = (string) $3;
2370 set_implicit_value_parameter_name = "Value";
2376 variable_declarators end_of_stmt
2378 int mod = (int) current_modifiers;
2380 VariableDeclaration.FixupTypes ((ArrayList) $2);
2381 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2383 if (current_container is Module)
2384 mod = mod | Modifiers.STATIC;
2386 // Structure members are Public by default
2387 if ((current_container is Struct) && (mod == 0))
2388 mod = Modifiers.PUBLIC;
2390 if ((mod & Modifiers.Accessibility) == 0)
2391 mod |= Modifiers.PRIVATE;
2393 foreach (VariableDeclaration var in (ArrayList) $2){
2394 Location l = var.Location;
2395 Field field = new Field (var.type, mod, var.identifier,
2396 var.expression_or_array_initializer,
2397 (Attributes) null, l);
2399 CheckDef (current_container.AddField (field), field.Name, l);
2404 withevents_declaration
2405 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2407 // Module members are static by default, but delegates *can't* be declared static
2408 // so we must fix it, if mbas was the one actually responsible for this
2409 // instead of triggering an error.
2410 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2411 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2413 /* WithEvents Fields must be resolved into properties
2414 with a bit of magic behind the scenes */
2416 VariableDeclaration.FixupTypes ((ArrayList) $3);
2418 foreach (VariableDeclaration var in (ArrayList) $3) {
2419 // 1 - We create a private field
2420 Location l = var.Location;
2422 if ((current_modifiers & Modifiers.STATIC) > 0)
2423 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2425 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2426 var.expression_or_array_initializer,
2427 (Attributes) null, l);
2429 CheckDef (current_container.AddField (field), field.Name, l);
2431 // 2 - Public property
2433 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2434 field, (int) current_modifiers,
2435 (Attributes) current_attributes, l);
2437 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2447 delegate_declaration
2448 : DELEGATE SUB _mark_
2449 identifier OPEN_PARENS
2450 opt_formal_parameter_list
2454 Location l = (Location)$3;
2455 // Module members are static by default, but delegates *can't* be declared static
2456 // so we must fix it, if mbas was the one actually responsible for this
2457 // instead of triggering an error.
2458 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2459 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2461 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2462 TypeManager.system_void_expr,
2463 (int) current_modifiers,
2464 MakeName ((string) $4), (Parameters) $6,
2465 (Attributes) current_attributes, l);
2467 del.Namespace = current_namespace;
2468 CheckDef (current_container.AddDelegate (del), del.Name, l);
2470 | DELEGATE FUNCTION _mark_
2471 identifier OPEN_PARENS
2472 opt_formal_parameter_list
2473 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2475 Location l = (Location)$3;
2477 // Module members are static by default, but delegates *can't* be declared static
2478 // so we must fix it, if mbas was the one actually responsible for this
2479 // instead of triggering an error.
2480 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2481 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2483 Expression ftype = ($8 == null) ? TypeManager.system_object_expr : (Expression) $8;
2485 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2487 ftype, (int) current_modifiers, MakeName ((string) $4),
2488 (Parameters) $6, (Attributes) current_attributes, l);
2490 del.Namespace = current_namespace;
2491 CheckDef (current_container.AddDelegate (del), del.Name, l);
2496 : /* empty */ { $$ = null; }
2497 | HANDLES evt_handler { $$ = $2; }
2501 : qualified_identifier _mark_
2503 $$ = (Expression) DecomposeQI ((string)$1, (Location)$2);
2509 | ME DOT qualified_identifier _mark_
2511 $$ = (Expression) DecomposeQI ((string)$3, (Location)$4);
2513 /*| MYBASE DOT qualified_identifier
2515 // FIXME: this is blatantly wrong and crash-prone
2516 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2520 constructor_declaration
2521 : SUB _mark_ NEW opt_params logical_end_of_line
2523 push_into_stack((int)Start_block.SUB, (Location)$2);
2524 current_local_parameters = (Parameters) $4;
2526 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, (Location)$2);
2531 Constructor c = (Constructor) $1;
2532 c.Block = (Block) end_block();
2533 c.ModFlags = (int) current_modifiers;
2534 c.OptAttributes = current_attributes;
2536 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2538 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2539 current_local_parameters = null;
2543 pop_out_of_stack((int)$9, lexer.Location);
2548 opt_formal_parameter_list
2551 $$ = Parameters.EmptyReadOnlyParameters;
2553 | formal_parameter_list
2556 //Parameter p = ((Parameters) $1).FixedParameters[0];
2560 formal_parameter_list
2563 ArrayList pars_list = (ArrayList) $1;
2564 Parameter [] pars = null;
2565 Parameter array_parameter = null;
2566 int non_array_count = pars_list.Count;
2567 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2568 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2569 non_array_count = pars_list.Count - 1;
2571 foreach (Parameter par in pars_list)
2572 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2573 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2574 non_array_count = 0;
2575 array_parameter = null;
2578 if (non_array_count > 0) {
2579 pars = new Parameter [non_array_count];
2580 pars_list.CopyTo (0, pars, 0, non_array_count);
2582 $$ = new Parameters (pars, array_parameter, lexer.Location);
2589 ArrayList pars = new ArrayList ();
2594 | parameters COMMA parameter
2596 ArrayList pars = (ArrayList) $1;
2605 opt_parameter_modifier
2606 identifier _mark_ opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2608 Parameter.Modifier pm = (Parameter.Modifier)$2;
2609 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2612 if (opt_parm && ($8 == null))
2613 Report.Error (30812, (Location)$4, "Optional parameters must have a default value");
2615 if (!opt_parm && ($8 != null))
2616 Report.Error (32024, (Location)$4, "Non-Optional parameters should not have a default value");
2618 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2619 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2620 Report.Error (30667, (Location)$4, "ParamArray parameters must be ByVal");
2623 if ((pm & Parameter.Modifier.REF) !=0)
2624 pm |= Parameter.Modifier.ISBYREF;
2626 if ($5 != null && $7 != null && $5 != $7)
2627 Report.Error (30302, (Location)$4, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2629 ptype = (Expression)(($7 == null) ? (($5 == null) ? TypeManager.system_object_expr : $5) : $7);
2631 string t = ptype.ToString ();
2632 if (t.IndexOf('[') >= 0)
2633 Report.Error (31087, (Location)$4, "Array types specified in too many places");
2635 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $6, true, (Location)$4), (Location)$4);
2637 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2638 Report.Error (30050, (Location)$4, "ParamArray parameters must be an array type");
2639 $$ = new Parameter (ptype, (string) $3, pm,
2640 (Attributes) $1, (Expression) $8, opt_parm);
2644 opt_parameter_modifier
2645 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2646 | parameter_modifiers { $$ = $1; }
2650 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2651 | parameter_modifier { $$ = $1; }
2655 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2656 | BYVAL { $$ = Parameter.Modifier.VAL; }
2657 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2658 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2663 | statement_list end_of_stmt
2668 | statement_list end_of_stmt
2673 : declaration_statement
2675 if ($1 != null && (Block) $1 != current_block){
2676 current_block.AddStatement ((Statement) $1);
2677 current_block = (Block) $1;
2680 | embedded_statement
2682 current_block.AddStatement ((Statement) $1);
2685 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2687 AddHandler ((Expression) $2, (Expression) $5);
2689 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2691 RemoveHandler ((Expression) $2, (Expression) $5);
2693 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2695 RaiseEvent ((string) $2, (ArrayList) $3);
2697 /* | array_handling_statement */
2698 /* | empty_statement */
2701 current_block.AddStatement ((Statement) $1);
2706 : END_EOL {$$ = new End (lexer.Location);}
2710 opt_raise_event_args
2711 : /* empty */ { $$ = null; }
2712 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2729 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2731 if (!current_block.AddLabel ((string) $1, labeled)){
2732 Location l = lexer.Location;
2733 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2735 current_block.AddStatement (labeled);
2739 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2741 if (!current_block.AddLabel ((string) $1, labeled)){
2742 Location l = lexer.Location;
2743 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2745 current_block.AddStatement (labeled);
2751 : expression_statement
2752 | selection_statement
2753 | iteration_statement
2755 | synclock_statement
2757 | array_handling_statement
2763 $$ = new EmptyStatement ();
2769 : WITH _mark_ expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2771 // was : Expression e = DecomposeQI ((string) $3, (Location)$2);
2772 push_into_stack((int)Start_block.WITH, (Location)$2);
2773 Expression e = (Expression) $3;
2780 pop_out_of_stack((int)$7,lexer.Location);
2781 Block b = end_block();
2788 array_handling_statement
2794 : REDIM opt_preserve redim_clauses
2796 ArrayList list = (ArrayList) $3;
2797 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2804 : /* empty */ { $$ = false; }
2805 | PRESERVE { $$ = true; }
2811 ArrayList clauses = new ArrayList ();
2816 | redim_clauses COMMA redim_clause
2818 ArrayList clauses = (ArrayList) ($1);
2826 : invocation_expression
2828 Invocation i = (Invocation) $1;
2829 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2835 : ERASE erase_clauses
2837 ArrayList list = (ArrayList) $2;
2838 foreach(Expression e in list)
2840 Erase r = new Erase (e, lexer.Location);
2849 ArrayList clauses = new ArrayList ();
2854 | erase_clauses COMMA erase_clause
2856 ArrayList clauses = (ArrayList) ($1);
2864 : primary_expression
2869 | continue_statement
2870 | */return_statement
2881 $$ = new Goto (current_block, (string) $2, lexer.Location);
2886 : THROW _mark_ opt_expression
2888 $$ = new Throw ((Expression) $3, (Location)$2);
2895 $$ = new Exit ((ExitType)$2, lexer.Location);
2900 : DO { $$ = ExitType.DO; }
2901 | FOR { $$ = ExitType.FOR; }
2902 | WHILE { $$ = ExitType.WHILE; }
2903 | SELECT { $$ = ExitType.SELECT; }
2904 | SUB { $$ = ExitType.SUB; }
2905 | FUNCTION { $$ = ExitType.FUNCTION; }
2906 | PROPERTY { $$ = ExitType.PROPERTY; }
2907 | TRY { $$ = ExitType.TRY; }
2910 : RETURN opt_expression
2912 $$ = new Return ((Expression) $2, lexer.Location);
2924 : FOR EACH identifier _mark_ opt_type_spec IN
2925 expression end_of_stmt
2927 Location l = (Location)$4;
2928 push_into_stack((int)Start_block.FOR, l);
2929 LocalVariableReference v = null;
2935 VariableDeclaration decl = new VariableDeclaration ((string) $3,
2936 (Expression) $5, null, (Location)$4, null);
2938 vi = current_block.AddVariable (
2939 (Expression) $5, decl.identifier, current_local_parameters, decl.Location);
2942 if (decl.expression_or_array_initializer is Expression)
2943 expr = (Expression) decl.expression_or_array_initializer;
2944 else if (decl.expression_or_array_initializer == null)
2948 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
2949 expr = new ArrayCreation ((Expression) $5, "", init, decl.Location);
2952 v = new LocalVariableReference (current_block, decl.identifier, l);
2956 Assign a = new Assign (v, expr, decl.Location);
2957 current_block.AddStatement (new StatementExpression (a, (Location)$4));
2962 vi = current_block.GetVariableInfo ((string) $3);
2965 // Get a reference to this variable.
2966 v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
2969 Report.Error (451, (Location)$4,"Name '" + (string) $3 + "' is not declared.");
2978 pop_out_of_stack((int)$11,lexer.Location);
2980 _mark_ opt_identifier
2982 string s = $3.ToString();
2985 s1 = $14.ToString();
2986 if (s1 != "" && s != s1)
2988 Report.Error(30070, (Location)$13, "Next Control Variable '"+s1+"' does not match with For Loop control variable '"+s+"'");
2990 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2991 Block foreach_block = end_block();
2995 f = new Foreach (null, v, (Expression) $7, foreach_block, (Location)$4);
2999 current_block.AddStatement (f);
3008 : YIELD expression _mark_
3010 if (!UseExtendedSyntax)
3016 if (iterator_container == null){
3017 Report.Error (204, (Location)$3, "yield statement can only be used within a method, operator or property");
3020 iterator_container.SetYields ();
3021 $$ = new Yield ((Expression) $2, (Location)$3);
3026 if (!UseExtendedSyntax)
3032 if (iterator_container == null){
3033 Report.Error (204, (Location)$3, "yield statement can only be used within a method, operator or property");
3036 iterator_container.SetYields ();
3037 $$ = new YieldBreak ((Location)$3);
3043 : SYNCLOCK _mark_ expression end_of_stmt
3045 push_into_stack((int)Start_block.SYNCLOCK, (Location)$2);
3051 pop_out_of_stack((int)$7,lexer.Location);
3052 $$ = new Lock ((Expression) $3, (Statement) (Block) end_block(), (Location)$2);
3062 : TRY _mark_ end_of_stmt
3064 push_into_stack((int)Start_block.TRY, (Location)$2);
3065 try_top=(Location)$2;
3071 tmp_catch_clauses = (ArrayList) $6;
3076 /*FIXME: Try block without a end try is throwing error at a wrong place*/
3079 _mark_ opt_end_block
3081 pop_out_of_stack((int)$3,lexer.Location);
3083 ArrayList s = new ArrayList ();
3085 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
3092 // Now s contains the list of specific catch clauses
3093 // and g contains the general one.
3094 Block b = end_block();
3096 $$ = new Try ((Block) b, s, g, null, try_top);
3103 tmp_block = end_block();
3110 _mark_ opt_end_block
3112 pop_out_of_stack((int)$8,lexer.Location);
3114 ArrayList s = new ArrayList ();
3115 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
3117 if (catch_list != null){
3118 foreach (Catch cc in catch_list) {
3126 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), try_top);
3132 : /* empty */ { $$ = null; }
3139 ArrayList l = new ArrayList ();
3144 | catch_clauses catch_clause
3146 ArrayList l = (ArrayList) $1;
3154 : /* empty */ { $$ = null; }
3159 : /* empty */ { $$ = null; }
3160 | WHEN boolean_expression
3167 : CATCH opt_catch_args opt_when _mark_ end_of_stmt
3169 Expression type = null;
3173 DictionaryEntry cc = (DictionaryEntry) $2;
3174 type = (Expression) cc.Key;
3175 id = (string) cc.Value;
3178 ArrayList one = new ArrayList ();
3179 Location loc = (Location)$4;
3181 one.Add (new VariableDeclaration (id, type, loc));
3184 current_block = new Block (current_block);
3185 Block b = declare_local_variables (type, one, loc);
3190 opt_statement_list {
3191 Expression type = null;
3193 Block b_catch = current_block;
3196 DictionaryEntry cc = (DictionaryEntry) $2;
3197 type = (Expression) cc.Key;
3198 id = (string) cc.Value;
3202 // FIXME: I can change this for an assignment.
3204 while (current_block != (Block) $1)
3205 current_block = current_block.Parent;
3208 $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, (Location)$4);
3213 : /* empty */ { $$ = null; }
3218 : identifier AS _mark_ type
3220 $$ = new DictionaryEntry ($4, $1);
3222 | error _mark_ AS type
3224 Report.Error(30203, (Location)$2, "Identifier Expected");
3227 | identifier AS _mark_ error
3229 Report.Error(30182, (Location)$3, "Type Expected");
3236 : DO _mark_ opt_do_construct end_of_stmt
3238 push_into_stack((int)Start_block.DO, (Location)$2);
3244 pop_out_of_stack((int)$7,lexer.Location);
3246 _mark_ opt_do_construct
3248 Expression t_before = (Expression) $3;
3249 Expression t_after = (Expression) $10;
3252 if ((t_before != null) && (t_after != null))
3253 Report.Error (30238, (Location)$9, "'Loop' cannot have a condition if matching 'Do' has one.");
3255 if ((t_before == null) && (t_after == null))
3256 t = new BoolLiteral (true);
3258 t = (t_before != null) ? t_before : t_after;
3260 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
3262 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
3263 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
3264 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, (Location)$2);
3266 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, (Location)$2);
3271 : /* empty */ { $$ = null; }
3272 | while_or_until boolean_expression
3274 do_type = (DoOptions)$1;
3275 $$ = (Expression) $2;
3280 : WHILE { $$ = DoOptions.WHILE; }
3281 | UNTIL { $$ = DoOptions.UNTIL; }
3287 push_into_stack((int)Start_block.WHILE, lexer.Location);
3289 oob_stack.Push (lexer.Location);
3291 boolean_expression end_of_stmt
3295 Location l = (Location) oob_stack.Pop ();
3296 pop_out_of_stack((int)$6,lexer.Location);
3297 Block b = end_block();
3298 Expression e = (Expression) $3;
3299 $$ = new While ((Expression) e, (Statement) b, l);
3304 : FOR _mark_ identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
3306 push_into_stack((int)Start_block.FOR, (Location)$2);
3310 ArrayList VarDeclaration = new ArrayList ();
3311 VarDeclaration.Add (new VariableDeclaration ((string) $3,
3312 (Expression) $4, null, (Location)$2, null));
3314 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), VarDeclaration);
3315 Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location)$2);
3323 pop_out_of_stack((int)$13,lexer.Location);
3325 _mark_ opt_identifier
3327 string s = $3.ToString();
3330 s1 = $16.ToString();
3331 if (s1 != "" && s != s1)
3333 Report.Error(30070, (Location)$15, "Next Control Variable '"+s1+"' does not match with For Loop control variable '"+s+"'");
3336 Block inner_statement = end_block();
3337 Location l = (Location)$2;
3338 Expression for_var = (Expression) DecomposeQI ((string)$3, l);
3340 Expression assign_expr = new Assign (for_var, (Expression) $6, l);
3341 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
3342 for_var, (Expression) $8, l);
3343 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
3344 for_var, (Expression) $9, l), l);
3346 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
3347 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
3349 For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
3352 current_block.AddStatement (f);
3361 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
3362 | STEP expression { $$ = $2; }
3371 : if_statement_open opt_then end_of_stmt opt_statement_list
3373 push_into_stack((int)Start_block.IF, (Location)$1);
3379 | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
3383 Location l = (Location) oob_stack.Pop ();
3384 tmp_expr = (Expression)expr_stack.Pop();
3385 $$ = new If ((Expression) tmp_expr, end_block(), l);
3389 Location l = (Location) oob_stack.Pop ();
3390 tmp_expr = (Expression)expr_stack.Pop();
3391 tmp_block = (Block) tmp_blocks.Pop ();
3392 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3395 | if_statement_open THEN else_pre_embedded_statement
3397 Location l = (Location) oob_stack.Pop ();
3398 tmp_expr = (Expression)expr_stack.Pop();
3399 tmp_block = (Block) tmp_blocks.Pop ();
3400 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3404 pre_embedded_statement
3405 : embedded_statement
3407 current_block.AddStatement ((Statement) $1);
3411 opt_else_pre_embedded_statement
3413 | else_pre_embedded_statement
3416 else_pre_embedded_statement
3419 Block bl = end_block();
3420 tmp_blocks.Push(bl);
3424 | ELSE embedded_statement
3426 Block bl = end_block();
3427 tmp_blocks.Push(bl);
3430 current_block.AddStatement ((Statement) $2);
3434 /*FIXME:if without end if not working. Error line shown is nor correct*/
3438 oob_stack.Push (lexer.Location);
3443 tmp_expr = (Expression) $4;
3444 expr_stack.Push(tmp_expr);
3458 Location l = (Location) oob_stack.Pop ();
3459 pop_out_of_stack((int)$1,lexer.Location);
3460 Expression expr = (Expression)expr_stack.Pop();
3461 $$ = new If ((Expression) expr, (Statement) end_block(), l);
3466 Block bl = end_block();
3467 tmp_blocks.Push(bl);
3473 Location l = (Location) oob_stack.Pop ();
3474 pop_out_of_stack((int)$5,lexer.Location);
3475 tmp_expr = (Expression)expr_stack.Pop();
3476 tmp_block = (Block) tmp_blocks.Pop();
3477 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
3480 opt_elseif boolean_expression opt_then
3482 tmp_expr = (Expression) $2;
3483 expr_stack.Push(tmp_expr);
3484 tmp_block = end_block();
3485 tmp_blocks.Push(tmp_block);
3488 end_of_stmt opt_statement_list
3489 else_if_statement_rest
3491 Statement stmt = (Statement) statement_stack.Pop();
3492 Block bl = (Block) tmp_blocks.Pop();
3493 Expression expr = (Expression)expr_stack.Pop();
3494 Location l = (Location) oob_stack.Pop ();
3495 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3500 else_if_statement_rest
3504 Block bl = end_block();
3505 tmp_blocks.Push(bl);
3511 Location l = (Location) oob_stack.Pop ();
3512 pop_out_of_stack((int)$5,lexer.Location);
3514 Expression expr = (Expression)expr_stack.Pop();
3515 Block bl = (Block)tmp_blocks.Pop();
3516 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3517 statement_stack.Push(stmt);
3520 opt_elseif boolean_expression opt_then
3522 expr_stack.Push((Expression) $2);
3523 Block bl = end_block();
3524 tmp_blocks.Push(bl);
3527 end_of_stmt opt_statement_list
3528 else_if_statement_rest
3530 Location l = (Location) oob_stack.Pop ();
3532 Statement tmp_stmt = (Statement)statement_stack.Pop();
3533 Block bl = (Block) tmp_blocks.Pop();
3534 Expression expr = (Expression)expr_stack.Pop();
3535 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3536 statement_stack.Push(stmt);
3541 Location l = (Location) oob_stack.Pop ();
3542 pop_out_of_stack((int)$1,lexer.Location);
3544 Expression expr = (Expression)expr_stack.Pop();
3545 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3546 statement_stack.Push(stmt);
3550 /*FIXME:Select without an expression is showing a parser error instead of a expression missing error*/
3553 _mark_ opt_case expression end_of_stmt
3555 push_into_stack((int)Start_block.SELECT, (Location)$2);
3556 oob_stack.Push (lexer.Location);
3557 switch_stack.Push (current_block);
3562 pop_out_of_stack((int)$8,lexer.Location);
3563 current_block = (Block) switch_stack.Pop ();
3564 $$ = new Switch ((Expression) $4, (ArrayList) $7, (Location) oob_stack.Pop ());
3569 : /* empty */ { $$ = null; }
3570 | case_sections { $$ = $1; }
3574 : case_sections case_section
3576 ArrayList sections = (ArrayList) $1;
3583 ArrayList sections = new ArrayList ();
3597 : CASE case_clauses ends
3603 //Block topmost = current_block;
3604 Block topmost = end_block();
3606 while (topmost.Implicit)
3607 topmost = topmost.Parent;
3609 // FIXME: This is a horrible hack which MUST go
3610 topmost.statements.Add (new Break (lexer.Location));
3611 $$ = new SwitchSection ((ArrayList) $2, topmost);
3614 /* FIXME: we should somehow flag an error
3615 (BC30321 'Case' cannot follow a 'Case Else'
3616 in the same 'Select' statement.)
3617 if Case Else is not the last of the Case clauses
3624 //Block topmost = current_block;
3625 Block topmost = end_block();
3627 while (topmost.Implicit)
3628 topmost = topmost.Parent;
3630 // FIXME: This is a horrible hack which MUST go
3631 topmost.statements.Add (new Break (lexer.Location));
3633 ArrayList a = new ArrayList();
3634 a.Add (new SwitchLabel (null, lexer.Location));
3635 $$ = new SwitchSection ((ArrayList) a, topmost);
3642 if ($1 is ArrayList) //From expression TO expression
3646 ArrayList labels = new ArrayList ();
3652 | case_clauses COMMA case_clause
3654 ArrayList labels = (ArrayList) ($1);
3662 : opt_is comparison_operator expression
3665 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3667 | expression TO expression
3669 //FIXME: need to handle when expressions are character strings.
3670 Constant start = (Constant) $1;
3671 Constant end = (Constant) $3;
3672 int i = 0, s = 0, e = 0;
3673 Location l = lexer.Location ;
3674 ArrayList labels = new ArrayList ();
3677 s = (int) start.GetValue ();
3679 e = (int) end.GetValue ();
3680 for(i = s; i <= e; i++) {
3681 labels.Add(new SwitchLabel ((Expression)new IntLiteral(i), l));
3706 expression_statement
3707 : statement_expression
3714 statement_expression
3715 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3716 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3717 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3720 object_creation_expression
3721 : NEW type OPEN_PARENS _mark_ opt_argument_list CLOSE_PARENS
3723 $$ = new New ((Expression) $2, (ArrayList) $5, (Location)$4);
3727 $$ = new New ((Expression) $2, new ArrayList(), (Location)$3);
3731 array_creation_expression
3732 : object_creation_expression opt_rank_specifiers _mark_ array_initializer
3735 ArrayList dims = new ArrayList();
3737 if (n.Arguments != null) {
3738 foreach (Argument a in n.Arguments) {
3743 Expression atype = n.RequestedType;
3746 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, (Location)$3), (Location)$3);
3748 ArrayList init = (ArrayList) $4;
3749 if (init.Count == 0)
3752 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3753 VariableDeclaration.VBFixIndexList (ref dims);
3754 $$ = new ArrayCreation (atype, dims, "", init, (Location)$3);
3758 string rank = VariableDeclaration.BuildRank (dims);
3759 $$ = new ArrayCreation (atype, rank, (ArrayList) $4, (Location)$3);
3761 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3766 : object_creation_expression
3767 | array_creation_expression
3770 declaration_statement
3771 : _mark_ local_variable_declaration
3774 DictionaryEntry de = (DictionaryEntry) $2;
3776 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location)$1);
3779 | local_constant_declaration
3782 DictionaryEntry de = (DictionaryEntry) $1;
3784 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3789 local_variable_declaration
3790 : DIM _mark_ variable_declarators
3792 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), $3);
3797 local_constant_declaration
3798 : CONST constant_declarators
3801 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3807 constant_declarators
3808 : constant_declarator
3810 ArrayList decl = new ArrayList ();
3816 | constant_declarators COMMA constant_declarator
3818 ArrayList decls = (ArrayList) $1;
3827 : _mark_ variable_name opt_type_decl opt_variable_initializer
3829 VarName vname = (VarName) $2;
3830 string varname = (string) vname.Name;
3831 current_rank_specifiers = (ArrayList) vname.Rank;
3832 object varinit = $4;
3834 if (varinit == null)
3836 30438, (Location)$1, "Constant should have a value"
3839 if (vname.Type != null && $3 != null)
3841 30302, (Location)$1,
3842 "Type character cannot be used with explicit type declaration" );
3844 Expression vartype = ($3 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $3;
3846 if (current_rank_specifiers != null)
3848 Report.Error (30424, (Location)$1, "Constant doesn't support array");
3852 $$ = new VariableDeclaration (varname, vartype, varinit, (Location)$1, null);
3856 variable_declarators
3857 : variable_declarator
3859 ArrayList decl = new ArrayList ();
3860 decl.AddRange ((ArrayList) $1);
3863 | variable_declarators COMMA variable_declarator
3865 ArrayList decls = (ArrayList) $1;
3866 decls.AddRange ((ArrayList) $3);
3872 : _mark_ variable_names opt_type_decl opt_variable_initializer
3874 ArrayList names = (ArrayList) $2;
3875 object varinit = $4;
3876 ArrayList VarDeclarations = new ArrayList();
3878 ArrayList a_dims = null;
3880 if ((names.Count > 1) && (varinit != null))
3882 30671, (Location)$1,
3883 "Multiple variables with single type can not have " +
3884 "a explicit initialization" );
3887 foreach (VarName vname in names)
3889 string varname = (string) vname.Name;
3890 current_rank_specifiers = (ArrayList) vname.Rank;
3894 if(vname.Type != null && $3 != null)
3896 30302, (Location)$1,
3897 "Type character cannot be used with explicit type declaration" );
3899 // Some checking is required for particularly weird declarations
3900 // like Dim a As Integer(,)
3902 vartype = (Expression) ((Pair) $3).First;
3904 /*if ($4 != null && $4 is ArrayList)
3905 Report.Error (205, "End of statement expected.");*/
3907 ArrayList args = (ArrayList) ((Pair) $3).Second;
3908 if (current_rank_specifiers != null)
3909 Report.Error (31087, (Location)$1,
3910 "Array types specified in too many places");
3912 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3913 Report.Error (30638, (Location)$1,"Array bounds cannot appear in type specifiers.");
3915 current_rank_specifiers = new ArrayList ();
3916 current_rank_specifiers.Add (args);
3919 vartype = ($3 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $3;
3921 // if the variable is an array with explicit bound
3922 // and having explicit initialization throw exception
3923 if (current_rank_specifiers != null && varinit != null)
3925 bool broken = false;
3926 foreach (ArrayList exprs in current_rank_specifiers)
3928 foreach (Expression expr in exprs)
3930 if (!((Expression)expr is EmptyExpression ))
3933 30672, (Location)$1,
3934 "Array declared with explicit bound " +
3935 " can not have explicit initialization");
3946 Check for a declaration like Dim a(2) or Dim a(2,3)
3947 If this is the case, we must generate an ArrayCreationExpression
3948 and, in case, add the initializer after the array has been created.
3950 if (VariableDeclaration.IsArrayDecl (this)) {
3951 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3952 a_dims = (ArrayList) current_rank_specifiers;
3953 VariableDeclaration.VBFixIndexLists (ref a_dims);
3954 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, (Location)$1);
3956 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, (Location)$1), (Location)$1);
3959 if (vartype is New) {
3960 if (varinit != null) {
3961 Report.Error (30205, (Location)$1, "End of statement expected");
3967 vartype = ((New)vartype).RequestedType;
3970 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, (Location)$1, null));
3972 $$ = VarDeclarations;
3979 ArrayList list = new ArrayList ();
3983 | variable_names COMMA variable_name
3985 ArrayList list = (ArrayList) $1;
3992 : identifier opt_type_character opt_array_name_modifier
3994 $$ = new VarName ($1, $2, $3);
4005 $$ = (Expression) $2;
4011 | AS type _mark_ rank_specifiers
4013 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$4, true, (Location)$3), (Location)$3);
4018 : opt_type_with_ranks
4024 New n = new New ((Expression)$3, null, lexer.Location);
4025 $$ = (Expression) n;
4027 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
4029 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
4030 $$ = (Expression) n;
4032 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
4034 ArrayList args = new ArrayList();
4035 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
4038 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
4039 $$ = (Expression) n;
4043 opt_array_name_modifier
4044 : /* empty */ { $$ = null; }
4045 | array_type_modifier { $$ = $1; }
4049 : rank_specifiers { $$ = $1; }
4052 opt_variable_initializer
4053 : /* empty */ { $$ = null; }
4054 | ASSIGN variable_initializer { $$ = $2; }
4057 variable_initializer
4070 : OPEN_BRACE CLOSE_BRACE
4072 ArrayList list = new ArrayList ();
4075 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
4077 $$ = (ArrayList) $2;
4081 variable_initializer_list
4082 : variable_initializer
4084 ArrayList list = new ArrayList ();
4088 | variable_initializer_list COMMA variable_initializer
4090 ArrayList list = (ArrayList) $1;
4111 ArrayList rs = new ArrayList();
4115 | rank_specifiers rank_specifier
4117 ArrayList rs = (ArrayList) $1;
4124 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
4133 ArrayList ds = new ArrayList();
4134 ds.Add (new EmptyExpression());
4139 ArrayList ds = new ArrayList();
4140 ds.Add ((Expression) $1);
4143 | opt_dim_specifiers COMMA expression
4145 ArrayList ds = (ArrayList) $1;
4146 ds.Add ((Expression) $3);
4149 | opt_dim_specifiers COMMA
4151 ArrayList ds = (ArrayList) $1;
4152 ds.Add (new EmptyExpression());
4162 | parenthesized_expression
4165 | qualified_identifier _mark_
4167 string name = (string) $1;
4168 $$ = DecomposeQI (name, (Location)$2);
4170 | get_type_expression
4172 | invocation_expression
4177 { Report.Error(30201,(Location)$2,"Expression expected"); $$ = (Expression)null;}
4184 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
4185 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
4186 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
4187 | NOTHING { $$ = NullLiteral.Null; }
4191 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
4192 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
4193 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
4198 object v = lexer.Value;
4201 $$ = new IntLiteral ((Int32)v);
4202 else if (v is short)
4203 $$ = new ShortLiteral ((Int16)v);
4205 $$ = new LongLiteral ((Int64)v);
4207 Console.WriteLine ("Unexpected result from scanner");
4213 : TRUE { $$ = new BoolLiteral (true); }
4214 | FALSE { $$ = new BoolLiteral (false); }
4217 parenthesized_expression
4218 : OPEN_PARENS expression CLOSE_PARENS
4223 : primary_expression DOT _mark_ identifier
4226 string id_name = (string)$4;
4227 if (id_name.ToUpper() == "NEW")
4229 $$ = new MemberAccess ((Expression) $1, id_name, (Location)$3);
4233 if (with_stack.Count > 0) {
4234 Expression e = (Expression) with_stack.Peek();
4235 $$ = new MemberAccess (e, (string) $4, (Location)$3);
4243 /* | primary_expression DOT _mark_ NEW
4245 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", (Location)$3);
4247 | predefined_type DOT _mark_ identifier
4250 $$ = new MemberAccess ((Expression) $1, (string) $4, (Location)$3);
4253 if (with_stack.Count > 0) {
4254 Expression e = (Expression) with_stack.Peek();
4255 $$ = new MemberAccess (e, (string) $4, (Location)$3);
4269 invocation_expression
4270 // To support Mid$()
4271 : primary_expression opt_dolar_sign OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
4274 Location l = (Location)$5;
4275 Report.Error (1, l, "THIS IS CRAZY");
4277 $$ = new Invocation ((Expression) $1, (ArrayList) $4, (Location)$5);
4278 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($4 != null) ? ((ArrayList) $4).Count : 0);
4280 | CALL primary_expression OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
4283 Location l = (Location)$5;
4284 Report.Error (1, l, "THIS IS CRAZY");
4286 $$ = new Invocation ((Expression) $2, (ArrayList) $3, (Location)$5);
4287 // Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
4289 | primary_expression EXCLAMATION _mark_ identifier // FIXME : This should be identifier-or-keyword
4292 Location l = (Location)$3;
4293 Report.Error (1, l, "THIS IS CRAZY");
4296 ArrayList args = new ArrayList ();
4297 Expression etmp = new StringLiteral ((string)$4);
4299 args.Add (new Argument (etmp, Argument.AType.Expression));
4300 $$ = new Invocation ((Expression) $1, args, (Location)$3);
4310 : MYBASE DOT IDENTIFIER
4312 string id_name = (string) $3;
4313 if (id_name.ToUpper() == "NEW")
4315 $$ = new BaseAccess (id_name, lexer.Location);
4319 $$ = new BaseAccess ("New", lexer.Location);
4327 The 'argument' rule returns an 'empty' argument
4328 of type NoArg (used for default arguments in invocations)
4329 if no arguments are actually passed.
4331 If there is only one argument and it is o type NoArg,
4332 we return a null (empty) list
4334 ArrayList args = (ArrayList) $1;
4335 if (args.Count == 1 &&
4336 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
4346 ArrayList list = new ArrayList ();
4350 | argument_list COMMA argument
4352 ArrayList list = (ArrayList) $1;
4361 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
4363 | BYREF variable_reference
4365 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
4369 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
4371 | ADDRESSOF expression
4373 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
4378 : expression {/* note ("section 5.4"); */ $$ = $1; }
4383 : conditional_xor_expression { $$ = $1; }
4384 /*| assignment_expression*/
4395 $$ = new This (current_block, lexer.Location);
4399 $$ = new This (This.TypeOfAccess.MyClass, current_block, lexer.Location);
4404 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
4408 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
4410 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
4412 | cast_operator OPEN_PARENS expression CLOSE_PARENS
4414 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
4419 : CBOOL { $$ = TypeManager.system_boolean_expr; }
4420 | CBYTE { $$ = TypeManager.system_byte_expr; }
4421 | CCHAR { $$ = TypeManager.system_char_expr; }
4422 | CDATE { $$ = TypeManager.system_date_expr; }
4423 | CDBL { $$ = TypeManager.system_double_expr; }
4424 | CDEC { $$ = TypeManager.system_decimal_expr; }
4425 | CINT { $$ = TypeManager.system_int32_expr; }
4426 | CLNG { $$ = TypeManager.system_int64_expr; }
4427 | COBJ { $$ = TypeManager.system_object_expr; }
4428 | CSHORT { $$ = TypeManager.system_int16_expr; }
4429 | CSNG { $$ = TypeManager.system_single_expr; }
4430 | CSTR { $$ = TypeManager.system_string_expr; }
4434 : GETTYPE OPEN_PARENS _mark_ type CLOSE_PARENS
4436 $$ = new TypeOf ((Expression) $4, (Location)$3);
4440 exponentiation_expression
4441 : prefixed_unary_expression
4442 | exponentiation_expression OP_EXP _mark_ primary_expression
4444 $$ = new Binary (Binary.Operator.Exponentiation,
4445 (Expression) $1, (Expression) $4, (Location)$3);
4449 prefixed_unary_expression
4450 : primary_expression
4451 | PLUS _mark_ prefixed_unary_expression
4453 //FIXME: Is this rule correctly defined ?
4454 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $3, (Location)$2);
4456 | MINUS _mark_ prefixed_unary_expression
4458 //FIXME: Is this rule correctly defined ?
4459 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $3, (Location)$2);
4463 multiplicative_expression
4464 : exponentiation_expression
4465 | multiplicative_expression STAR _mark_ prefixed_unary_expression
4467 $$ = new Binary (Binary.Operator.Multiply,
4468 (Expression) $1, (Expression) $4, (Location)$3);
4470 | multiplicative_expression DIV _mark_ prefixed_unary_expression
4472 $$ = new Binary (Binary.Operator.Division,
4473 (Expression) $1, (Expression) $4, (Location)$3);
4477 integer_division_expression
4478 : multiplicative_expression
4479 | integer_division_expression OP_IDIV _mark_ multiplicative_expression
4481 //FIXME: Is this right ?
4482 $$ = new Binary (Binary.Operator.IntDivision,
4483 (Expression) $1, (Expression) $4, (Location)$3);
4488 : integer_division_expression
4489 | mod_expression MOD _mark_ integer_division_expression
4491 $$ = new Binary (Binary.Operator.Modulus,
4492 (Expression) $1, (Expression) $4, (Location)$3);
4498 | additive_expression PLUS _mark_ mod_expression
4500 $$ = new Binary (Binary.Operator.Addition,
4501 (Expression) $1, (Expression) $4, (Location)$3);
4503 | additive_expression MINUS _mark_ mod_expression
4505 $$ = new Binary (Binary.Operator.Subtraction,
4506 (Expression) $1, (Expression) $4, (Location)$3);
4511 : additive_expression
4512 | concat_expression OP_CONCAT _mark_ additive_expression
4514 // FIXME: This should only work for String expressions
4515 // We probably need to use something from the runtime
4516 $$ = new StringConcat((Location)$3,
4517 (Expression) $1, (Expression) $4);
4524 | shift_expression OP_SHIFT_LEFT _mark_ concat_expression
4526 $$ = new Binary(Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, (Location)$3);
4528 | shift_expression OP_SHIFT_RIGHT _mark_ concat_expression
4530 $$ = new Binary(Binary.Operator.RightShift, (Expression) $1, (Expression) $4, (Location)$3);
4534 relational_expression
4536 | relational_expression LIKE _mark_ shift_expression
4538 $$ = new Binary (Binary.Operator.Like,
4539 (Expression) $1, (Expression) $4, (Location)$3);
4541 | relational_expression ASSIGN _mark_ shift_expression
4543 $$ = new Binary (Binary.Operator.Equality,
4544 (Expression) $1, (Expression) $4, (Location)$3);
4546 | relational_expression OP_NE _mark_ shift_expression
4548 $$ = new Binary (Binary.Operator.Inequality,
4549 (Expression) $1, (Expression) $4, (Location)$3);
4551 | relational_expression OP_LT _mark_ shift_expression
4553 $$ = new Binary (Binary.Operator.LessThan,
4554 (Expression) $1, (Expression) $4, (Location)$3);
4556 | relational_expression OP_GT _mark_ shift_expression
4558 $$ = new Binary (Binary.Operator.GreaterThan,
4559 (Expression) $1, (Expression) $4, (Location)$3);
4561 | relational_expression OP_LE _mark_ shift_expression
4563 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4564 (Expression) $1, (Expression) $4, (Location)$3);
4566 | relational_expression OP_GE _mark_ shift_expression
4568 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4569 (Expression) $1, (Expression) $4, (Location)$3);
4571 | relational_expression IS _mark_ shift_expression
4573 $$ = new Binary (Binary.Operator.Is,
4574 (Expression) $1, (Expression) $4, (Location)$3);
4576 | TYPEOF shift_expression _mark_ IS type
4578 //FIXME: Is this rule correctly defined ?
4579 $$ = new Is ((Expression) $2, (Expression) $5, (Location)$3);
4584 : relational_expression
4585 | NOT _mark_ negation_expression
4587 //FIXME: Is this rule correctly defined ?
4588 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $3, (Location)$2);
4592 conditional_and_expression
4593 : negation_expression
4594 | conditional_and_expression AND _mark_ negation_expression
4596 $$ = new Binary (Binary.Operator.BitwiseAnd,
4597 (Expression) $1, (Expression) $4, (Location)$3);
4599 | conditional_and_expression ANDALSO _mark_ negation_expression
4600 { // FIXME: this is likely to be broken
4601 $$ = new Binary (Binary.Operator.LogicalAnd,
4602 (Expression) $1, (Expression) $4, (Location)$3);
4606 conditional_or_expression
4607 : conditional_and_expression
4608 | conditional_or_expression OR _mark_ conditional_and_expression
4610 $$ = new Binary (Binary.Operator.BitwiseOr,
4611 (Expression) $1, (Expression) $4, (Location)$3);
4613 | conditional_or_expression ORELSE _mark_ conditional_and_expression
4614 { // FIXME: this is likely to be broken
4615 $$ = new Binary (Binary.Operator.LogicalOr,
4616 (Expression) $1, (Expression) $4, (Location)$3);
4620 conditional_xor_expression
4621 : conditional_or_expression
4622 | conditional_xor_expression XOR _mark_ conditional_or_expression
4624 $$ = new Binary (Binary.Operator.ExclusiveOr,
4625 (Expression) $1, (Expression) $4, (Location)$3);
4629 assignment_expression
4630 : prefixed_unary_expression ASSIGN _mark_ expression
4632 $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$3);
4634 | prefixed_unary_expression OP_EXP ASSIGN _mark_ expression
4636 Location l = (Location)$4;
4638 $$ = new CompoundAssign (
4639 Binary.Operator.Exponentiation, (Expression) $1, (Expression) $5, l);
4641 | prefixed_unary_expression STAR ASSIGN _mark_ expression
4643 Location l = (Location)$4;
4645 $$ = new CompoundAssign (
4646 Binary.Operator.Multiply, (Expression) $1, (Expression) $5, l);
4648 | prefixed_unary_expression DIV ASSIGN _mark_ expression
4650 Location l = (Location)$4;
4652 $$ = new CompoundAssign (
4653 Binary.Operator.Division, (Expression) $1, (Expression) $5, l);
4655 | prefixed_unary_expression PLUS ASSIGN _mark_ expression
4657 Location l = (Location)$4;
4659 $$ = new CompoundAssign (
4660 Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
4662 | prefixed_unary_expression MINUS ASSIGN _mark_ expression
4664 Location l = (Location)$4;
4666 $$ = new CompoundAssign (
4667 Binary.Operator.Subtraction, (Expression) $1, (Expression) $5, l);
4669 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN _mark_ expression
4671 Location l = (Location)$4;
4673 $$ = new CompoundAssign (
4674 Binary.Operator.LeftShift, (Expression) $1, (Expression) $5, l);
4676 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN _mark_ expression
4678 Location l = (Location)$4;
4680 $$ = new CompoundAssign (
4681 Binary.Operator.RightShift, (Expression) $1, (Expression) $5, l);
4683 | prefixed_unary_expression OP_CONCAT ASSIGN _mark_ expression
4685 Location l = (Location)$4;
4687 // FIXME should be strings only
4688 $$ = new CompoundAssign (
4689 Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
4691 | prefixed_unary_expression ASSIGN ADDRESSOF _mark_ expression
4693 ArrayList args = new ArrayList();
4694 Argument arg = new Argument ((Expression) $5, Argument.AType.Expression);
4697 New n = new New ((Expression) $1, (ArrayList) args, (Location)$4);
4698 n.isDelegate = true;
4699 $$ = new Assign ((Expression) $1, (Expression) n, (Location)$4);
4712 : namespace_or_type_name
4714 $$ = DecomposeQI ((string) $1, lexer.Location);
4723 ArrayList types = new ArrayList ();
4728 | type_list COMMA type
4730 ArrayList types = (ArrayList) $1;
4737 namespace_or_type_name
4738 : qualified_identifier
4742 : OBJECT { $$ = TypeManager.system_object_expr; }
4748 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4749 | DATE { $$ = TypeManager.system_date_expr; }
4750 | CHAR { $$ = TypeManager.system_char_expr; }
4751 | STRING { $$ = TypeManager.system_string_expr; }
4757 | floating_point_type
4758 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4763 | BYTE { $$ = TypeManager.system_byte_expr; }
4764 | SHORT { $$ = TypeManager.system_int16_expr; }
4765 | INTEGER { $$ = TypeManager.system_int32_expr; }
4766 | LONG { $$ = TypeManager.system_int64_expr; }
4770 : SINGLE { $$ = TypeManager.system_single_expr; }
4771 | DOUBLE { $$ = TypeManager.system_double_expr; }
4775 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS _mark_ EOL
4777 if(tokenizerController.IsAcceptingTokens)
4779 if(in_external_source)
4780 Report.Error (30580, (Location)$8, "#ExternalSource directives may not be nested");
4782 in_external_source = true;
4784 lexer.EffectiveSource = (string) $4;
4785 lexer.EffectiveLine = (int) $6;
4789 | HASH IDENTIFIER LITERAL_STRING _mark_ EOL
4791 if(tokenizerController.IsAcceptingTokens)
4793 if(!($2 as string).ToLower().Equals("region"))
4794 Report.Error (30205, (Location)$4, "Invalid Pre-processor directive");
4801 | HASH END IDENTIFIER _mark_ EOL
4803 if(tokenizerController.IsAcceptingTokens)
4805 if( ($3 as string).ToLower().Equals("externalsource")) {
4806 if(!in_external_source)
4807 Report.Error (30578, (Location)$4, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4809 in_external_source = false;
4810 lexer.EffectiveSource = lexer.Source;
4811 lexer.EffectiveLine = lexer.Line;
4814 else if(($3 as string).ToLower().Equals("region")) {
4815 if(in_marked_region > 0)
4818 Report.Error (30205, (Location)$4, "'#End Region' must be preceded by a matching '#Region'");
4821 Report.Error (29999, (Location)$4, "Unrecognized Pre-Processor statement");
4825 | HASH CONST IDENTIFIER ASSIGN boolean_literal _mark_ EOL
4827 if(tokenizerController.IsAcceptingTokens)
4835 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4838 ifElseStateMachine.HandleToken(tok);
4840 catch(ApplicationException) {
4841 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
4844 boolean_literal opt_then EOL
4846 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$5);
4848 | HASH opt_elseif _mark_
4850 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4852 ifElseStateMachine.HandleToken(tok);
4854 catch(ApplicationException) {
4855 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
4858 boolean_literal opt_then EOL
4860 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$5);
4864 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4866 ifElseStateMachine.HandleToken(tok);
4868 catch(ApplicationException) {
4869 throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
4874 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4876 | HASH END IF _mark_
4878 /*FIXME: IF without ENDIF not working properly. Error line is not diplayed properly*/
4880 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4882 ifElseStateMachine.HandleToken(tok);
4884 catch(ApplicationException) {
4885 throw new MBASException(ifElseStateMachine.Error, (Location)$4, ifElseStateMachine.ErrString);
4890 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4892 | HASH error _mark_ EOL
4894 if(tokenizerController.IsAcceptingTokens)
4895 Report.Error(29999, (Location)$3, "Unrecognized Pre-Processor statement");
4897 Report.Warning (29999, (Location)$3,"Unrecognized Pre-Processor statement");
4902 // Utility rule to save location information
4905 { $$ = lexer.Location; if (yyToken == Token.EOL) { $$ = new Location (lexer.Location.Row - 1, lexer.Location.Col); } }
4908 // Changed to accept "Else If" also along with "ElseIf"
4914 // Changed so as to check if every block is closed or not...
4963 /*In case of any new end block please add it here.. after END_GET as single token... and please continue the numbering from 17...*/
4971 public Tokenizer Lexer {
4977 public static Expression DecomposeQI (string name, Location loc)
4981 if (name.IndexOf ('.') == -1){
4982 return new SimpleName (name, loc);
4984 int pos = name.LastIndexOf (".");
4985 string left = name.Substring (0, pos);
4986 string right = name.Substring (pos + 1);
4988 o = DecomposeQI (left, loc);
4990 return new MemberAccess (o, right, loc);
4994 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4996 Block implicit_block;
4997 ArrayList inits = null;
5000 // We use the `Used' property to check whether statements
5001 // have been added to the current block. If so, we need
5002 // to create another block to contain the new declaration
5003 // otherwise, as an optimization, we use the same block to
5004 // add the declaration.
5006 // FIXME: A further optimization is to check if the statements
5007 // that were added were added as part of the initialization
5008 // below. In which case, no other statements have been executed
5009 // and we might be able to reduce the number of blocks for
5010 // situations like this:
5012 // int j = 1; int k = j + 1;
5015 VariableDeclaration.FixupTypes (variable_declarators);
5017 if (current_block.Used) {
5018 implicit_block = new Block (current_block, true, loc, Location.Null);
5019 implicit_block.AddChildVariableNames (current_block);
5021 implicit_block = current_block;
5023 foreach (VariableDeclaration decl in variable_declarators){
5024 Expression type = decl.type;
5025 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, loc) != null) {
5026 if (decl.expression_or_array_initializer != null){
5028 inits = new ArrayList ();
5035 return implicit_block;
5037 foreach (VariableDeclaration decl in inits){
5040 Expression type = decl.type;
5042 if ((decl.expression_or_array_initializer is Expression) ||
5043 (decl.expression_or_array_initializer is New)) {
5044 expr = (Expression) decl.expression_or_array_initializer;
5046 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
5048 expr = new ArrayCreation (type, "", init, decl.Location);
5051 LocalVariableReference var;
5052 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
5054 assign = new Assign (var, expr, decl.Location);
5056 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
5059 return implicit_block;
5062 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
5064 Block implicit_block;
5065 VariableDeclaration.FixupTypes (variable_declarators);
5067 if (current_block.Used)
5068 implicit_block = new Block (current_block, true);
5070 implicit_block = current_block;
5072 foreach (VariableDeclaration decl in variable_declarators){
5073 Expression type = decl.type;
5074 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
5075 current_local_parameters, decl.Location);
5078 return implicit_block;
5086 public VarName (object n, object t, object r)
5096 // A class used to pass around variable declarations and constants
5098 public class VariableDeclaration {
5099 public string identifier;
5100 public object expression_or_array_initializer;
5101 public Location Location;
5102 public Attributes OptAttributes;
5103 public Expression type;
5104 public ArrayList dims;
5106 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
5108 this.identifier = id;
5109 this.expression_or_array_initializer = eoai;
5111 this.OptAttributes = opt_attrs;
5116 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
5120 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
5124 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
5125 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
5129 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
5131 // FIXME : This is broken: only the first rank is parsed
5132 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
5135 public static void FixupTypes (ArrayList vars)
5137 int varcount = vars.Count;
5138 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
5140 if (last_var.type == null)
5141 last_var.type = TypeManager.system_object_expr;
5143 Expression cur_type = last_var.type;
5144 int n = varcount - 1;
5147 VariableDeclaration var = (VariableDeclaration) vars[n--];
5148 if (var.type == null)
5149 var.type = cur_type;
5151 cur_type = var.type;
5155 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
5159 if (IndexList != null) {
5160 foreach (Expression e in IndexList)
5161 if (!(e is EmptyExpression)) {
5170 public static bool IndexesSpecified (ArrayList ranks)
5174 if (ranks != null) {
5175 foreach (ArrayList IndexList in ranks) {
5176 if (IndexesSpecifiedInRank (IndexList)) {
5185 public static string StripDims (string varname, ref string d)
5187 string res = varname;
5190 if (varname.IndexOf("[") >= 0) {
5191 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
5192 res = varname.Substring(0, varname.IndexOf("["));
5198 public static string StripDims (string varname)
5202 return (StripDims(varname, ref dres));
5205 public static string StripIndexesFromDims (string dims)
5207 StringBuilder sb = new StringBuilder();
5209 foreach (char c in dims)
5210 if (c == ',' || c == ']' || c == '[')
5213 return sb.ToString();
5216 public static string BuildRank (ArrayList rank)
5219 return BuildRank(rank, out allEmpty);
5222 public static string BuildRank (ArrayList rank, out bool allEmpty)
5229 foreach (object e in rank) {
5230 if (!(e is EmptyExpression))
5241 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
5245 bool allEmpty = true;
5246 foreach (ArrayList rank in rank_specifiers) {
5248 res = BuildRank (rank, out tmp) + res;
5252 if (!allEmpty && mustBeEmpty)
5253 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
5258 public static void VBFixIndexList (ref ArrayList IndexList)
5260 if (IndexList != null) {
5261 for (int x = 0; x < IndexList.Count; x++) {
5262 Expression e = (Expression) IndexList[x];
5263 if (!(e is EmptyExpression)) {
5264 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
5270 public static bool IsArrayDecl (Parser t)
5272 // return (varname.IndexOf("[") >= 0);
5273 return (t.current_rank_specifiers != null);
5276 public static void VBFixIndexLists (ref ArrayList ranks)
5278 if (ranks != null) {
5279 for (int x = 0; x < ranks.Count; x++) {
5280 ArrayList IndexList = (ArrayList) ranks[x];
5281 VBFixIndexList (ref IndexList);
5286 public static void FixupArrayTypes (ArrayList vars)
5290 foreach (VariableDeclaration var in vars) {
5291 if (var.identifier.EndsWith(",")) {
5292 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
5293 var.identifier.LastIndexOf(",")) + "]";
5294 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
5295 var.type = new ComposedCast (var.type, (string) dims, var.Location);
5302 public Property BuildSimpleProperty (Expression p_type, string name,
5303 Field p_fld, int mod_flags,
5304 Attributes attrs, Location loc)
5307 Block get_block, set_block;
5308 Accessor acc_set, acc_get;
5309 StatementExpression a_set;
5314 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
5315 args = new Parameter [1];
5316 args [0] = implicit_value_parameter;
5318 Parameters set_params = new Parameters (args, null, loc);
5319 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
5320 (Expression) new SimpleName("value", loc), loc), loc);
5322 set_block = new Block (current_block, set_params, loc, Location.Null);
5323 set_block.AddStatement ((Statement) a_set);
5324 acc_set = new Accessor (set_block, attrs);
5327 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
5328 get_block = new Block (current_block, null, loc, Location.Null);
5329 get_block.AddStatement ((Statement) a_get);
5330 acc_get = new Accessor (get_block, attrs);
5332 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
5339 current_block = new Block (current_block, current_local_parameters,
5340 lexer.Location, Location.Null);
5347 while (current_block.Implicit)
5348 current_block = current_block.Parent;
5350 res = current_block;
5352 current_block.SetEndLocation (lexer.Location);
5353 current_block = current_block.Parent;
5358 void push_into_stack(int BlockStart, Location l)
5360 end_of_block.Push(BlockStart);
5361 loc_end_of_block.Push(l);
5364 void pop_out_of_stack(int BlockEnd, Location l)
5366 if(BlockEnd != Token.EOF) {
5367 int current = (int)end_of_block.Pop();
5368 Location current_loc = (Location)loc_end_of_block.Pop();
5369 if(BlockEnd != current) {
5370 // Block end is missing
5371 // eg: For 'Sub' BlockEnd should be 'End Sub'
5373 if(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2]) {
5374 while(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2])
5376 if(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2])
5377 Report.Error(error_end_blocks[current,0],current_loc,"'"+end_blocks[current,0]+"' is not having matching '"+end_blocks[current,1]+"'");
5378 current = (int)end_of_block.Pop();
5379 current_loc = (Location)loc_end_of_block.Pop();
5383 // Extra end is present, but works for lesser priority
5384 // (for priority see opt_end_block opt_block_types return values
5385 // eg: 'EndIf' without 'If' inside 'Sub'
5386 // Also certain other errors like 'Sub' having a 'End Module' etc
5387 // can be handled here
5389 if(error_end_blocks[BlockEnd,2] < error_end_blocks[current,2]) {
5390 Report.Error(error_end_blocks[BlockEnd,1],l,"'"+end_blocks[BlockEnd,1]+"' is not having a corresponding '"+end_blocks[BlockEnd,0]+"'");
5391 end_of_block.Push(current);
5392 loc_end_of_block.Push(current_loc);
5394 // Extra end is present but with equal priorty
5396 if((error_end_blocks[BlockEnd,2] == error_end_blocks[current,2]) && BlockEnd != current) {
5397 while((error_end_blocks[BlockEnd,2] == error_end_blocks[current,2]) && BlockEnd != current) {
5398 temp_block.Push(current);
5399 loc_temp_block.Push(current_loc);
5400 current = (int)end_of_block.Pop();
5401 current_loc = (Location)loc_end_of_block.Pop();
5404 if(BlockEnd == current) {
5405 while(temp_block.Count !=0)
5407 int lapse = (int) temp_block.Pop();
5408 Location lapse_location = (Location)loc_temp_block.Pop();
5409 Report.Error(error_end_blocks[lapse,0],lapse_location,"'"+end_blocks[lapse,0]+"' is not having matching '"+end_blocks[lapse,1]+"'");
5414 Report.Error(error_end_blocks[BlockEnd,1],l,"'"+end_blocks[BlockEnd,1]+"' is not having a corresponding '"+end_blocks[BlockEnd,0]+"'");
5415 end_of_block.Push(current);
5416 loc_end_of_block.Push(current_loc);
5417 while(temp_block.Count !=0) {
5418 int lapse = (int) temp_block.Pop();
5419 Location lapse_location = (Location)loc_temp_block.Pop();
5420 end_of_block.Push(lapse);
5421 loc_end_of_block.Push(lapse_location);
5428 while(end_of_block.Count !=0) {
5429 int lapse = (int) end_of_block.Pop();
5430 Location lapse_location = (Location)loc_end_of_block.Pop();
5431 Report.Error(error_end_blocks[lapse,0],lapse_location,"'"+end_blocks[lapse,0]+"' is not having matching '"+end_blocks[lapse,1]+"'");
5436 private void AddHandler (Expression evt_definition, Expression handler_exp)
5438 AddHandler (current_block, evt_definition, handler_exp);
5441 void CheckAttributeTarget (string a)
5445 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
5449 Location l = lexer.Location;
5450 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
5455 private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
5457 Location loc = lexer.Location;
5459 Statement addhnd = (Statement) new AddHandler (evt_id,
5462 b.AddStatement (addhnd);
5465 private void RaiseEvent (string evt_name, ArrayList args)
5467 Location loc = lexer.Location;
5469 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
5470 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
5471 current_block.AddStatement (s);
5474 private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
5476 Location loc = lexer.Location;
5478 Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
5481 b.AddStatement (rmhnd);
5485 // This method is used to get at the complete string representation of
5486 // a fully-qualified type name, hiding inside a MemberAccess ;-)
5487 // This is necessary because local_variable_type admits primary_expression
5488 // as the type of the variable. So we do some extra checking
5490 string GetQualifiedIdentifier (Expression expr)
5492 if (expr is SimpleName)
5493 return ((SimpleName)expr).Name;
5494 else if (expr is MemberAccess)
5495 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
5497 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
5501 private void RemoveHandler (Expression evt_definition, Expression handler_exp)
5503 RemoveHandler (current_block, evt_definition, handler_exp);
5506 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
5508 ConstructorInitializer ci = null;
5511 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
5512 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
5514 if (i.expr is BaseAccess) {
5515 BaseAccess ba = (BaseAccess) i.expr;
5516 if (ba.member == "New" || ba.member == ".ctor") {
5517 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
5521 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
5522 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
5530 void Error_ExpectingTypeName (Location l, Expression expr)
5532 if (expr is Invocation){
5533 Report.Error (1002, l, "; expected");
5535 Report.Error (-1, l, "Invalid Type definition");
5539 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
5543 private void ReportError9998()
5545 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
5548 protected override int parse ()
5550 RootContext.InitializeImports(ImportsList);
5551 current_namespace = new Namespace (null, RootContext.RootNamespace);
5552 current_container = RootContext.Tree.Types;
5553 current_container.Namespace = current_namespace;
5554 oob_stack = new Stack ();
5555 switch_stack = new Stack ();
5556 expr_stack = new Stack ();
5557 tmp_blocks = new Stack();
5558 with_stack = new Stack();
5559 statement_stack = new Stack();
5560 end_of_block = new Stack ();
5561 loc_end_of_block = new Stack ();
5562 temp_block = new Stack();
5563 loc_temp_block = new Stack();
5565 allow_global_attribs = true;
5566 expecting_global_attribs = false;
5567 expecting_local_attribs = false;
5568 local_attrib_section_added = false;
5570 UseExtendedSyntax = name.EndsWith(".mbs");
5571 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
5572 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
5573 OptionCompareBinary = InitialOptionCompareBinary;
5575 lexer = new Tokenizer (input, name, defines);
5577 ifElseStateMachine = new IfElseStateMachine();
5578 tokenizerController = new TokenizerController(lexer);
5581 if (yacc_verbose_flag > 0)
5582 yyparse (lexer, new yydebug.yyDebugSimple ());
5588 catch(MBASException e) {
5589 Report.Error(e.code, e.loc, e.Message);
5591 catch (Exception e) {
5592 if (Report.Stacktrace)
5593 Console.WriteLine(e);
5594 Report.Error (29999, lexer.Location, "Parsing error");
5597 RootContext.VerifyImports();
5599 return Report.Errors;
5605 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
5607 catch(ApplicationException) {
5608 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5611 if(in_external_source)
5612 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
5614 if(in_marked_region > 0)
5615 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
5618 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
5621 tokenizerController.PositionTokenizerCursor(tok, expr);
5623 catch(ApplicationException) {
5624 tok = IfElseStateMachine.Token.EOF;
5626 ifElseStateMachine.HandleToken(tok);
5628 catch(ApplicationException) {
5629 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);