3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
5 // Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
6 // Anirban Bhattacharjee (banirban@novell.com)
7 // Jambunathan K (kjambunathan@novell.com)
9 // Licensed under the terms of the GNU GPL
11 // Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
12 // Copyright (C) 2003, 2004 Novell
16 namespace Mono.MonoBASIC
20 using System.Reflection;
21 using System.Collections;
25 public class MBASException : ApplicationException
30 public MBASException(int code, Location loc, string text) : base(text)
38 /// The MonoBASIC Parser
41 public class Parser : GenericParser
47 /// Current block is used to add statements as we find
53 /// Tmp block is used to store block endings in if/select's
58 /// Tmp block is used to store tmp copies of expressions
63 /// Tmp catch is used to store catch clauses in try..catch..finally
65 ArrayList tmp_catch_clauses;
68 /// Current interface is used by the various declaration
69 /// productions in the interface declaration to "add"
70 /// the interfaces as we find them.
72 Interface current_interface;
75 /// This is used by the unary_expression code to resolve
76 /// a name against a parameter.
78 Parameters current_local_parameters;
81 /// This are used when parsing parameters in property
84 Parameters set_parameters;
85 Parameters get_parameters;
88 /// This is used by the sub_header parser to store modifiers
89 /// to be passed to sub/constructor
91 int current_modifiers;
94 /// This is used by the sub_header parser to store attributes
95 /// to be passed to sub/constructor
97 Attributes current_attributes;
100 /// Using during property parsing to describe the implicit
101 /// value parameter that is passed to the "set" accessor
104 string get_implicit_value_parameter_name;
107 // Using during property parsing to describe the implicit
108 // value parameter that is passed to the "set" and "get"accesor
109 // methods (properties and indexers).
111 Expression get_implicit_value_parameter_type;
114 /// Using during property parsing to describe the implicit
115 /// value parameter that is passed to the "set" accessor
118 string set_implicit_value_parameter_name;
121 // Using during property parsing to describe the implicit
122 // value parameter that is passed to the "set" and "get"accesor
123 // methods (properties and indexers).
125 Expression set_implicit_value_parameter_type;
127 Location member_location;
129 // An out-of-band stack.
133 ArrayList current_rank_specifiers;
141 // Expression stack for nested ifs
145 Stack statement_stack;
147 // A stack for With expressions.
152 static public bool InitialOptionExplicit = false;
153 static public bool InitialOptionStrict = false;
154 static public bool InitialOptionCompareBinary = true;
155 static public ArrayList ImportsList = null;
159 bool OptionCompareBinary;
161 static public bool UseExtendedSyntax; // for ".mbs" files
163 bool implicit_modifiers;
165 public override string[] extensions()
167 string [] list = { ".vb", ".mbs" };
171 bool in_external_source = false;
172 int in_marked_region = 0;
174 TokenizerController tokenizerController;
175 IfElseStateMachine ifElseStateMachine;
178 public class IfElseStateMachine {
202 public static Hashtable errStrings = new Hashtable();
205 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
207 static IfElseStateMachine()
209 // FIXME: Fix both the error nos and the error strings.
210 // Currently the error numbers and the error strings are
211 // just placeholders for getting the state-machine going.
213 errStrings.Add(0, "");
214 errStrings.Add(30012, "#If must end with a matching #End If");
215 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
216 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
217 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
218 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
220 errTable[(int)State.START, (int)Token.IF] = 0;
221 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
222 errTable[(int)State.START, (int)Token.ELSE] = 30028;
223 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
224 errTable[(int)State.START, (int)Token.EOF] = 0;
226 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
227 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
228 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
229 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
230 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
232 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
233 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
234 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
235 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
236 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
238 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
239 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
240 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
241 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
242 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
244 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
245 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
246 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
247 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
248 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
251 public IfElseStateMachine()
255 stateStack = new Stack();
256 stateStack.Push(state);
259 // The parameter here need not be qualified with IfElseStateMachine
260 // But it hits a bug in mcs. So temporarily scoping it so that builds
263 public void HandleToken(IfElseStateMachine.Token tok)
265 err = (int) errTable[(int)state, (int)tok];
268 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
270 if(tok == Token.IF) {
271 stateStack.Push(state);
274 else if(tok == Token.ENDIF) {
275 state = (State)stateStack.Pop();
287 public string ErrString {
289 return (string) errStrings[err];
295 public class TokenizerController {
299 public bool CanAcceptTokens;
300 public bool CanSelectBlock;
308 public TokenizerController(Tokenizer lexer)
311 stateStack = new Stack();
313 currentState.CanAcceptTokens = true;
314 currentState.CanSelectBlock = true;
316 stateStack.Push(currentState);
321 return (State)stateStack.Peek();
325 public bool IsAcceptingTokens {
327 return currentState.CanAcceptTokens;
331 public void PositionCursorAtNextPreProcessorDirective()
333 lexer.PositionCursorAtNextPreProcessorDirective();
336 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
338 if(tok == IfElseStateMachine.Token.ENDIF) {
339 currentState = (State)stateStack.Pop();
341 if(currentState.CanAcceptTokens)
344 PositionCursorAtNextPreProcessorDirective();
349 if(tok == IfElseStateMachine.Token.IF) {
350 stateStack.Push(currentState);
352 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
353 currentState.CanSelectBlock = true;
356 if(parentState.CanAcceptTokens &&
357 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
359 currentState.CanAcceptTokens = true;
360 currentState.CanSelectBlock = false;
364 currentState.CanAcceptTokens = false;
365 PositionCursorAtNextPreProcessorDirective();
371 bool allow_global_attribs = true;
373 bool expecting_global_attribs = false;
374 bool expecting_local_attribs = false;
376 bool local_attrib_section_added = false;
380 %token NONE /* This token is never returned by our lexer */
381 %token ERROR // This is used not by the parser, but by the tokenizer.
385 *These are the MonoBASIC keywords
477 %token NOTINHERITABLE
478 %token NOTOVERRIDABLE
534 %token YIELD // MonoBASIC extension
538 /* MonoBASIC single character operators/punctuation. */
540 %token OPEN_BRACKET "["
541 %token CLOSE_BRACKET "]"
542 %token OPEN_PARENS "("
543 %token OPEN_BRACE "{"
544 %token CLOSE_BRACE "}"
545 %token CLOSE_PARENS ")"
559 %token OP_IDIV "\\" //FIXME: This should be "\"
561 %token EXCLAMATION "!"
564 %token LONGTYPECHAR "&"
566 %token SINGLETYPECHAR "!"
567 %token NUMBER_SIGN "#"
568 %token DOLAR_SIGN "$"
570 %token ATTR_ASSIGN ":="
572 /* MonoBASIC multi-character operators. */
577 //%token OP_MODULUS //"mod"
579 /* VB.NET 2003 new bit-shift operators */
580 %token OP_SHIFT_LEFT "<<"
581 %token OP_SHIFT_RIGHT ">>"
584 %token LITERAL_INTEGER "int literal"
585 %token LITERAL_SINGLE "float literal"
586 %token LITERAL_DOUBLE "double literal"
587 %token LITERAL_DECIMAL "decimal literal"
588 %token LITERAL_CHARACTER "character literal"
589 %token LITERAL_STRING "string literal"
590 %token LITERAL_DATE "datetime literal"
594 /* Add precedence rules to solve dangling else s/r conflict */
603 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
605 %left STAR DIV PERCENT
606 %right BITWISE_NOT CARRET UMINUS
607 %nonassoc OP_INC OP_DEC
609 %left OPEN_BRACKET OPEN_BRACE
614 %start compilation_unit
618 : logical_end_of_line
624 | logical_end_of_line pp_directive
628 : logical_end_of_line
629 opt_option_directives
630 opt_imports_directives
637 opt_option_directives
638 opt_imports_directives
646 opt_option_directives
653 | option_directives option_directive
657 : option_explicit_directive
658 | option_strict_directive
659 | option_compare_directive
688 option_explicit_directive
689 : OPTION EXPLICIT on_off logical_end_of_line
691 if (!UseExtendedSyntax)
692 OptionExplicit = (bool)$3;
695 9999, lexer.Location,
696 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
701 option_strict_directive
702 : OPTION STRICT on_off logical_end_of_line
704 if (!UseExtendedSyntax)
705 OptionStrict = (bool)$3;
708 9999, lexer.Location,
709 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
713 option_compare_directive
714 : OPTION COMPARE text_or_binary logical_end_of_line
716 OptionCompareBinary = (bool)$3;
727 | declarations declaration
731 : declaration_qualifiers
733 // FIXME: Need to check declaration qualifiers for multi-file compilation
734 // FIXME: Qualifiers cannot be applied to namespaces
735 allow_global_attribs = false;
737 namespace_declaration
738 |declaration_qualifiers
740 // FIXME: Need to check declaration qualifiers for multi-file compilation
741 allow_global_attribs = false;
743 type_spec_declaration
748 if ($3 is Class || $3 is Struct || $3 is Module ){
749 TypeContainer c = (TypeContainer) $3;
750 mod_flags = c.ModFlags;
755 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
757 1527, lexer.Location,
758 "Namespace elements cannot be explicitly " +
759 "declared private or protected in '" + name + "'");
774 : PERCENT { $$ = TypeManager.system_int32_expr; }
775 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
776 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
777 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
778 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
779 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
783 : /* empty */ { $$ = null; }
784 | type_character { $$ = $1; }
790 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
792 $$ = (($1).ToString ()) + "." + ($3.ToString ());
796 opt_imports_directives
803 | imports_directives imports_directive
807 : IMPORTS imports_terms logical_end_of_line
812 | imports_terms COMMA imports_term
816 : namespace_or_type_name
818 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
820 | identifier ASSIGN namespace_or_type_name
822 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
827 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
828 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
829 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
837 local_attrib_section_added = false;
846 expecting_local_attribs = false;
847 expecting_global_attribs = false;
851 if (expecting_local_attribs) {
852 local_attrib_section_added = true;
853 allow_global_attribs = false;
855 $$ = new Attributes ((ArrayList) $1);
858 if (expecting_global_attribs) {
860 CodeGen.AddGlobalAttributes ((ArrayList) $1);
863 expecting_local_attribs = false;
864 expecting_global_attribs = false;
874 ArrayList attrs = (ArrayList) $3;
876 if (expecting_local_attribs) {
877 if (local_attrib_section_added) {
878 expecting_local_attribs = false;
879 expecting_global_attribs = false;
880 Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
885 $$ = new Attributes (attrs);
887 ((Attributes) $1).Add (attrs);
889 local_attrib_section_added = true;
890 allow_global_attribs = false;
893 if (expecting_global_attribs) {
895 CodeGen.AddGlobalAttributes ((ArrayList) $3);
899 expecting_local_attribs = false;
900 expecting_global_attribs = false;
905 : OP_LT attribute_list OP_GT opt_end_of_stmt
909 if (expecting_global_attribs && !(bool) $4) {
910 Report.Error (30205, lexer.Location, "End of statement expected");
914 if (expecting_local_attribs) {
916 Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
927 : /* empty */ { $$ = false; }
928 | end_of_stmt { $$ = true; }
934 ArrayList attrs = null;
936 attrs = new ArrayList ();
941 | attribute_list COMMA attribute
943 ArrayList attrs = null;
946 attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
955 : namespace_or_type_name
959 opt_attribute_arguments
963 if (expecting_global_attribs)
964 Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
966 expecting_local_attribs = true;
967 $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
970 | attribute_target_specifier
975 namespace_or_type_name
979 opt_attribute_arguments
983 string attribute_target = (string) $1;
984 if (attribute_target != "assembly" && attribute_target != "module") {
985 Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
988 if (!allow_global_attribs) {
989 Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
993 if (expecting_local_attribs) {
994 Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
998 expecting_global_attribs = true;
999 $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
1003 attribute_target_specifier
1004 : ASSEMBLY { $$ = "assembly"; }
1005 | MODULE { $$ = "module"; }
1006 | namespace_or_type_name
1010 opt_attribute_arguments
1011 : /* empty */ { $$ = null; }
1012 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
1018 opt_attribute_arguments_list
1020 | attribute_arguments_list
1023 attribute_arguments_list
1024 : positional_argument_list
1026 ArrayList args = new ArrayList ();
1031 | positional_argument_list COMMA named_argument_list
1033 ArrayList args = new ArrayList ();
1039 | named_argument_list
1041 ArrayList args = new ArrayList ();
1049 positional_argument_list
1050 : constant_expression
1052 ArrayList args = new ArrayList ();
1053 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
1057 | positional_argument_list COMMA constant_expression
1059 ArrayList args = (ArrayList) $1;
1060 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
1069 ArrayList args = new ArrayList ();
1074 | named_argument_list COMMA named_argument
1076 ArrayList args = (ArrayList) $1;
1084 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
1086 $$ = new DictionaryEntry (
1088 new Argument ((Expression) $3, Argument.AType.Expression));
1092 namespace_declaration
1093 : NAMESPACE qualified_identifier logical_end_of_line
1095 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2);
1098 END NAMESPACE logical_end_of_line
1100 current_namespace = current_namespace.Parent;
1104 declaration_qualifiers
1108 current_attributes = (Attributes) $1;
1109 current_modifiers = (int) $2;
1113 type_spec_declaration
1115 | module_declaration
1116 | interface_declaration
1117 | delegate_declaration
1118 | struct_declaration
1123 : CLASS identifier logical_end_of_line opt_inherits opt_implements
1125 // Module members are static by default, but Class *can't* be declared static
1126 // so we must fix it, if mbas was the one actually responsible for this
1127 // instead of triggering an error.
1128 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1129 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1134 name = MakeName ((string) $2);
1135 new_class = new Class (current_container, name, current_modifiers,
1136 (Attributes) current_attributes, lexer.Location);
1138 current_container = new_class;
1139 current_container.Namespace = current_namespace;
1140 RootContext.Tree.RecordDecl (name, new_class);
1142 opt_class_member_declarations
1143 END CLASS logical_end_of_line
1145 Class new_class = (Class) current_container;
1147 ArrayList bases = (ArrayList) $4;
1149 ArrayList ifaces = (ArrayList) $5;
1150 if (ifaces != null){
1152 bases.AddRange(ifaces);
1156 new_class.Bases = bases;
1158 current_container = current_container.Parent;
1159 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1166 : /* empty */ { $$ = null; }
1167 | INHERITS type_list logical_end_of_line { $$ = $2; }
1171 : /* empty */ { $$ = null; }
1172 | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
1176 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1177 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1182 | modifiers modifier
1187 if ((m1 & m2) != 0) {
1188 Location l = lexer.Location;
1189 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1191 $$ = (int) (m1 | m2);
1196 : PUBLIC { $$ = Modifiers.PUBLIC; }
1197 | PROTECTED { $$ = Modifiers.PROTECTED; }
1198 | PRIVATE { $$ = Modifiers.PRIVATE; }
1199 | SHARED { $$ = Modifiers.STATIC; }
1200 | FRIEND { $$ = Modifiers.INTERNAL; }
1201 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1202 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1203 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1204 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1205 | OVERLOADS { $$ = Modifiers.NEW; }
1206 | SHADOWS { $$ = Modifiers.SHADOWS; }
1207 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1208 | READONLY { $$ = Modifiers.READONLY; }
1209 | DEFAULT { $$ = Modifiers.DEFAULT; }
1210 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1214 : MODULE identifier logical_end_of_line
1218 name = MakeName((string) $2);
1219 new_module = new Module(current_container,
1221 current_modifiers, // already checks then
1222 (Attributes) current_attributes,
1224 current_container = new_module;
1225 current_container.Namespace = current_namespace;
1226 RootContext.Tree.RecordDecl(name, new_module);
1228 opt_module_member_declarations
1229 END MODULE logical_end_of_line
1231 Module new_module = (Module)current_container;
1233 current_container = current_container.Parent;
1234 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1236 TypeManager.AddStandardModule(new_module);
1242 opt_module_member_declarations
1244 | module_member_declarations
1247 module_member_declarations
1248 : module_member_declaration
1249 | module_member_declarations module_member_declaration
1252 module_member_declaration
1256 current_attributes = (Attributes) $1;
1257 current_modifiers = ((int)$2) | Modifiers.STATIC;
1258 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1259 implicit_modifiers = (!explicit_static);
1261 module_member_declarator
1263 implicit_modifiers = false;
1268 module_member_declarator
1269 : constructor_declaration
1270 | method_declaration
1272 Method method = (Method) $1;
1273 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1276 | withevents_declaration /* This is a field but must be treated specially, see below */
1277 | constant_declaration
1278 | property_declaration
1280 | type_spec_declaration
1283 constant_declaration
1284 : CONST constant_declarators logical_end_of_line
1286 // Module members are static by default, but constants *can't* be declared static
1287 // so we must fix it, if mbas was the one actually responsible for this
1288 // instead of triggering an error.
1289 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1290 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1292 int mod = (int) current_modifiers;
1294 // Structure members are Public by default
1295 if ((current_container is Struct) && (mod == 0))
1296 mod = Modifiers.PUBLIC;
1298 ArrayList consts = (ArrayList) $2;
1299 if(consts.Count > 0)
1301 VariableDeclaration.FixupTypes ((ArrayList) $2);
1302 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1304 foreach (VariableDeclaration var in (ArrayList) $2){
1305 Location l = var.Location;
1306 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1307 (Expression)var.expression_or_array_initializer,
1308 mod, (Attributes) null, l);
1310 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1316 opt_class_member_declarations
1318 | class_member_declarations
1321 class_member_declarations
1322 : class_member_declaration
1323 | class_member_declarations class_member_declaration
1326 class_member_declaration
1330 current_attributes = (Attributes) $1;
1331 current_modifiers = (int) $2;
1333 class_member_declarator
1339 class_member_declarator
1340 : constructor_declaration
1341 | method_declaration
1343 Method method = (Method) $1;
1344 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1347 | constant_declaration
1348 | property_declaration
1350 | withevents_declaration /* This is a field but must be treated specially, see below */
1351 | type_spec_declaration
1358 | must_override_declaration
1361 must_override_declaration
1362 : must_override_sub_declaration
1363 | must_override_func_declaration
1366 must_override_sub_declaration
1367 : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
1369 if (current_container is Module)
1370 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1372 if (current_container is Struct)
1373 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1375 current_modifiers |= Modifiers.ABSTRACT;
1377 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1378 (Parameters) $4, null, (ArrayList) $5, lexer.Location);
1380 if (!(current_container is Class))
1381 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1388 must_override_func_declaration
1389 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1391 Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.
1392 system_object_expr : (Expression) $4 ) : (Expression) $6;
1394 if (current_container is Module)
1395 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1397 if (current_container is Struct)
1398 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1400 current_modifiers |= Modifiers.ABSTRACT;
1402 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1403 (string) $3,(Parameters) $5, null, (ArrayList) $7,
1406 if (!(current_container is Class))
1407 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1414 : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1416 current_local_parameters = (Parameters) $3;
1419 // Structure members are Public by default
1420 if ((current_container is Struct) && (current_modifiers == 0))
1421 current_modifiers = Modifiers.PUBLIC;
1423 member_location = lexer.Location;
1426 END SUB logical_end_of_line
1428 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1429 (Parameters) current_local_parameters, (Attributes) current_attributes,
1430 (ArrayList) $5, member_location);
1432 method.Block = (Block) end_block();
1436 // we have an event handler to take care of
1438 Expression handles_exp = (Expression) $4;
1439 Location loc = lexer.Location;
1441 if (handles_exp is MemberAccess) {
1442 string evt_def = ((MemberAccess)$4).ToString();
1443 int pos = evt_def.LastIndexOf (".");
1444 string evt_target = evt_def.Substring (0, pos);
1447 if (current_container.Properties != null) {
1448 foreach (Property p in current_container.Properties) {
1449 if (p.Name == evt_target) {
1452 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1453 DecomposeQI((string) $2, loc),
1456 current_container.AddEventHandler (addhnd);
1464 Report.Error(30506, lexer.Location,
1465 evt_target + " is not declared with WithEvents");
1467 } else if (handles_exp is BaseAccess) {
1468 string evt_id = ((BaseAccess) $4).member;
1469 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1470 DecomposeQI((string) $2, loc),
1473 current_container.AddEventHandler (addhnd);
1481 : FUNCTION identifier opt_type_character
1482 opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1484 current_local_parameters = (Parameters) $4;
1485 member_location = lexer.Location;
1488 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1490 // Structure members are Public by default
1491 if ((current_container is Struct) && (current_modifiers == 0))
1492 current_modifiers = Modifiers.PUBLIC;
1493 // Add local var declaration
1495 ArrayList retval = new ArrayList ();
1496 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1497 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1500 END FUNCTION logical_end_of_line
1502 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1504 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1505 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1506 (ArrayList) $6, member_location);
1507 method.Block = end_block();
1513 : STRUCTURE identifier logical_end_of_line
1514 opt_implement_clause
1517 string full_struct_name = MakeName ((string) $2);
1519 // Module members are static by default, but structures *can't* be declared static
1520 // so we must fix it, if mbas was the one actually responsible for this
1521 // instead of triggering an error.
1522 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1523 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1525 new_struct = new Struct (current_container, full_struct_name,
1526 (int) current_modifiers,
1527 (Attributes) current_attributes, lexer.Location);
1528 current_container = new_struct;
1529 current_container.Namespace = current_namespace;
1530 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1532 opt_struct_member_declarations
1534 Struct new_struct = (Struct) current_container;
1537 new_struct.Bases = (ArrayList) $4;
1539 current_container = current_container.Parent;
1540 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1543 END STRUCTURE logical_end_of_line
1546 opt_struct_member_declarations
1548 | struct_member_declarations
1551 struct_member_declarations
1552 : struct_member_declaration
1553 | struct_member_declarations struct_member_declaration
1556 struct_member_declaration
1558 struct_member_declarator
1561 struct_member_declarator
1563 | constant_declaration
1564 | constructor_declaration
1565 | method_declaration
1567 Method method = (Method) $1;
1568 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1570 | property_declaration
1572 | type_spec_declaration
1575 * This is only included so we can flag error 575:
1576 * destructors only allowed on class types
1578 //| destructor_declaration
1582 : EVENT identifier AS type opt_implement_clause logical_end_of_line
1584 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1586 Event e = new Event ((Expression) $4, var.identifier,
1587 null, current_modifiers,
1588 current_attributes, (ArrayList) $5,
1591 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1593 | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1595 string delName = null;
1598 delName = (string) $2;
1599 delName = delName + "EventHandler";
1600 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1601 (current_container, TypeManager.system_void_expr,
1602 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1603 (Attributes) current_attributes, lexer.Location);
1605 del.Namespace = current_namespace;
1606 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1608 ArrayList impls = (ArrayList) $4;
1609 if (impls.Count > 1) {
1610 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1611 "' can not be implemented with Event '" +
1612 (string) $2 + "', since it's delegate type does not match " +
1613 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1614 Report.Error (31407, lexer.Location, expstr);
1616 Expression impl = (Expression) impls[0];
1617 delName = impl.ToString();
1618 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1619 delName = delName + "EventHandler";
1622 Event e = new Event (DecomposeQI (delName, lexer.Location),
1624 null, current_modifiers,
1625 current_attributes, (ArrayList) $4,
1628 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1633 : ENUM identifier opt_type_spec logical_end_of_line
1634 opt_enum_member_declarations
1636 Location enum_location = lexer.Location;
1637 string full_name = MakeName ((string) $2);
1638 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1639 ArrayList enum_members = (ArrayList) $5;
1641 if (enum_members.Count == 0)
1642 Report.Error (30280, enum_location,
1643 "Enum can not have empty member list");
1645 // Module members are static by default, but enums *can't* be declared static
1646 // so we must fix it if mbas was the one actually responsible for this
1647 // instead of triggering an error.
1648 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1649 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1651 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1652 (int) current_modifiers, full_name,
1653 (Attributes) current_attributes, enum_location);
1655 foreach (VariableDeclaration ev in enum_members) {
1656 Location loc = (Location) ev.Location;
1658 CheckDef (e.AddEnumMember (ev.identifier,
1659 (Expression) ev.expression_or_array_initializer,
1660 loc, ev.OptAttributes), ev.identifier, loc);
1663 e.Namespace = current_namespace;
1665 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1666 RootContext.Tree.RecordDecl (full_name, e);
1669 END ENUM logical_end_of_line
1672 opt_enum_member_declarations
1673 : /* empty */ { $$ = new ArrayList (); }
1674 | enum_member_declarations { $$ = $1; }
1677 enum_member_declarations
1678 : enum_member_declaration
1680 ArrayList l = new ArrayList ();
1685 | enum_member_declarations enum_member_declaration
1687 ArrayList l = (ArrayList) $1;
1695 enum_member_declaration
1696 : opt_attributes identifier logical_end_of_line
1698 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1700 | opt_attributes identifier
1702 $$ = lexer.Location;
1704 ASSIGN expression logical_end_of_line
1706 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1710 interface_declaration
1711 : INTERFACE identifier logical_end_of_line
1713 Interface new_interface;
1714 string full_interface_name = MakeName ((string) $2);
1716 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1717 (Attributes) current_attributes, lexer.Location);
1718 if (current_interface != null) {
1719 Location l = lexer.Location;
1720 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1722 current_interface = new_interface;
1723 new_interface.Namespace = current_namespace;
1724 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1729 Interface new_interface = (Interface) current_interface;
1732 new_interface.Bases = (ArrayList) $5;
1734 current_interface = null;
1735 CheckDef (current_container.AddInterface (new_interface),
1736 new_interface.Name, new_interface.Location);
1739 END INTERFACE logical_end_of_line
1743 : /* empty */ { $$ = null; }
1749 | interface_bases interface_base
1751 ArrayList bases = (ArrayList) $1;
1752 bases.AddRange ((ArrayList) $2);
1758 : INHERITS type_list logical_end_of_line { $$ = $2; }
1762 : opt_interface_member_declarations
1765 opt_interface_member_declarations
1767 | interface_member_declarations
1770 interface_member_declarations
1771 : interface_member_declaration
1772 | interface_member_declarations interface_member_declaration
1775 interface_member_declaration
1779 current_attributes = (Attributes) $1;
1780 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
1782 interface_member_declarator
1788 interface_member_declarator
1789 : interface_method_declaration
1791 Method m = (Method) $1;
1792 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1794 | interface_property_declaration
1795 | interface_event_declaration
1798 interface_method_declaration
1799 : SUB identifier opt_params logical_end_of_line
1801 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1802 (Parameters) $3, current_attributes, null, lexer.Location);
1806 | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
1808 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.
1809 system_object_expr : (Expression) $3 ) : (Expression) $5;
1811 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1812 (string) $2,(Parameters) $4, current_attributes, null,
1819 interface_property_declaration
1820 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1822 Expression ftype = ($5 == null) ? (($3 == null) ?
1823 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1825 current_local_parameters = (Parameters) $4;
1826 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1827 get_parameters = current_local_parameters.Copy (lexer.Location);
1828 set_parameters = current_local_parameters.Copy (lexer.Location);
1830 Parameter implicit_value_parameter = new Parameter (
1831 ftype, "Value", Parameter.Modifier.NONE, null);
1833 set_parameters.AppendParameter (implicit_value_parameter);
1837 get_parameters = Parameters.EmptyReadOnlyParameters;
1838 set_parameters = new Parameters (null, null ,lexer.Location);
1840 Parameter implicit_value_parameter = new Parameter (
1841 ftype, "Value", Parameter.Modifier.NONE, null);
1843 set_parameters.AppendParameter (implicit_value_parameter);
1845 lexer.PropertyParsing = true;
1847 Accessor get_block = new Accessor (null, null);
1848 Accessor set_block = new Accessor (null, null);
1850 Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
1851 get_block, set_block, current_attributes, lexer.Location,
1852 null, get_parameters, set_parameters, null);
1854 CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
1856 get_implicit_value_parameter_type = null;
1857 set_implicit_value_parameter_type = null;
1858 get_parameters = null;
1859 set_parameters = null;
1860 current_local_parameters = null;
1864 interface_event_declaration
1865 : EVENT identifier AS type logical_end_of_line
1867 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1869 Event e = new Event ((Expression) $4, var.identifier,
1870 null, current_modifiers,
1871 current_attributes, lexer.Location);
1873 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1876 | EVENT identifier opt_params logical_end_of_line
1878 string delName = (string) $2;
1879 delName = delName + "EventHandler";
1880 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
1881 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1882 (current_container, TypeManager.system_void_expr,
1883 (int) delModifiers, MakeName(delName), (Parameters) $3,
1884 (Attributes) current_attributes, lexer.Location);
1886 del.Namespace = current_namespace;
1887 CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
1889 Event e = new Event (DecomposeQI (delName, lexer.Location),
1891 null, current_modifiers,
1892 current_attributes, lexer.Location);
1894 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1898 property_declaration
1899 : abstract_propery_declaration
1900 | non_abstract_propery_declaration
1903 abstract_propery_declaration
1904 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1906 Expression ftype = ($6 == null) ? (($4 == null) ?
1907 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
1909 if (current_container is Module)
1910 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1912 if (current_container is Struct)
1913 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1915 current_modifiers |= Modifiers.ABSTRACT;
1917 current_local_parameters = (Parameters) $5;
1918 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1919 get_parameters = current_local_parameters.Copy (lexer.Location);
1920 set_parameters = current_local_parameters.Copy (lexer.Location);
1922 Parameter implicit_value_parameter = new Parameter (
1923 ftype, "Value", Parameter.Modifier.NONE, null);
1925 set_parameters.AppendParameter (implicit_value_parameter);
1929 get_parameters = Parameters.EmptyReadOnlyParameters;
1930 set_parameters = new Parameters (null, null ,lexer.Location);
1932 Parameter implicit_value_parameter = new Parameter (
1933 ftype, "Value", Parameter.Modifier.NONE, null);
1935 set_parameters.AppendParameter (implicit_value_parameter);
1937 lexer.PropertyParsing = true;
1939 Accessor get_block = new Accessor (null, null);
1940 Accessor set_block = new Accessor (null, null);
1942 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1943 get_block, set_block, current_attributes, lexer.Location,
1944 null, get_parameters, set_parameters, null);
1946 if (!(current_container is Class))
1947 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1949 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1951 get_implicit_value_parameter_type = null;
1952 set_implicit_value_parameter_type = null;
1953 get_parameters = null;
1954 set_parameters = null;
1955 current_local_parameters = null;
1960 non_abstract_propery_declaration
1961 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
1963 if ((current_modifiers & Modifiers.DEFAULT) > 0) {
1964 if (current_container.DefaultPropName != null)
1965 Report.Error (30359,
1967 "Type '" + current_container.Name +
1968 "' cannot have more than one 'Default Property' ");
1970 current_container.DefaultPropName = (string) $2;
1973 get_implicit_value_parameter_type =
1974 ($5 == null) ? (($3 == null) ?
1975 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1976 get_implicit_value_parameter_name = (string) $2;
1978 current_local_parameters = (Parameters) $4;
1979 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1980 get_parameters = current_local_parameters.Copy (lexer.Location);
1981 set_parameters = current_local_parameters.Copy (lexer.Location);
1985 get_parameters = Parameters.EmptyReadOnlyParameters;
1986 set_parameters = new Parameters (null, null ,lexer.Location);
1988 lexer.PropertyParsing = true;
1990 $$ = lexer.Location;
1992 accessor_declarations
1993 END PROPERTY logical_end_of_line
1995 lexer.PropertyParsing = false;
1998 Pair pair = (Pair) $9;
2000 Accessor get_block = null;
2001 Accessor set_block = null;
2003 if (pair.First != null){
2004 get_block = (Accessor) pair.First;
2007 if (pair.Second != null) {
2008 set_block = (Accessor) pair.Second;
2011 Location loc = lexer.Location;
2013 // Structure members are Public by default
2014 if ((current_container is Struct) && (current_modifiers == 0))
2015 current_modifiers = Modifiers.PUBLIC;
2017 prop = new Property ((Expression) get_implicit_value_parameter_type,
2018 (string) $2, current_modifiers, get_block, set_block,
2019 current_attributes, loc, set_implicit_value_parameter_name,
2020 get_parameters, set_parameters, (ArrayList) $6);
2022 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
2023 get_implicit_value_parameter_type = null;
2024 set_implicit_value_parameter_type = null;
2025 get_parameters = null;
2026 set_parameters = null;
2027 current_local_parameters = null;
2031 opt_property_parameters
2034 $$ = Parameters.EmptyReadOnlyParameters;
2036 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2042 opt_implement_clause
2047 | IMPLEMENTS implement_clause_list
2053 implement_clause_list
2054 : qualified_identifier
2056 ArrayList impl_list = new ArrayList ();
2057 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
2060 | implement_clause_list COMMA qualified_identifier
2062 ArrayList impl_list = (ArrayList) $1;
2063 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
2069 accessor_declarations
2070 : get_accessor_declaration opt_set_accessor_declaration
2072 $$ = new Pair ($1, $2);
2074 | set_accessor_declaration opt_get_accessor_declaration
2076 $$ = new Pair ($2, $1);
2080 opt_get_accessor_declaration
2081 : /* empty */ { $$ = null; }
2082 | get_accessor_declaration
2085 opt_set_accessor_declaration
2086 : /* empty */ { $$ = null; }
2087 | set_accessor_declaration
2090 get_accessor_declaration
2091 : opt_attributes GET logical_end_of_line
2093 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
2094 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
2096 current_local_parameters = get_parameters;
2098 lexer.PropertyParsing = false;
2101 // Add local var declaration
2103 ArrayList retval = new ArrayList ();
2104 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
2105 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
2108 END GET logical_end_of_line
2110 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2111 current_local_parameters = null;
2112 lexer.PropertyParsing = true;
2116 set_accessor_declaration
2117 : opt_attributes SET opt_set_parameter logical_end_of_line
2119 if ((current_modifiers & Modifiers.READONLY) != 0)
2120 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
2122 Parameter implicit_value_parameter = new Parameter (
2123 set_implicit_value_parameter_type,
2124 set_implicit_value_parameter_name,
2125 Parameter.Modifier.NONE, null);
2127 current_local_parameters = set_parameters;
2128 current_local_parameters.AppendParameter (implicit_value_parameter);
2131 lexer.PropertyParsing = false;
2134 END SET logical_end_of_line
2136 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2137 current_local_parameters = null;
2138 lexer.PropertyParsing = true;
2145 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2146 set_implicit_value_parameter_name = "Value";
2148 |OPEN_PARENS CLOSE_PARENS
2150 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2151 set_implicit_value_parameter_name = "Value";
2153 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2155 Parameter.Modifier pm = (Parameter.Modifier)$2;
2156 if ((pm | Parameter.Modifier.VAL) != 0)
2157 Report.Error (31065,
2159 "Set cannot have a paremeter modifier other than 'ByVal'");
2161 set_implicit_value_parameter_type = (Expression) $4;
2163 if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
2164 Report.Error (31064,
2166 "Set value parameter type can not be different from property type");
2169 set_implicit_value_parameter_name = (string) $3;
2171 set_implicit_value_parameter_name = "Value";
2177 variable_declarators logical_end_of_line
2179 int mod = (int) current_modifiers;
2181 VariableDeclaration.FixupTypes ((ArrayList) $2);
2182 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2184 if (current_container is Module)
2185 mod = mod | Modifiers.STATIC;
2187 // Structure members are Public by default
2188 if ((current_container is Struct) && (mod == 0))
2189 mod = Modifiers.PUBLIC;
2191 if ((mod & Modifiers.Accessibility) == 0)
2192 mod |= Modifiers.PRIVATE;
2194 foreach (VariableDeclaration var in (ArrayList) $2){
2195 Location l = var.Location;
2196 Field field = new Field (var.type, mod, var.identifier,
2197 var.expression_or_array_initializer,
2198 (Attributes) null, l);
2200 CheckDef (current_container.AddField (field), field.Name, l);
2205 withevents_declaration
2206 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2208 // Module members are static by default, but delegates *can't* be declared static
2209 // so we must fix it, if mbas was the one actually responsible for this
2210 // instead of triggering an error.
2211 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2212 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2214 /* WithEvents Fields must be resolved into properties
2215 with a bit of magic behind the scenes */
2217 VariableDeclaration.FixupTypes ((ArrayList) $3);
2219 foreach (VariableDeclaration var in (ArrayList) $3) {
2220 // 1 - We create a private field
2221 Location l = var.Location;
2223 if ((current_modifiers & Modifiers.STATIC) > 0)
2224 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2226 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2227 var.expression_or_array_initializer,
2228 (Attributes) null, l);
2230 CheckDef (current_container.AddField (field), field.Name, l);
2232 // 2 - Public property
2234 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2235 field, (int) current_modifiers,
2236 (Attributes) current_attributes, l);
2238 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2248 delegate_declaration
2250 identifier OPEN_PARENS
2251 opt_formal_parameter_list
2255 Location l = lexer.Location;
2256 // Module members are static by default, but delegates *can't* be declared static
2257 // so we must fix it, if mbas was the one actually responsible for this
2258 // instead of triggering an error.
2259 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2260 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2262 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2263 TypeManager.system_void_expr,
2264 (int) current_modifiers,
2265 MakeName ((string) $3), (Parameters) $5,
2266 (Attributes) current_attributes, l);
2268 del.Namespace = current_namespace;
2269 CheckDef (current_container.AddDelegate (del), del.Name, l);
2272 identifier OPEN_PARENS
2273 opt_formal_parameter_list
2274 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2276 Location l = lexer.Location;
2278 // Module members are static by default, but delegates *can't* be declared static
2279 // so we must fix it, if mbas was the one actually responsible for this
2280 // instead of triggering an error.
2281 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2282 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2284 Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2286 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2288 ftype, (int) current_modifiers, MakeName ((string) $3),
2289 (Parameters) $5, (Attributes) current_attributes, l);
2291 del.Namespace = current_namespace;
2292 CheckDef (current_container.AddDelegate (del), del.Name, l);
2297 : /* empty */ { $$ = null; }
2298 | HANDLES evt_handler { $$ = $2; }
2302 : qualified_identifier
2304 $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);
2310 | ME DOT qualified_identifier
2312 $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);
2314 /*| MYBASE DOT qualified_identifier
2316 // FIXME: this is blatantly wrong and crash-prone
2317 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2321 constructor_declaration
2322 : SUB NEW opt_params logical_end_of_line
2324 current_local_parameters = (Parameters) $3;
2326 oob_stack.Push (lexer.Location);
2328 Location l = (Location) oob_stack.Pop ();
2329 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2334 Constructor c = (Constructor) $1;
2335 c.Block = (Block) end_block();
2336 c.ModFlags = (int) current_modifiers;
2337 c.OptAttributes = current_attributes;
2339 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2341 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2342 current_local_parameters = null;
2344 END SUB logical_end_of_line
2347 opt_formal_parameter_list
2350 $$ = Parameters.EmptyReadOnlyParameters;
2352 | formal_parameter_list
2355 //Parameter p = ((Parameters) $1).FixedParameters[0];
2359 formal_parameter_list
2362 ArrayList pars_list = (ArrayList) $1;
2363 Parameter [] pars = null;
2364 Parameter array_parameter = null;
2365 int non_array_count = pars_list.Count;
2366 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2367 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2368 non_array_count = pars_list.Count - 1;
2370 foreach (Parameter par in pars_list)
2371 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2372 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2373 non_array_count = 0;
2374 array_parameter = null;
2377 if (non_array_count > 0) {
2378 pars = new Parameter [non_array_count];
2379 pars_list.CopyTo (0, pars, 0, non_array_count);
2381 $$ = new Parameters (pars, array_parameter, lexer.Location);
2388 ArrayList pars = new ArrayList ();
2393 | parameters COMMA parameter
2395 ArrayList pars = (ArrayList) $1;
2404 opt_parameter_modifier
2405 identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2407 Parameter.Modifier pm = (Parameter.Modifier)$2;
2408 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2411 if (opt_parm && ($7 == null))
2412 Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
2414 if (!opt_parm && ($7 != null))
2415 Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
2417 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2418 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2419 Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
2422 if ((pm & Parameter.Modifier.REF) !=0)
2423 pm |= Parameter.Modifier.ISBYREF;
2425 if ($4 != null && $6 != null && $4 != $6)
2426 Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2428 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2430 string t = ptype.ToString ();
2431 if (t.IndexOf('[') >= 0)
2432 Report.Error (31087, lexer.Location, "Array types specified in too many places");
2434 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
2436 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2437 Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
2438 $$ = new Parameter (ptype, (string) $3, pm,
2439 (Attributes) $1, (Expression) $7, opt_parm);
2443 opt_parameter_modifier
2444 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2445 | parameter_modifiers { $$ = $1; }
2449 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2450 | parameter_modifier { $$ = $1; }
2454 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2455 | BYVAL { $$ = Parameter.Modifier.VAL; }
2456 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2457 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2462 | statement_list end_of_stmt
2467 | statement_list end_of_stmt statement
2471 : declaration_statement
2473 if ($1 != null && (Block) $1 != current_block){
2474 current_block.AddStatement ((Statement) $1);
2475 current_block = (Block) $1;
2478 | embedded_statement
2480 Statement s = (Statement) $1;
2482 current_block.AddStatement ((Statement) $1);
2485 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2487 AddHandler ((Expression) $2, (Expression) $5);
2489 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2491 RemoveHandler ((Expression) $2, (Expression) $5);
2493 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2495 RaiseEvent ((string) $2, (ArrayList) $3);
2497 /* | array_handling_statement */
2498 /* | empty_statement */
2501 Statement s = (Statement) $1;
2503 current_block.AddStatement ((Statement) $1);
2507 opt_raise_event_args
2508 : /* empty */ { $$ = null; }
2509 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2526 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2528 if (!current_block.AddLabel ((string) $1, labeled)){
2529 Location l = lexer.Location;
2530 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2532 current_block.AddStatement (labeled);
2536 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2538 if (!current_block.AddLabel ((string) $1, labeled)){
2539 Location l = lexer.Location;
2540 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2542 current_block.AddStatement (labeled);
2548 : expression_statement
2549 | selection_statement
2550 | iteration_statement
2552 | synclock_statement
2554 | array_handling_statement
2560 $$ = new EmptyStatement ();
2566 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2568 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2569 Expression e = (Expression) $2;
2576 Block b = end_block();
2583 array_handling_statement
2589 : REDIM opt_preserve redim_clauses
2591 ArrayList list = (ArrayList) $3;
2592 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2599 : /* empty */ { $$ = false; }
2600 | PRESERVE { $$ = true; }
2606 ArrayList clauses = new ArrayList ();
2611 | redim_clauses COMMA redim_clause
2613 ArrayList clauses = (ArrayList) ($1);
2621 : invocation_expression
2623 Invocation i = (Invocation) $1;
2624 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2630 : ERASE erase_clauses
2632 ArrayList list = (ArrayList) $2;
2633 foreach(Expression e in list)
2635 Erase r = new Erase (e, lexer.Location);
2644 ArrayList clauses = new ArrayList ();
2649 | erase_clauses COMMA erase_clause
2651 ArrayList clauses = (ArrayList) ($1);
2659 : primary_expression
2664 | continue_statement
2665 | */return_statement
2675 $$ = new Goto (current_block, (string) $2, lexer.Location);
2680 : THROW opt_expression
2682 $$ = new Throw ((Expression) $2, lexer.Location);
2689 $$ = new Exit ((ExitType)$2, lexer.Location);
2694 : DO { $$ = ExitType.DO; }
2695 | FOR { $$ = ExitType.FOR; }
2696 | WHILE { $$ = ExitType.WHILE; }
2697 | SELECT { $$ = ExitType.SELECT; }
2698 | SUB { $$ = ExitType.SUB; }
2699 | FUNCTION { $$ = ExitType.FUNCTION; }
2700 | PROPERTY { $$ = ExitType.PROPERTY; }
2701 | TRY { $$ = ExitType.TRY; }
2704 : RETURN opt_expression
2706 $$ = new Return ((Expression) $2, lexer.Location);
2718 : FOR EACH identifier opt_type_spec IN
2720 oob_stack.Push (lexer.Location);
2722 expression end_of_stmt
2724 Location l = lexer.Location;
2725 LocalVariableReference v = null;
2731 VariableDeclaration decl = new VariableDeclaration ((string) $3,
2732 (Expression) $4, null, lexer.Location, null);
2734 vi = current_block.AddVariable (
2735 (Expression) $4, decl.identifier, current_local_parameters, decl.Location);
2738 if (decl.expression_or_array_initializer is Expression)
2739 expr = (Expression) decl.expression_or_array_initializer;
2740 else if (decl.expression_or_array_initializer == null)
2744 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
2745 expr = new ArrayCreation ((Expression) $4, "", init, decl.Location);
2748 v = new LocalVariableReference (current_block, decl.identifier, l);
2752 Assign a = new Assign (v, expr, decl.Location);
2753 current_block.AddStatement (new StatementExpression (a, lexer.Location));
2758 vi = current_block.GetVariableInfo ((string) $3);
2761 // Get a reference to this variable.
2762 v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
2765 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2774 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2775 Block foreach_block = end_block();
2776 Location l = (Location) oob_stack.Pop ();
2780 f = new Foreach (null, v, (Expression) $7, foreach_block, l);
2784 current_block.AddStatement (f);
2795 if (!UseExtendedSyntax)
2801 if (iterator_container == null){
2802 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2805 iterator_container.SetYields ();
2806 $$ = new Yield ((Expression) $2, lexer.Location);
2811 if (!UseExtendedSyntax)
2817 if (iterator_container == null){
2818 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2821 iterator_container.SetYields ();
2822 $$ = new YieldBreak (lexer.Location);
2828 : SYNCLOCK expression end_of_stmt
2835 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2852 tmp_catch_clauses = (ArrayList) $5;
2861 ArrayList s = new ArrayList ();
2863 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2870 // Now s contains the list of specific catch clauses
2871 // and g contains the general one.
2872 Block b = end_block();
2874 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2881 tmp_block = end_block();
2891 ArrayList s = new ArrayList ();
2892 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2894 if (catch_list != null){
2895 foreach (Catch cc in catch_list) {
2903 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2909 : /* empty */ { $$ = null; }
2916 ArrayList l = new ArrayList ();
2921 | catch_clauses catch_clause
2923 ArrayList l = (ArrayList) $1;
2931 : /* empty */ { $$ = null; }
2936 : /* empty */ { $$ = null; }
2937 | WHEN boolean_expression { $$ = $2; }
2941 : CATCH opt_catch_args opt_when end_of_stmt
2943 Expression type = null;
2947 DictionaryEntry cc = (DictionaryEntry) $2;
2948 type = (Expression) cc.Key;
2949 id = (string) cc.Value;
2952 ArrayList one = new ArrayList ();
2953 Location loc = lexer.Location;
2955 one.Add (new VariableDeclaration (id, type, loc));
2958 current_block = new Block (current_block);
2959 Block b = declare_local_variables (type, one, loc);
2964 opt_statement_list {
2965 Expression type = null;
2967 Block b_catch = current_block;
2970 DictionaryEntry cc = (DictionaryEntry) $2;
2971 type = (Expression) cc.Key;
2972 id = (string) cc.Value;
2976 // FIXME: I can change this for an assignment.
2978 while (current_block != (Block) $1)
2979 current_block = current_block.Parent;
2982 $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, lexer.Location);
2987 : /* empty */ { $$ = null; }
2992 : identifier AS type
2994 $$ = new DictionaryEntry ($3, $1);
3000 : DO opt_do_construct end_of_stmt
3003 oob_stack.Push (lexer.Location);
3006 LOOP opt_do_construct
3008 Expression t_before = (Expression) $2;
3009 Expression t_after = (Expression) $7;
3012 if ((t_before != null) && (t_after != null))
3013 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
3015 if ((t_before == null) && (t_after == null))
3016 t = new BoolLiteral (true);
3018 t = (t_before != null) ? t_before : t_after;
3020 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
3022 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
3023 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
3024 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
3026 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
3031 : /* empty */ { $$ = null; }
3032 | while_or_until boolean_expression
3034 do_type = (DoOptions)$1;
3035 $$ = (Expression) $2;
3040 : WHILE { $$ = DoOptions.WHILE; }
3041 | UNTIL { $$ = DoOptions.UNTIL; }
3048 oob_stack.Push (lexer.Location);
3050 boolean_expression end_of_stmt
3054 Location l = (Location) oob_stack.Pop ();
3055 Block b = end_block();
3056 Expression e = (Expression) $3;
3057 $$ = new While ((Expression) e, (Statement) b, l);
3062 : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
3067 ArrayList VarDeclaration = new ArrayList ();
3068 VarDeclaration.Add (new VariableDeclaration ((string) $2,
3069 (Expression) $3, null, lexer.Location, null));
3071 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
3072 Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3075 oob_stack.Push (lexer.Location);
3081 Block inner_statement = end_block();
3082 Location l = (Location) oob_stack.Pop ();
3083 Expression for_var = (Expression) DecomposeQI ((string)$2, l);
3085 Expression assign_expr = new Assign (for_var, (Expression) $5, l);
3086 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
3087 for_var, (Expression) $7, l);
3088 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
3089 for_var, (Expression) $8, l), l);
3091 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
3092 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
3094 For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
3097 current_block.AddStatement (f);
3106 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
3107 | STEP expression { $$ = $2; }
3116 : if_statement_open opt_then if_statement_rest
3120 | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
3124 Location l = (Location) oob_stack.Pop ();
3125 tmp_expr = (Expression)expr_stack.Pop();
3126 $$ = new If ((Expression) tmp_expr, end_block(), l);
3130 Location l = (Location) oob_stack.Pop ();
3131 tmp_expr = (Expression)expr_stack.Pop();
3132 tmp_block = (Block) tmp_blocks.Pop ();
3133 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3136 | if_statement_open THEN else_pre_embedded_statement
3138 Location l = (Location) oob_stack.Pop ();
3139 tmp_expr = (Expression)expr_stack.Pop();
3140 tmp_block = (Block) tmp_blocks.Pop ();
3141 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
3145 pre_embedded_statement
3146 : embedded_statement
3148 Statement s = (Statement) $1;
3150 current_block.AddStatement ((Statement) $1);
3154 opt_else_pre_embedded_statement
3156 | else_pre_embedded_statement
3159 else_pre_embedded_statement
3162 Block bl = end_block();
3163 tmp_blocks.Push(bl);
3167 | ELSE embedded_statement
3169 Block bl = end_block();
3170 tmp_blocks.Push(bl);
3173 Statement s = (Statement) $2;
3174 current_block.AddStatement ((Statement) $2);
3179 : IF boolean_expression
3181 oob_stack.Push (lexer.Location);
3183 tmp_expr = (Expression) $2;
3184 expr_stack.Push(tmp_expr);
3198 Location l = (Location) oob_stack.Pop ();
3199 Expression expr = (Expression)expr_stack.Pop();
3200 $$ = new If ((Expression) expr, (Statement) end_block(), l);
3206 Block bl = end_block();
3207 tmp_blocks.Push(bl);
3213 Location l = (Location) oob_stack.Pop ();
3214 tmp_expr = (Expression)expr_stack.Pop();
3215 tmp_block = (Block) tmp_blocks.Pop();
3216 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
3220 ELSEIF boolean_expression opt_then
3222 tmp_expr = (Expression) $4;
3223 expr_stack.Push(tmp_expr);
3224 tmp_block = end_block();
3225 tmp_blocks.Push(tmp_block);
3228 else_if_statement_rest
3230 Statement stmt = (Statement) statement_stack.Pop();
3231 Block bl = (Block) tmp_blocks.Pop();
3232 Expression expr = (Expression)expr_stack.Pop();
3233 Location l = (Location) oob_stack.Pop ();
3234 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3239 else_if_statement_rest
3244 Location l = (Location) oob_stack.Pop ();
3246 Expression expr = (Expression)expr_stack.Pop();
3247 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3248 statement_stack.Push(stmt);
3254 Block bl = end_block();
3255 tmp_blocks.Push(bl);
3261 Location l = (Location) oob_stack.Pop ();
3263 Expression expr = (Expression)expr_stack.Pop();
3264 Block bl = (Block)tmp_blocks.Pop();
3265 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3266 statement_stack.Push(stmt);
3270 ELSEIF boolean_expression opt_then
3272 expr_stack.Push((Expression) $4);
3273 Block bl = end_block();
3274 tmp_blocks.Push(bl);
3277 else_if_statement_rest
3279 Location l = (Location) oob_stack.Pop ();
3281 Statement tmp_stmt = (Statement)statement_stack.Pop();
3282 Block bl = (Block) tmp_blocks.Pop();
3283 Expression expr = (Expression)expr_stack.Pop();
3284 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3285 statement_stack.Push(stmt);
3290 : SELECT opt_case expression end_of_stmt
3292 oob_stack.Push (lexer.Location);
3293 switch_stack.Push (current_block);
3298 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3299 current_block = (Block) switch_stack.Pop ();
3304 : /* empty */ { $$ = null; }
3305 | case_sections { $$ = $1; }
3309 : case_sections case_section
3311 ArrayList sections = (ArrayList) $1;
3318 ArrayList sections = new ArrayList ();
3332 : CASE case_clauses ends
3338 //Block topmost = current_block;
3339 Block topmost = end_block();
3341 while (topmost.Implicit)
3342 topmost = topmost.Parent;
3344 // FIXME: This is a horrible hack which MUST go
3345 topmost.statements.Add (new Break (lexer.Location));
3346 $$ = new SwitchSection ((ArrayList) $2, topmost);
3349 /* FIXME: we should somehow flag an error
3350 (BC30321 'Case' cannot follow a 'Case Else'
3351 in the same 'Select' statement.)
3352 if Case Else is not the last of the Case clauses
3359 //Block topmost = current_block;
3360 Block topmost = end_block();
3362 while (topmost.Implicit)
3363 topmost = topmost.Parent;
3365 // FIXME: This is a horrible hack which MUST go
3366 topmost.statements.Add (new Break (lexer.Location));
3368 ArrayList a = new ArrayList();
3369 a.Add (new SwitchLabel (null, lexer.Location));
3370 $$ = new SwitchSection ((ArrayList) a, topmost);
3377 ArrayList labels = new ArrayList ();
3382 | case_clauses COMMA case_clause
3384 ArrayList labels = (ArrayList) ($1);
3392 : opt_is comparison_operator expression
3395 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3417 expression_statement
3418 : statement_expression
3425 statement_expression
3426 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3427 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3428 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3431 object_creation_expression
3432 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3434 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3438 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3442 array_creation_expression
3443 : object_creation_expression opt_rank_specifiers array_initializer
3446 ArrayList dims = new ArrayList();
3448 if (n.Arguments != null) {
3449 foreach (Argument a in n.Arguments) {
3454 Expression atype = n.RequestedType;
3457 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
3459 ArrayList init = (ArrayList) $3;
3460 if (init.Count == 0)
3463 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3464 VariableDeclaration.VBFixIndexList (ref dims);
3465 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3469 string rank = VariableDeclaration.BuildRank (dims);
3470 $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location);
3472 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3477 : object_creation_expression
3478 | array_creation_expression
3481 declaration_statement
3482 : local_variable_declaration
3485 DictionaryEntry de = (DictionaryEntry) $1;
3487 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3490 | local_constant_declaration
3493 DictionaryEntry de = (DictionaryEntry) $1;
3495 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3500 local_variable_declaration
3501 : DIM variable_declarators
3503 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3508 local_constant_declaration
3509 : CONST constant_declarators
3512 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3518 constant_declarators
3519 : constant_declarator
3521 ArrayList decl = new ArrayList ();
3527 | constant_declarators COMMA constant_declarator
3529 ArrayList decls = (ArrayList) $1;
3538 : variable_name opt_type_decl opt_variable_initializer
3540 VarName vname = (VarName) $1;
3541 string varname = (string) vname.Name;
3542 current_rank_specifiers = (ArrayList) vname.Rank;
3543 object varinit = $3;
3544 ArrayList a_dims = null;
3546 if (varinit == null)
3548 30438, lexer.Location, "Constant should have a value"
3551 if (vname.Type != null && $2 != null)
3553 30302, lexer.Location,
3554 "Type character cannot be used with explicit type declaration" );
3556 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3558 if (current_rank_specifiers != null)
3560 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3564 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3568 variable_declarators
3569 : variable_declarator
3571 ArrayList decl = new ArrayList ();
3572 decl.AddRange ((ArrayList) $1);
3575 | variable_declarators COMMA variable_declarator
3577 ArrayList decls = (ArrayList) $1;
3578 decls.AddRange ((ArrayList) $3);
3584 : variable_names opt_type_decl opt_variable_initializer
3586 ArrayList names = (ArrayList) $1;
3587 object varinit = $3;
3588 ArrayList VarDeclarations = new ArrayList();
3590 ArrayList a_dims = null;
3592 if ((names.Count > 1) && (varinit != null))
3594 30671, lexer.Location,
3595 "Multiple variables with single type can not have " +
3596 "a explicit initialization" );
3599 foreach (VarName vname in names)
3601 string varname = (string) vname.Name;
3602 current_rank_specifiers = (ArrayList) vname.Rank;
3606 if(vname.Type != null && $2 != null)
3608 30302, lexer.Location,
3609 "Type character cannot be used with explicit type declaration" );
3611 // Some checking is required for particularly weird declarations
3612 // like Dim a As Integer(,)
3614 vartype = (Expression) ((Pair) $2).First;
3616 /*if ($3 != null && $3 is ArrayList)
3617 Report.Error (205, "End of statement expected.");*/
3619 ArrayList args = (ArrayList) ((Pair) $2).Second;
3620 if (current_rank_specifiers != null)
3621 Report.Error (31087, lexer.Location,
3622 "Array types specified in too many places");
3624 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3625 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3627 current_rank_specifiers = new ArrayList ();
3628 current_rank_specifiers.Add (args);
3631 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3633 // if the variable is an array with explicit bound
3634 // and having explicit initialization throw exception
3635 if (current_rank_specifiers != null && varinit != null)
3637 bool broken = false;
3638 foreach (ArrayList exprs in current_rank_specifiers)
3640 foreach (Expression expr in exprs)
3642 if (!((Expression)expr is EmptyExpression ))
3645 30672, lexer.Location,
3646 "Array declared with explicit bound " +
3647 " can not have explicit initialization");
3658 Check for a declaration like Dim a(2) or Dim a(2,3)
3659 If this is the case, we must generate an ArrayCreationExpression
3660 and, in case, add the initializer after the array has been created.
3662 if (VariableDeclaration.IsArrayDecl (this)) {
3663 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3664 a_dims = (ArrayList) current_rank_specifiers;
3665 VariableDeclaration.VBFixIndexLists (ref a_dims);
3666 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3668 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
3671 if (vartype is New) {
3672 if (varinit != null) {
3673 Report.Error (30205, lexer.Location, "End of statement expected");
3679 vartype = ((New)vartype).RequestedType;
3682 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3684 $$ = VarDeclarations;
3691 ArrayList list = new ArrayList ();
3695 | variable_names COMMA variable_name
3697 ArrayList list = (ArrayList) $1;
3704 : identifier opt_type_character opt_array_name_modifier
3706 $$ = new VarName ($1, $2, $3);
3717 $$ = (Expression) $2;
3723 | AS type rank_specifiers
3725 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
3730 : opt_type_with_ranks
3736 New n = new New ((Expression)$3, null, lexer.Location);
3737 $$ = (Expression) n;
3739 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3741 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3742 $$ = (Expression) n;
3744 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3746 ArrayList args = new ArrayList();
3747 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3750 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3751 $$ = (Expression) n;
3755 opt_array_name_modifier
3756 : /* empty */ { $$ = null; }
3757 | array_type_modifier { $$ = $1; }
3761 : rank_specifiers { $$ = $1; }
3764 opt_variable_initializer
3765 : /* empty */ { $$ = null; }
3766 | ASSIGN variable_initializer { $$ = $2; }
3769 variable_initializer
3782 : OPEN_BRACE CLOSE_BRACE
3784 ArrayList list = new ArrayList ();
3787 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3789 $$ = (ArrayList) $2;
3793 variable_initializer_list
3794 : variable_initializer
3796 ArrayList list = new ArrayList ();
3800 | variable_initializer_list COMMA variable_initializer
3802 ArrayList list = (ArrayList) $1;
3823 ArrayList rs = new ArrayList();
3827 | rank_specifiers rank_specifier
3829 ArrayList rs = (ArrayList) $1;
3836 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
3845 ArrayList ds = new ArrayList();
3846 ds.Add (new EmptyExpression());
3851 ArrayList ds = new ArrayList();
3852 ds.Add ((Expression) $1);
3855 | opt_dim_specifiers COMMA expression
3857 ArrayList ds = (ArrayList) $1;
3858 ds.Add ((Expression) $3);
3861 | opt_dim_specifiers COMMA
3863 ArrayList ds = (ArrayList) $1;
3864 ds.Add (new EmptyExpression());
3874 | parenthesized_expression
3877 | qualified_identifier
3879 string name = (string) $1;
3880 $$ = DecomposeQI (name, lexer.Location);
3882 | get_type_expression
3884 | invocation_expression
3894 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3895 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3896 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3897 | NOTHING { $$ = NullLiteral.Null; }
3901 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3902 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3903 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3908 object v = lexer.Value;
3911 $$ = new IntLiteral ((Int32)v);
3912 else if (v is short)
3913 $$ = new ShortLiteral ((Int16)v);
3915 $$ = new LongLiteral ((Int64)v);
3917 Console.WriteLine ("OOPS. Unexpected result from scanner");
3923 : TRUE { $$ = new BoolLiteral (true); }
3924 | FALSE { $$ = new BoolLiteral (false); }
3927 parenthesized_expression
3928 : OPEN_PARENS expression CLOSE_PARENS
3933 : primary_expression DOT identifier
3936 string id_name = (string)$3;
3937 if (id_name.ToUpper() == "NEW")
3939 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3943 if (with_stack.Count > 0) {
3944 Expression e = (Expression) with_stack.Peek();
3945 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3953 /* | primary_expression DOT NEW
3955 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3957 | predefined_type DOT identifier
3960 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3963 if (with_stack.Count > 0) {
3964 Expression e = (Expression) with_stack.Peek();
3965 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3979 invocation_expression
3980 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3983 Location l = lexer.Location;
3984 Report.Error (1, l, "THIS IS CRAZY");
3986 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3987 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3989 | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3992 Location l = lexer.Location;
3993 Report.Error (1, l, "THIS IS CRAZY");
3995 $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
3996 // Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
4001 : MYBASE DOT IDENTIFIER
4003 string id_name = (string) $3;
4004 if (id_name.ToUpper() == "NEW")
4006 $$ = new BaseAccess (id_name, lexer.Location);
4010 $$ = new BaseAccess ("New", lexer.Location);
4018 The 'argument' rule returns an 'empty' argument
4019 of type NoArg (used for default arguments in invocations)
4020 if no arguments are actually passed.
4022 If there is only one argument and it is o type NoArg,
4023 we return a null (empty) list
4025 ArrayList args = (ArrayList) $1;
4026 if (args.Count == 1 &&
4027 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
4037 ArrayList list = new ArrayList ();
4041 | argument_list COMMA argument
4043 ArrayList list = (ArrayList) $1;
4052 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
4054 | BYREF variable_reference
4056 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
4060 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
4062 | ADDRESSOF expression
4064 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
4069 : expression {/* note ("section 5.4"); */ $$ = $1; }
4074 : conditional_xor_expression { $$ = $1; }
4075 /*| assignment_expression*/
4086 $$ = new This (current_block, lexer.Location);
4090 // FIXME: This is actually somewhat different from Me
4091 // because it is for accessing static (classifier) methods/properties/fields
4092 $$ = new This (current_block, lexer.Location);
4097 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
4101 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
4103 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
4105 | cast_operator OPEN_PARENS expression CLOSE_PARENS
4107 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
4112 : CBOOL { $$ = TypeManager.system_boolean_expr; }
4113 | CBYTE { $$ = TypeManager.system_byte_expr; }
4114 | CCHAR { $$ = TypeManager.system_char_expr; }
4115 | CDATE { $$ = TypeManager.system_date_expr; }
4116 | CDBL { $$ = TypeManager.system_double_expr; }
4117 | CDEC { $$ = TypeManager.system_decimal_expr; }
4118 | CINT { $$ = TypeManager.system_int32_expr; }
4119 | CLNG { $$ = TypeManager.system_int64_expr; }
4120 | COBJ { $$ = TypeManager.system_object_expr; }
4121 | CSHORT { $$ = TypeManager.system_int16_expr; }
4122 | CSNG { $$ = TypeManager.system_single_expr; }
4123 | CSTR { $$ = TypeManager.system_string_expr; }
4127 : GETTYPE OPEN_PARENS type CLOSE_PARENS
4129 $$ = new TypeOf ((Expression) $3, lexer.Location);
4133 exponentiation_expression
4134 : primary_expression
4135 | exponentiation_expression OP_EXP primary_expression
4141 prefixed_unary_expression
4142 : exponentiation_expression
4143 | PLUS prefixed_unary_expression
4145 //FIXME: Is this rule correctly defined ?
4146 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
4148 | MINUS prefixed_unary_expression
4150 //FIXME: Is this rule correctly defined ?
4151 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
4155 multiplicative_expression
4156 : prefixed_unary_expression
4157 | multiplicative_expression STAR prefixed_unary_expression
4159 $$ = new Binary (Binary.Operator.Multiply,
4160 (Expression) $1, (Expression) $3, lexer.Location);
4162 | multiplicative_expression DIV prefixed_unary_expression
4164 $$ = new Binary (Binary.Operator.Division,
4165 (Expression) $1, (Expression) $3, lexer.Location);
4169 integer_division_expression
4170 : multiplicative_expression
4171 | integer_division_expression OP_IDIV multiplicative_expression
4173 //FIXME: Is this right ?
4174 $$ = new Binary (Binary.Operator.Division,
4175 (Expression) $1, (Expression) $3, lexer.Location);
4180 : integer_division_expression
4181 | mod_expression MOD integer_division_expression
4183 $$ = new Binary (Binary.Operator.Modulus,
4184 (Expression) $1, (Expression) $3, lexer.Location);
4190 | additive_expression PLUS mod_expression
4192 $$ = new Binary (Binary.Operator.Addition,
4193 (Expression) $1, (Expression) $3, lexer.Location);
4195 | additive_expression MINUS mod_expression
4197 $$ = new Binary (Binary.Operator.Subtraction,
4198 (Expression) $1, (Expression) $3, lexer.Location);
4203 : additive_expression
4204 | concat_expression OP_CONCAT additive_expression
4206 // FIXME: This should only work for String expressions
4207 // We probably need to use something from the runtime
4208 $$ = new Binary (Binary.Operator.Addition,
4209 (Expression) $1, (Expression) $3, lexer.Location);
4215 | shift_expression OP_SHIFT_LEFT concat_expression
4219 | shift_expression OP_SHIFT_RIGHT concat_expression
4225 relational_expression
4227 | relational_expression ASSIGN shift_expression
4229 $$ = new Binary (Binary.Operator.Equality,
4230 (Expression) $1, (Expression) $3, lexer.Location);
4232 | relational_expression OP_NE shift_expression
4234 $$ = new Binary (Binary.Operator.Inequality,
4235 (Expression) $1, (Expression) $3, lexer.Location);
4237 | relational_expression OP_LT shift_expression
4239 $$ = new Binary (Binary.Operator.LessThan,
4240 (Expression) $1, (Expression) $3, lexer.Location);
4242 | relational_expression OP_GT shift_expression
4244 $$ = new Binary (Binary.Operator.GreaterThan,
4245 (Expression) $1, (Expression) $3, lexer.Location);
4247 | relational_expression OP_LE shift_expression
4249 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4250 (Expression) $1, (Expression) $3, lexer.Location);
4252 | relational_expression OP_GE shift_expression
4254 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4255 (Expression) $1, (Expression) $3, lexer.Location);
4257 | relational_expression IS shift_expression
4259 //FIXME: Should be a different op for reference equality but allows tests to use Is
4260 $$ = new Binary (Binary.Operator.Equality,
4261 (Expression) $1, (Expression) $3, lexer.Location);
4263 | TYPEOF shift_expression IS type
4265 //FIXME: Is this rule correctly defined ?
4266 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4271 : relational_expression
4272 | NOT negation_expression
4274 //FIXME: Is this rule correctly defined ?
4275 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4279 conditional_and_expression
4280 : negation_expression
4281 | conditional_and_expression AND negation_expression
4283 $$ = new Binary (Binary.Operator.LogicalAnd,
4284 (Expression) $1, (Expression) $3, lexer.Location);
4286 | conditional_and_expression ANDALSO negation_expression
4287 { // FIXME: this is likely to be broken
4288 $$ = new Binary (Binary.Operator.LogicalAnd,
4289 (Expression) $1, (Expression) $3, lexer.Location);
4293 conditional_or_expression
4294 : conditional_and_expression
4295 | conditional_or_expression OR conditional_and_expression
4297 $$ = new Binary (Binary.Operator.LogicalOr,
4298 (Expression) $1, (Expression) $3, lexer.Location);
4300 | conditional_or_expression ORELSE conditional_and_expression
4301 { // FIXME: this is likely to be broken
4302 $$ = new Binary (Binary.Operator.LogicalOr,
4303 (Expression) $1, (Expression) $3, lexer.Location);
4307 conditional_xor_expression
4308 : conditional_or_expression
4309 | conditional_xor_expression XOR conditional_or_expression
4311 $$ = new Binary (Binary.Operator.ExclusiveOr,
4312 (Expression) $1, (Expression) $3, lexer.Location);
4316 assignment_expression
4317 : prefixed_unary_expression ASSIGN expression
4319 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4321 | prefixed_unary_expression STAR ASSIGN expression
4323 Location l = lexer.Location;
4325 $$ = new CompoundAssign (
4326 Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
4328 | prefixed_unary_expression DIV ASSIGN expression
4330 Location l = lexer.Location;
4332 $$ = new CompoundAssign (
4333 Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
4335 | prefixed_unary_expression PLUS ASSIGN expression
4337 Location l = lexer.Location;
4339 $$ = new CompoundAssign (
4340 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4342 | prefixed_unary_expression MINUS ASSIGN expression
4344 Location l = lexer.Location;
4346 $$ = new CompoundAssign (
4347 Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
4349 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
4351 Location l = lexer.Location;
4353 $$ = new CompoundAssign (
4354 Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
4356 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
4358 Location l = lexer.Location;
4360 $$ = new CompoundAssign (
4361 Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
4363 | prefixed_unary_expression OP_CONCAT ASSIGN expression
4365 Location l = lexer.Location;
4367 // FIXME should be strings only
4368 $$ = new CompoundAssign (
4369 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4371 | prefixed_unary_expression OP_EXP ASSIGN expression
4373 Location l = lexer.Location;
4375 /* TODO: $$ = new CompoundAssign (
4376 Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
4378 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4380 ArrayList args = new ArrayList();
4381 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4384 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4385 n.isDelegate = true;
4386 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4399 : namespace_or_type_name
4401 $$ = DecomposeQI ((string) $1, lexer.Location);
4410 ArrayList types = new ArrayList ();
4415 | type_list COMMA type
4417 ArrayList types = (ArrayList) $1;
4424 namespace_or_type_name
4425 : qualified_identifier
4429 : OBJECT { $$ = TypeManager.system_object_expr; }
4435 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4436 | DATE { $$ = TypeManager.system_date_expr; }
4437 | CHAR { $$ = TypeManager.system_char_expr; }
4438 | STRING { $$ = TypeManager.system_string_expr; }
4444 | floating_point_type
4445 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4450 | BYTE { $$ = TypeManager.system_byte_expr; }
4451 | SHORT { $$ = TypeManager.system_int16_expr; }
4452 | INTEGER { $$ = TypeManager.system_int32_expr; }
4453 | LONG { $$ = TypeManager.system_int64_expr; }
4457 : SINGLE { $$ = TypeManager.system_single_expr; }
4458 | DOUBLE { $$ = TypeManager.system_double_expr; }
4462 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4464 if(tokenizerController.IsAcceptingTokens)
4466 if(in_external_source)
4467 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4469 in_external_source = true;
4471 lexer.EffectiveSource = (string) $4;
4472 lexer.EffectiveLine = (int) $6;
4476 | HASH IDENTIFIER LITERAL_STRING EOL
4478 if(tokenizerController.IsAcceptingTokens)
4480 string id = ($2 as string);
4482 if(!($2 as string).ToLower().Equals("region"))
4483 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4490 | HASH END IDENTIFIER EOL
4492 if(tokenizerController.IsAcceptingTokens)
4494 if( ($3 as string).ToLower().Equals("externalsource")) {
4495 if(!in_external_source)
4496 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4498 in_external_source = false;
4499 lexer.EffectiveSource = lexer.Source;
4500 lexer.EffectiveLine = lexer.Line;
4503 else if(($3 as string).ToLower().Equals("region")) {
4504 if(in_marked_region > 0)
4507 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4510 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4514 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4516 if(tokenizerController.IsAcceptingTokens)
4523 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4526 ifElseStateMachine.HandleToken(tok);
4528 catch(ApplicationException) {
4529 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4532 boolean_literal opt_then EOL
4534 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4538 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4540 ifElseStateMachine.HandleToken(tok);
4542 catch(ApplicationException) {
4543 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4546 boolean_literal opt_then EOL
4548 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4552 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4554 ifElseStateMachine.HandleToken(tok);
4556 catch(ApplicationException) {
4557 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4562 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4566 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4568 ifElseStateMachine.HandleToken(tok);
4570 catch(ApplicationException) {
4571 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4576 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4580 if(tokenizerController.IsAcceptingTokens)
4581 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4583 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4593 public Tokenizer Lexer {
4599 public static Expression DecomposeQI (string name, Location loc)
4603 if (name.IndexOf ('.') == -1){
4604 return new SimpleName (name, loc);
4606 int pos = name.LastIndexOf (".");
4607 string left = name.Substring (0, pos);
4608 string right = name.Substring (pos + 1);
4610 o = DecomposeQI (left, loc);
4612 return new MemberAccess (o, right, loc);
4616 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4618 Block implicit_block;
4619 ArrayList inits = null;
4622 // We use the `Used' property to check whether statements
4623 // have been added to the current block. If so, we need
4624 // to create another block to contain the new declaration
4625 // otherwise, as an optimization, we use the same block to
4626 // add the declaration.
4628 // FIXME: A further optimization is to check if the statements
4629 // that were added were added as part of the initialization
4630 // below. In which case, no other statements have been executed
4631 // and we might be able to reduce the number of blocks for
4632 // situations like this:
4634 // int j = 1; int k = j + 1;
4637 VariableDeclaration.FixupTypes (variable_declarators);
4639 if (current_block.Used) {
4640 implicit_block = new Block (current_block, true, loc, Location.Null);
4641 implicit_block.AddChildVariableNames (current_block);
4643 implicit_block = current_block;
4645 foreach (VariableDeclaration decl in variable_declarators){
4646 Expression type = decl.type;
4647 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4648 if (decl.expression_or_array_initializer != null){
4650 inits = new ArrayList ();
4657 return implicit_block;
4659 foreach (VariableDeclaration decl in inits){
4662 Expression type = decl.type;
4664 if ((decl.expression_or_array_initializer is Expression) ||
4665 (decl.expression_or_array_initializer is New)) {
4666 expr = (Expression) decl.expression_or_array_initializer;
4668 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4670 expr = new ArrayCreation (type, "", init, decl.Location);
4673 LocalVariableReference var;
4674 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4676 assign = new Assign (var, expr, decl.Location);
4678 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4681 return implicit_block;
4684 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4686 Block implicit_block;
4687 VariableDeclaration.FixupTypes (variable_declarators);
4689 if (current_block.Used)
4690 implicit_block = new Block (current_block, true);
4692 implicit_block = current_block;
4694 foreach (VariableDeclaration decl in variable_declarators){
4695 Expression type = decl.type;
4696 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4697 current_local_parameters, decl.Location);
4700 return implicit_block;
4708 public VarName (object n, object t, object r)
4718 // A class used to pass around variable declarations and constants
4720 public class VariableDeclaration {
4721 public string identifier;
4722 public object expression_or_array_initializer;
4723 public Location Location;
4724 public Attributes OptAttributes;
4725 public Expression type;
4726 public ArrayList dims;
4728 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4730 this.identifier = id;
4731 this.expression_or_array_initializer = eoai;
4733 this.OptAttributes = opt_attrs;
4738 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4742 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4746 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4747 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4751 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4753 // FIXME : This is broken: only the first rank is parsed
4754 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4757 public static void FixupTypes (ArrayList vars)
4759 int varcount = vars.Count;
4760 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4762 if (last_var.type == null)
4763 last_var.type = TypeManager.system_object_expr;
4765 Expression cur_type = last_var.type;
4766 int n = varcount - 1;
4769 VariableDeclaration var = (VariableDeclaration) vars[n--];
4770 if (var.type == null)
4771 var.type = cur_type;
4773 cur_type = var.type;
4777 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4781 if (IndexList != null) {
4782 foreach (Expression e in IndexList)
4783 if (!(e is EmptyExpression)) {
4792 public static bool IndexesSpecified (ArrayList ranks)
4796 if (ranks != null) {
4797 foreach (ArrayList IndexList in ranks) {
4798 if (IndexesSpecifiedInRank (IndexList)) {
4807 public static string StripDims (string varname, ref string d)
4809 string res = varname;
4812 if (varname.IndexOf("[") >= 0) {
4813 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4814 res = varname.Substring(0, varname.IndexOf("["));
4820 public static string StripDims (string varname)
4824 return (StripDims(varname, ref dres));
4827 public static string StripIndexesFromDims (string dims)
4829 StringBuilder sb = new StringBuilder();
4831 foreach (char c in dims)
4832 if (c == ',' || c == ']' || c == '[')
4835 return sb.ToString();
4838 public static string BuildRank (ArrayList rank)
4841 return BuildRank(rank, out allEmpty);
4844 public static string BuildRank (ArrayList rank, out bool allEmpty)
4851 foreach (object e in rank) {
4852 if (!(e is EmptyExpression))
4863 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
4867 bool allEmpty = true;
4868 foreach (ArrayList rank in rank_specifiers) {
4870 res = BuildRank (rank, out tmp) + res;
4874 if (!allEmpty && mustBeEmpty)
4875 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
4880 public static void VBFixIndexList (ref ArrayList IndexList)
4882 if (IndexList != null) {
4883 for (int x = 0; x < IndexList.Count; x++) {
4884 Expression e = (Expression) IndexList[x];
4885 if (!(e is EmptyExpression)) {
4886 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4892 public static bool IsArrayDecl (Parser t)
4894 // return (varname.IndexOf("[") >= 0);
4895 return (t.current_rank_specifiers != null);
4898 public static void VBFixIndexLists (ref ArrayList ranks)
4900 if (ranks != null) {
4901 for (int x = 0; x < ranks.Count; x++) {
4902 ArrayList IndexList = (ArrayList) ranks[x];
4903 VBFixIndexList (ref IndexList);
4908 public static void FixupArrayTypes (ArrayList vars)
4910 int varcount = vars.Count;
4913 foreach (VariableDeclaration var in vars) {
4914 if (var.identifier.EndsWith(",")) {
4915 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4916 var.identifier.LastIndexOf(",")) + "]";
4917 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4918 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4925 public Property BuildSimpleProperty (Expression p_type, string name,
4926 Field p_fld, int mod_flags,
4927 Attributes attrs, Location loc)
4930 Block get_block, set_block;
4931 Accessor acc_set, acc_get;
4932 StatementExpression a_set;
4937 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4938 args = new Parameter [1];
4939 args [0] = implicit_value_parameter;
4941 Parameters set_params = new Parameters (args, null, loc);
4942 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4943 (Expression) new SimpleName("value", loc), loc), loc);
4945 set_block = new Block (current_block, set_params, loc, Location.Null);
4946 set_block.AddStatement ((Statement) a_set);
4947 acc_set = new Accessor (set_block, attrs);
4950 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4951 get_block = new Block (current_block, null, loc, Location.Null);
4952 get_block.AddStatement ((Statement) a_get);
4953 acc_get = new Accessor (get_block, attrs);
4955 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4962 current_block = new Block (current_block, current_local_parameters,
4963 lexer.Location, Location.Null);
4970 while (current_block.Implicit)
4971 current_block = current_block.Parent;
4973 res = current_block;
4975 current_block.SetEndLocation (lexer.Location);
4976 current_block = current_block.Parent;
4981 private void AddHandler (Expression evt_definition, Expression handler_exp)
4983 AddHandler (current_block, evt_definition, handler_exp);
4986 void CheckAttributeTarget (string a)
4990 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4994 Location l = lexer.Location;
4995 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
5000 private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
5002 Expression evt_target;
5003 Location loc = lexer.Location;
5005 Statement addhnd = (Statement) new AddHandler (evt_id,
5009 b.AddStatement (addhnd);
5012 private void RaiseEvent (string evt_name, ArrayList args)
5014 Location loc = lexer.Location;
5016 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
5017 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
5018 current_block.AddStatement (s);
5021 private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
5023 Expression evt_target;
5024 Location loc = lexer.Location;
5026 Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
5029 b.AddStatement (rmhnd);
5033 // This method is used to get at the complete string representation of
5034 // a fully-qualified type name, hiding inside a MemberAccess ;-)
5035 // This is necessary because local_variable_type admits primary_expression
5036 // as the type of the variable. So we do some extra checking
5038 string GetQualifiedIdentifier (Expression expr)
5040 if (expr is SimpleName)
5041 return ((SimpleName)expr).Name;
5042 else if (expr is MemberAccess)
5043 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
5045 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
5049 private void RemoveHandler (Expression evt_definition, Expression handler_exp)
5051 RemoveHandler (current_block, evt_definition, handler_exp);
5054 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
5056 ConstructorInitializer ci = null;
5059 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
5060 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
5062 if (i.expr is BaseAccess) {
5063 BaseAccess ba = (BaseAccess) i.expr;
5064 if (ba.member == "New" || ba.member == ".ctor") {
5065 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
5069 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
5070 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
5078 void Error_ExpectingTypeName (Location l, Expression expr)
5080 if (expr is Invocation){
5081 Report.Error (1002, l, "; expected");
5083 Report.Error (-1, l, "Invalid Type definition");
5087 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
5091 private void ReportError9998()
5093 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
5096 protected override int parse ()
5098 RootContext.InitializeImports(ImportsList);
5099 current_namespace = new Namespace (null, RootContext.RootNamespace);
5100 current_container = RootContext.Tree.Types;
5101 current_container.Namespace = current_namespace;
5102 oob_stack = new Stack ();
5103 switch_stack = new Stack ();
5104 expr_stack = new Stack ();
5105 tmp_blocks = new Stack();
5106 with_stack = new Stack();
5107 statement_stack = new Stack();
5109 allow_global_attribs = true;
5110 expecting_global_attribs = false;
5111 expecting_local_attribs = false;
5112 local_attrib_section_added = false;
5114 UseExtendedSyntax = name.EndsWith(".mbs");
5115 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
5116 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
5117 OptionCompareBinary = InitialOptionCompareBinary;
5119 lexer = new Tokenizer (input, name, defines);
5121 ifElseStateMachine = new IfElseStateMachine();
5122 tokenizerController = new TokenizerController(lexer);
5124 StringBuilder value = new StringBuilder ();
5126 if (yacc_verbose_flag > 0)
5127 yyparse (lexer, new yydebug.yyDebugSimple ());
5133 catch(MBASException e) {
5134 Report.Error(e.code, e.loc, e.Message);
5136 catch (Exception e) {
5137 if (Report.Stacktrace)
5138 Console.WriteLine(e);
5139 Report.Error (29999, lexer.Location, "Parsing error");
5142 RootContext.VerifyImports();
5144 return Report.Errors;
5150 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
5152 catch(ApplicationException) {
5153 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5156 if(in_external_source)
5157 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
5159 if(in_marked_region > 0)
5160 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
5163 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
5166 tokenizerController.PositionTokenizerCursor(tok, expr);
5168 catch(ApplicationException) {
5169 tok = IfElseStateMachine.Token.EOF;
5171 ifElseStateMachine.HandleToken(tok);
5173 catch(ApplicationException) {
5174 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);