3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
5 // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
6 // Anirban Bhattacharjee (banirban@novell.com)
8 // Licensed under the terms of the GNU GPL
10 // Copyright (C) 2001 A Rafael D Teixeira
14 namespace Mono.MonoBASIC
18 using System.Reflection;
19 using System.Collections;
23 public class MBASException : ApplicationException
28 public MBASException(int code, Location loc, string text) : base(text)
36 /// The MonoBASIC Parser
39 public class Parser : GenericParser
44 /// Current block is used to add statements as we find
50 /// Tmp block is used to store block endings in if/select's
55 /// Tmp block is used to store tmp copies of expressions
60 /// Tmp catch is used to store catch clauses in try..catch..finally
62 ArrayList tmp_catch_clauses;
65 /// Current interface is used by the various declaration
66 /// productions in the interface declaration to "add"
67 /// the interfaces as we find them.
69 Interface current_interface;
72 /// This is used by the unary_expression code to resolve
73 /// a name against a parameter.
75 Parameters current_local_parameters;
78 /// This are used when parsing parameters in property
81 Parameters set_parameters;
82 Parameters get_parameters;
85 /// This is used by the sub_header parser to store modifiers
86 /// to be passed to sub/constructor
88 int current_modifiers;
91 /// This is used by the sub_header parser to store attributes
92 /// to be passed to sub/constructor
94 Attributes current_attributes;
97 /// Using during property parsing to describe the implicit
98 /// value parameter that is passed to the "set" accessor
101 string get_implicit_value_parameter_name;
104 // Using during property parsing to describe the implicit
105 // value parameter that is passed to the "set" and "get"accesor
106 // methods (properties and indexers).
108 Expression get_implicit_value_parameter_type;
111 /// Using during property parsing to describe the implicit
112 /// value parameter that is passed to the "set" accessor
115 string set_implicit_value_parameter_name;
118 // Using during property parsing to describe the implicit
119 // value parameter that is passed to the "set" and "get"accesor
120 // methods (properties and indexers).
122 Expression set_implicit_value_parameter_type;
124 Location member_location;
126 // An out-of-band stack.
130 ArrayList current_rank_specifiers;
138 // Expression stack for nested ifs
142 Stack statement_stack;
144 // A stack for With expressions.
149 static public bool InitialOptionExplicit = false;
150 static public bool InitialOptionStrict = false;
151 static public bool InitialOptionCompareBinary = true;
152 static public ArrayList ImportsList = null;
156 bool OptionCompareBinary;
158 static public bool UseExtendedSyntax; // for ".mbs" files
160 bool implicit_modifiers;
162 public override string[] extensions()
164 string [] list = { ".vb", ".mbs" };
168 bool in_external_source = false;
169 int in_marked_region = 0;
171 TokenizerController tokenizerController;
172 IfElseStateMachine ifElseStateMachine;
175 public class IfElseStateMachine {
199 public static Hashtable errStrings = new Hashtable();
202 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
204 static IfElseStateMachine()
206 // FIXME: Fix both the error nos and the error strings.
207 // Currently the error numbers and the error strings are
208 // just placeholders for getting the state-machine going.
210 errStrings.Add(0, "");
211 errStrings.Add(30012, "#If must end with a matching #End If");
212 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
213 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
214 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
215 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
217 errTable[(int)State.START, (int)Token.IF] = 0;
218 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
219 errTable[(int)State.START, (int)Token.ELSE] = 30028;
220 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
221 errTable[(int)State.START, (int)Token.EOF] = 0;
223 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
224 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
225 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
226 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
227 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
229 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
230 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
231 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
232 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
233 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
235 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
236 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
237 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
238 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
239 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
241 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
242 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
243 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
244 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
245 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
248 public IfElseStateMachine()
252 stateStack = new Stack();
253 stateStack.Push(state);
256 // The parameter here need not be qualified with IfElseStateMachine
257 // But it hits a bug in mcs. So temporarily scoping it so that builds
260 public void HandleToken(IfElseStateMachine.Token tok)
262 err = (int) errTable[(int)state, (int)tok];
265 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
267 if(tok == Token.IF) {
268 stateStack.Push(state);
271 else if(tok == Token.ENDIF) {
272 state = (State)stateStack.Pop();
284 public string ErrString {
286 return (string) errStrings[err];
292 public class TokenizerController {
296 public bool CanAcceptTokens;
297 public bool CanSelectBlock;
305 public TokenizerController(Tokenizer lexer)
308 stateStack = new Stack();
310 currentState.CanAcceptTokens = true;
311 currentState.CanSelectBlock = true;
313 stateStack.Push(currentState);
318 return (State)stateStack.Peek();
322 public bool IsAcceptingTokens {
324 return currentState.CanAcceptTokens;
328 public void PositionCursorAtNextPreProcessorDirective()
330 lexer.PositionCursorAtNextPreProcessorDirective();
333 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
335 if(tok == IfElseStateMachine.Token.ENDIF) {
336 currentState = (State)stateStack.Pop();
338 if(currentState.CanAcceptTokens)
341 PositionCursorAtNextPreProcessorDirective();
346 if(tok == IfElseStateMachine.Token.IF) {
347 stateStack.Push(currentState);
349 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
350 currentState.CanSelectBlock = true;
353 if(parentState.CanAcceptTokens &&
354 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
356 currentState.CanAcceptTokens = true;
357 currentState.CanSelectBlock = false;
361 currentState.CanAcceptTokens = false;
362 PositionCursorAtNextPreProcessorDirective();
370 %token NONE /* This token is never returned by our lexer */
371 %token ERROR // This is used not by the parser, but by the tokenizer.
375 *These are the MonoBASIC keywords
467 %token NOTINHERITABLE
468 %token NOTOVERRIDABLE
524 %token YIELD // MonoBASIC extension
528 /* MonoBASIC single character operators/punctuation. */
530 %token OPEN_BRACKET "["
531 %token CLOSE_BRACKET "]"
532 %token OPEN_PARENS "("
533 %token OPEN_BRACE "{"
534 %token CLOSE_BRACE "}"
535 %token CLOSE_PARENS ")"
549 %token OP_IDIV "\\" //FIXME: This should be "\"
551 %token EXCLAMATION "!"
554 %token LONGTYPECHAR "&"
556 %token SINGLETYPECHAR "!"
557 %token NUMBER_SIGN "#"
558 %token DOLAR_SIGN "$"
560 %token ATTR_ASSIGN ":="
562 /* MonoBASIC multi-character operators. */
567 //%token OP_MODULUS //"mod"
568 %token OP_MULT_ASSIGN "*="
569 %token OP_DIV_ASSIGN "/="
570 %token OP_IDIV_ASSIGN "\\="
571 %token OP_ADD_ASSIGN "+="
572 %token OP_SUB_ASSIGN "-="
573 %token OP_CONCAT_ASSIGN "&="
574 %token OP_EXP_ASSIGN "^="
576 /* VB.NET 2003 new bit-shift operators */
577 %token OP_SHIFT_LEFT "<<"
578 %token OP_SHIFT_RIGHT ">>"
581 %token LITERAL_INTEGER "int literal"
582 %token LITERAL_SINGLE "float literal"
583 %token LITERAL_DOUBLE "double literal"
584 %token LITERAL_DECIMAL "decimal literal"
585 %token LITERAL_CHARACTER "character literal"
586 %token LITERAL_STRING "string literal"
587 %token LITERAL_DATE "datetime literal"
591 /* Add precedence rules to solve dangling else s/r conflict */
600 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
602 %left STAR DIV PERCENT
603 %right BITWISE_NOT CARRET UMINUS
604 %nonassoc OP_INC OP_DEC
606 %left OPEN_BRACKET OPEN_BRACE
611 %start compilation_unit
615 : logical_end_of_line
621 | logical_end_of_line pp_directive
625 : logical_end_of_line
626 opt_option_directives
627 opt_imports_directives
637 opt_option_directives
644 | option_directives option_directive
648 : option_explicit_directive
649 | option_strict_directive
650 | option_compare_directive
679 option_explicit_directive
680 : OPTION EXPLICIT on_off logical_end_of_line
682 if (!UseExtendedSyntax)
683 OptionExplicit = (bool)$3;
686 9999, lexer.Location,
687 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
692 option_strict_directive
693 : OPTION STRICT on_off logical_end_of_line
695 if (!UseExtendedSyntax)
696 OptionStrict = (bool)$3;
699 9999, lexer.Location,
700 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
704 option_compare_directive
705 : OPTION COMPARE text_or_binary logical_end_of_line
707 OptionCompareBinary = (bool)$3;
718 | declarations declaration
722 : namespace_declaration
728 if ($1 is Class || $1 is Struct || $1 is Module ){
729 TypeContainer c = (TypeContainer) $1;
730 mod_flags = c.ModFlags;
735 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
737 1527, lexer.Location,
738 "Namespace elements cannot be explicitly " +
739 "declared private or protected in '" + name + "'");
754 : PERCENT { $$ = TypeManager.system_int32_expr; }
755 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
756 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
757 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
758 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
759 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
763 : /* empty */ { $$ = null; }
764 | type_character { $$ = $1; }
770 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
772 $$ = (($1).ToString ()) + "." + ($3.ToString ());
776 opt_imports_directives
783 | imports_directives imports_directive
787 : IMPORTS imports_terms logical_end_of_line
792 | imports_terms COMMA imports_term
796 : namespace_or_type_name
798 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
800 | identifier ASSIGN namespace_or_type_name
802 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
807 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
808 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
809 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
812 global_attribute_list
814 | global_attribute_list COMMA global_attribute
818 : attribute_modifier COLON attribute
825 Report.Error (658, lexer.Location, "`" + (string)$1 + "' is an invalid attribute target");
831 | attributes { $$ = $1; }
843 : attr_begin attribute_list attr_end
845 AttributeSection sect = new AttributeSection (null, (ArrayList) $2);
846 $$ = new Attributes (sect, lexer.Location);
848 | attr_begin global_attribute_list attr_end logical_end_of_line
854 ArrayList attrs = new ArrayList ();
860 | attribute_list COMMA attribute
862 ArrayList attrs = (ArrayList) $1;
874 opt_attribute_arguments
876 $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
881 : namespace_or_type_name
884 opt_attribute_arguments
885 : /* empty */ { $$ = null; }
886 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
892 opt_attribute_arguments_list
894 | attribute_arguments_list
897 attribute_arguments_list
898 : positional_argument_list
900 ArrayList args = new ArrayList ();
905 | positional_argument_list COMMA named_argument_list
907 ArrayList args = new ArrayList ();
913 | named_argument_list
915 ArrayList args = new ArrayList ();
923 positional_argument_list
924 : constant_expression
926 ArrayList args = new ArrayList ();
927 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
931 | positional_argument_list COMMA constant_expression
933 ArrayList args = (ArrayList) $1;
934 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
943 ArrayList args = new ArrayList ();
948 | named_argument_list COMMA named_argument
950 ArrayList args = (ArrayList) $1;
958 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
960 $$ = new DictionaryEntry (
962 new Argument ((Expression) $3, Argument.AType.Expression));
966 namespace_declaration
967 : NAMESPACE qualified_identifier logical_end_of_line
969 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2);
972 END NAMESPACE logical_end_of_line
974 current_namespace = current_namespace.Parent;
982 current_attributes = (Attributes) $1;
983 current_modifiers = (int) $2;
985 type_spec_declaration
988 type_spec_declaration
991 | interface_declaration
992 | delegate_declaration
998 : CLASS identifier logical_end_of_line opt_inherits opt_implements
1000 // Module members are static by default, but Class *can't* be declared static
1001 // so we must fix it, if mbas was the one actually responsible for this
1002 // instead of triggering an error.
1003 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1004 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1009 name = MakeName ((string) $2);
1010 new_class = new Class (current_container, name, current_modifiers,
1011 (Attributes) current_attributes, lexer.Location);
1013 current_container = new_class;
1014 current_container.Namespace = current_namespace;
1015 RootContext.Tree.RecordDecl (name, new_class);
1017 opt_class_member_declarations
1018 END CLASS logical_end_of_line
1020 Class new_class = (Class) current_container;
1022 ArrayList bases = (ArrayList) $4;
1024 ArrayList ifaces = (ArrayList) $5;
1025 if (ifaces != null){
1027 bases.AddRange(ifaces);
1031 new_class.Bases = bases;
1033 current_container = current_container.Parent;
1034 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1041 : /* empty */ { $$ = null; }
1042 | INHERITS type_list logical_end_of_line { $$ = $2; }
1046 : /* empty */ { $$ = null; }
1047 | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
1051 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1052 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1057 | modifiers modifier
1062 if ((m1 & m2) != 0) {
1063 Location l = lexer.Location;
1064 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1066 $$ = (int) (m1 | m2);
1071 : PUBLIC { $$ = Modifiers.PUBLIC; }
1072 | PROTECTED { $$ = Modifiers.PROTECTED; }
1073 | PRIVATE { $$ = Modifiers.PRIVATE; }
1074 | SHARED { $$ = Modifiers.STATIC; }
1075 | FRIEND { $$ = Modifiers.INTERNAL; }
1076 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1077 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1078 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1079 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1080 | OVERLOADS { $$ = Modifiers.NEW; }
1081 | SHADOWS { $$ = Modifiers.SHADOWS; }
1082 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1083 | READONLY { $$ = Modifiers.READONLY; }
1084 | DEFAULT { $$ = Modifiers.DEFAULT; }
1085 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1089 : MODULE identifier logical_end_of_line
1093 name = MakeName((string) $2);
1094 new_module = new Module(current_container,
1096 current_modifiers, // already checks then
1097 (Attributes) current_attributes,
1099 current_container = new_module;
1100 current_container.Namespace = current_namespace;
1101 RootContext.Tree.RecordDecl(name, new_module);
1103 opt_module_member_declarations
1104 END MODULE logical_end_of_line
1106 Module new_module = (Module)current_container;
1108 current_container = current_container.Parent;
1109 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1111 TypeManager.AddStandardModule(new_module);
1117 opt_module_member_declarations
1119 | module_member_declarations
1122 module_member_declarations
1123 : module_member_declaration
1124 | module_member_declarations module_member_declaration
1127 module_member_declaration
1131 current_attributes = (Attributes) $1;
1132 current_modifiers = ((int)$2) | Modifiers.STATIC;
1133 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1134 implicit_modifiers = (!explicit_static);
1136 module_member_declarator
1138 implicit_modifiers = false;
1143 module_member_declarator
1144 : constructor_declaration
1145 | method_declaration
1147 Method method = (Method) $1;
1148 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1151 | withevents_declaration /* This is a field but must be treated specially, see below */
1152 | constant_declaration
1153 | property_declaration
1155 | type_spec_declaration
1158 constant_declaration
1159 : CONST constant_declarators logical_end_of_line
1161 // Module members are static by default, but constants *can't* be declared static
1162 // so we must fix it, if mbas was the one actually responsible for this
1163 // instead of triggering an error.
1164 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1165 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1167 int mod = (int) current_modifiers;
1169 // Structure members are Public by default
1170 if ((current_container is Struct) && (mod == 0))
1171 mod = Modifiers.PUBLIC;
1173 ArrayList consts = (ArrayList) $2;
1174 if(consts.Count > 0)
1176 VariableDeclaration.FixupTypes ((ArrayList) $2);
1177 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1179 foreach (VariableDeclaration var in (ArrayList) $2){
1180 Location l = var.Location;
1181 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1182 (Expression)var.expression_or_array_initializer,
1183 mod, (Attributes) null, l);
1185 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1191 opt_class_member_declarations
1193 | class_member_declarations
1196 class_member_declarations
1197 : class_member_declaration
1198 | class_member_declarations class_member_declaration
1201 class_member_declaration
1205 current_attributes = (Attributes) $1;
1206 current_modifiers = (int) $2;
1208 class_member_declarator
1214 class_member_declarator
1215 : constructor_declaration
1216 | method_declaration
1218 Method method = (Method) $1;
1219 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1222 | constant_declaration
1223 | property_declaration
1225 | withevents_declaration /* This is a field but must be treated specially, see below */
1226 | type_spec_declaration
1233 | must_override_declaration
1236 must_override_declaration
1237 : must_override_sub_declaration
1238 | must_override_func_declaration
1241 must_override_sub_declaration
1242 : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
1244 if (current_container is Module)
1245 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1247 if (current_container is Struct)
1248 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1250 current_modifiers |= Modifiers.ABSTRACT;
1252 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1253 (Parameters) $4, null, (ArrayList) $5, lexer.Location);
1255 if (!(current_container is Class))
1256 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1263 must_override_func_declaration
1264 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1266 Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.
1267 system_object_expr : (Expression) $4 ) : (Expression) $6;
1269 if (current_container is Module)
1270 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1272 if (current_container is Struct)
1273 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1275 current_modifiers |= Modifiers.ABSTRACT;
1277 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1278 (string) $3,(Parameters) $5, null, (ArrayList) $7,
1281 if (!(current_container is Class))
1282 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1289 : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1291 current_local_parameters = (Parameters) $3;
1294 // Structure members are Public by default
1295 if ((current_container is Struct) && (current_modifiers == 0))
1296 current_modifiers = Modifiers.PUBLIC;
1298 member_location = lexer.Location;
1301 END SUB logical_end_of_line
1303 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1304 (Parameters) current_local_parameters, (Attributes) current_attributes,
1305 (ArrayList) $5, member_location);
1307 method.Block = (Block) end_block();
1311 // we have an event handler to take care of
1313 Expression handles_exp = (Expression) $4;
1314 Location loc = lexer.Location;
1316 if (handles_exp is MemberAccess) {
1317 string evt_def = ((MemberAccess)$4).ToString();
1318 int pos = evt_def.LastIndexOf (".");
1319 string evt_target = evt_def.Substring (0, pos);
1322 if (current_container.Properties != null) {
1323 foreach (Property p in current_container.Properties) {
1324 if (p.Name == evt_target) {
1327 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1328 DecomposeQI((string) $2, loc),
1329 DecomposeQI(evt_target, loc), loc);
1331 current_container.AddEventHandler (addhnd);
1339 Report.Error(30506, lexer.Location,
1340 evt_target + " is not declared with WithEvents");
1342 } else if (handles_exp is BaseAccess) {
1343 string evt_id = ((BaseAccess) $4).member;
1344 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1345 DecomposeQI((string) $2, loc),
1346 (Expression) $4, loc);
1348 current_container.AddEventHandler (addhnd);
1356 : FUNCTION identifier opt_type_character
1357 opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1359 current_local_parameters = (Parameters) $4;
1360 member_location = lexer.Location;
1363 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1365 // Structure members are Public by default
1366 if ((current_container is Struct) && (current_modifiers == 0))
1367 current_modifiers = Modifiers.PUBLIC;
1368 // Add local var declaration
1370 ArrayList retval = new ArrayList ();
1371 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1372 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1375 END FUNCTION logical_end_of_line
1377 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1379 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1380 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1381 (ArrayList) $6, member_location);
1382 method.Block = end_block();
1388 : STRUCTURE identifier logical_end_of_line
1389 opt_implement_clause
1392 string full_struct_name = MakeName ((string) $2);
1394 // Module members are static by default, but structures *can't* be declared static
1395 // so we must fix it, if mbas was the one actually responsible for this
1396 // instead of triggering an error.
1397 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1398 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1400 new_struct = new Struct (current_container, full_struct_name,
1401 (int) current_modifiers,
1402 (Attributes) current_attributes, lexer.Location);
1403 current_container = new_struct;
1404 current_container.Namespace = current_namespace;
1405 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1407 opt_struct_member_declarations
1409 Struct new_struct = (Struct) current_container;
1412 new_struct.Bases = (ArrayList) $4;
1414 current_container = current_container.Parent;
1415 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1418 END STRUCTURE logical_end_of_line
1421 opt_struct_member_declarations
1423 | struct_member_declarations
1426 struct_member_declarations
1427 : struct_member_declaration
1428 | struct_member_declarations struct_member_declaration
1431 struct_member_declaration
1433 struct_member_declarator
1436 struct_member_declarator
1438 | constant_declaration
1439 | constructor_declaration
1440 | method_declaration
1442 Method method = (Method) $1;
1443 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1445 | property_declaration
1447 | type_spec_declaration
1450 * This is only included so we can flag error 575:
1451 * destructors only allowed on class types
1453 //| destructor_declaration
1457 : EVENT identifier AS type opt_implement_clause logical_end_of_line
1459 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1461 Event e = new Event ((Expression) $4, var.identifier,
1462 null, current_modifiers, null, null,
1463 current_attributes, (ArrayList) $5,
1466 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1468 | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1470 string delName = null;
1473 delName = (string) $2;
1474 delName = delName + "EventHandler";
1475 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1476 (current_container, TypeManager.system_void_expr,
1477 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1478 (Attributes) current_attributes, lexer.Location);
1480 del.Namespace = current_namespace;
1481 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1483 ArrayList impls = (ArrayList) $4;
1484 if (impls.Count > 1) {
1485 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1486 "' can not be implemented with Event '" +
1487 (string) $2 + "', since it's delegate type does not match " +
1488 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1489 Report.Error (31407, lexer.Location, expstr);
1491 Expression impl = (Expression) impls[0];
1492 delName = impl.ToString();
1493 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1494 delName = delName + "EventHandler";
1497 Event e = new Event (DecomposeQI (delName, lexer.Location),
1499 null, current_modifiers, null, null,
1500 current_attributes, (ArrayList) $4,
1503 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1508 : ENUM identifier opt_type_spec logical_end_of_line
1509 opt_enum_member_declarations
1511 Location enum_location = lexer.Location;
1512 string full_name = MakeName ((string) $2);
1513 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1514 ArrayList enum_members = (ArrayList) $5;
1516 if (enum_members.Count == 0)
1517 Report.Error (30280, enum_location,
1518 "Enum can not have empty member list");
1520 // Module members are static by default, but enums *can't* be declared static
1521 // so we must fix it if mbas was the one actually responsible for this
1522 // instead of triggering an error.
1523 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1524 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1526 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1527 (int) current_modifiers, full_name,
1528 (Attributes) current_attributes, enum_location);
1530 foreach (VariableDeclaration ev in enum_members) {
1531 Location loc = (Location) ev.Location;
1533 CheckDef (e.AddEnumMember (ev.identifier,
1534 (Expression) ev.expression_or_array_initializer,
1535 loc, ev.OptAttributes), ev.identifier, loc);
1538 e.Namespace = current_namespace;
1540 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1541 RootContext.Tree.RecordDecl (full_name, e);
1544 END ENUM logical_end_of_line
1547 opt_enum_member_declarations
1548 : /* empty */ { $$ = new ArrayList (); }
1549 | enum_member_declarations { $$ = $1; }
1552 enum_member_declarations
1553 : enum_member_declaration
1555 ArrayList l = new ArrayList ();
1560 | enum_member_declarations enum_member_declaration
1562 ArrayList l = (ArrayList) $1;
1570 enum_member_declaration
1571 : opt_attributes identifier logical_end_of_line
1573 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1575 | opt_attributes identifier
1577 $$ = lexer.Location;
1579 ASSIGN expression logical_end_of_line
1581 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1585 interface_declaration
1586 : INTERFACE identifier logical_end_of_line
1588 Interface new_interface;
1589 string full_interface_name = MakeName ((string) $2);
1591 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1592 (Attributes) current_attributes, lexer.Location);
1593 if (current_interface != null) {
1594 Location l = lexer.Location;
1595 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1597 current_interface = new_interface;
1598 new_interface.Namespace = current_namespace;
1599 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1604 Interface new_interface = (Interface) current_interface;
1607 new_interface.Bases = (ArrayList) $5;
1609 current_interface = null;
1610 CheckDef (current_container.AddInterface (new_interface),
1611 new_interface.Name, new_interface.Location);
1614 END INTERFACE logical_end_of_line
1618 : /* empty */ { $$ = null; }
1624 | interface_bases interface_base
1626 ArrayList bases = (ArrayList) $1;
1627 bases.AddRange ((ArrayList) $2);
1633 : INHERITS type_list logical_end_of_line { $$ = $2; }
1637 : opt_interface_member_declarations
1640 opt_interface_member_declarations
1642 | interface_member_declarations
1645 interface_member_declarations
1646 : interface_member_declaration
1647 | interface_member_declarations interface_member_declaration
1650 interface_member_declaration
1654 current_attributes = (Attributes) $1;
1655 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
1657 interface_member_declarator
1663 interface_member_declarator
1664 : interface_method_declaration
1666 Method m = (Method) $1;
1667 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1669 | interface_property_declaration
1670 | interface_event_declaration
1673 interface_method_declaration
1674 : SUB identifier opt_params logical_end_of_line
1676 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1677 (Parameters) $3, current_attributes, null, lexer.Location);
1681 | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
1683 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.
1684 system_object_expr : (Expression) $3 ) : (Expression) $5;
1686 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1687 (string) $2,(Parameters) $4, current_attributes, null,
1694 interface_property_declaration
1695 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1697 Expression ftype = ($5 == null) ? (($3 == null) ?
1698 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1700 current_local_parameters = (Parameters) $4;
1701 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1702 get_parameters = current_local_parameters.Copy (lexer.Location);
1703 set_parameters = current_local_parameters.Copy (lexer.Location);
1705 Parameter implicit_value_parameter = new Parameter (
1706 ftype, "Value", Parameter.Modifier.NONE, null);
1708 set_parameters.AppendParameter (implicit_value_parameter);
1712 get_parameters = Parameters.EmptyReadOnlyParameters;
1713 set_parameters = new Parameters (null, null ,lexer.Location);
1715 Parameter implicit_value_parameter = new Parameter (
1716 ftype, "Value", Parameter.Modifier.NONE, null);
1718 set_parameters.AppendParameter (implicit_value_parameter);
1720 lexer.PropertyParsing = true;
1722 Accessor get_block = new Accessor (null, null);
1723 Accessor set_block = new Accessor (null, null);
1725 Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
1726 get_block, set_block, current_attributes, lexer.Location,
1727 null, get_parameters, set_parameters, null);
1729 CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
1731 get_implicit_value_parameter_type = null;
1732 set_implicit_value_parameter_type = null;
1733 get_parameters = null;
1734 set_parameters = null;
1735 current_local_parameters = null;
1739 interface_event_declaration
1740 : EVENT identifier AS type logical_end_of_line
1742 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1744 Event e = new Event ((Expression) $4, var.identifier,
1745 null, current_modifiers, null, null,
1746 current_attributes, lexer.Location);
1748 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1751 | EVENT identifier opt_params logical_end_of_line
1753 string delName = (string) $2;
1754 delName = delName + "EventHandler";
1755 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
1756 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1757 (current_container, TypeManager.system_void_expr,
1758 (int) delModifiers, MakeName(delName), (Parameters) $3,
1759 (Attributes) current_attributes, lexer.Location);
1761 del.Namespace = current_namespace;
1762 CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
1764 Event e = new Event (DecomposeQI (delName, lexer.Location),
1766 null, current_modifiers, null, null,
1767 current_attributes, lexer.Location);
1769 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1773 property_declaration
1774 : abstract_propery_declaration
1775 | non_abstract_propery_declaration
1778 abstract_propery_declaration
1779 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1781 Expression ftype = ($6 == null) ? (($4 == null) ?
1782 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
1784 if (current_container is Module)
1785 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1787 if (current_container is Struct)
1788 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1790 current_modifiers |= Modifiers.ABSTRACT;
1792 current_local_parameters = (Parameters) $5;
1793 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1794 get_parameters = current_local_parameters.Copy (lexer.Location);
1795 set_parameters = current_local_parameters.Copy (lexer.Location);
1797 Parameter implicit_value_parameter = new Parameter (
1798 ftype, "Value", Parameter.Modifier.NONE, null);
1800 set_parameters.AppendParameter (implicit_value_parameter);
1804 get_parameters = Parameters.EmptyReadOnlyParameters;
1805 set_parameters = new Parameters (null, null ,lexer.Location);
1807 Parameter implicit_value_parameter = new Parameter (
1808 ftype, "Value", Parameter.Modifier.NONE, null);
1810 set_parameters.AppendParameter (implicit_value_parameter);
1812 lexer.PropertyParsing = true;
1814 Accessor get_block = new Accessor (null, null);
1815 Accessor set_block = new Accessor (null, null);
1817 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1818 get_block, set_block, current_attributes, lexer.Location,
1819 null, get_parameters, set_parameters, null);
1821 if (!(current_container is Class))
1822 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1824 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1826 get_implicit_value_parameter_type = null;
1827 set_implicit_value_parameter_type = null;
1828 get_parameters = null;
1829 set_parameters = null;
1830 current_local_parameters = null;
1835 non_abstract_propery_declaration
1836 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
1838 get_implicit_value_parameter_type =
1839 ($5 == null) ? (($3 == null) ?
1840 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1841 get_implicit_value_parameter_name = (string) $2;
1843 current_local_parameters = (Parameters) $4;
1844 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1845 get_parameters = current_local_parameters.Copy (lexer.Location);
1846 set_parameters = current_local_parameters.Copy (lexer.Location);
1850 get_parameters = Parameters.EmptyReadOnlyParameters;
1851 set_parameters = new Parameters (null, null ,lexer.Location);
1853 lexer.PropertyParsing = true;
1855 $$ = lexer.Location;
1857 accessor_declarations
1858 END PROPERTY logical_end_of_line
1860 lexer.PropertyParsing = false;
1863 Pair pair = (Pair) $9;
1865 Accessor get_block = null;
1866 Accessor set_block = null;
1868 if (pair.First != null){
1869 get_block = (Accessor) pair.First;
1872 if (pair.Second != null) {
1873 set_block = (Accessor) pair.Second;
1876 Location loc = lexer.Location;
1878 // Structure members are Public by default
1879 if ((current_container is Struct) && (current_modifiers == 0))
1880 current_modifiers = Modifiers.PUBLIC;
1882 prop = new Property ((Expression) get_implicit_value_parameter_type,
1883 (string) $2, current_modifiers, get_block, set_block,
1884 current_attributes, loc, set_implicit_value_parameter_name,
1885 get_parameters, set_parameters, (ArrayList) $6);
1887 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1888 get_implicit_value_parameter_type = null;
1889 set_implicit_value_parameter_type = null;
1890 get_parameters = null;
1891 set_parameters = null;
1892 current_local_parameters = null;
1896 opt_property_parameters
1899 $$ = Parameters.EmptyReadOnlyParameters;
1901 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1907 opt_implement_clause
1912 | IMPLEMENTS implement_clause_list
1918 implement_clause_list
1919 : qualified_identifier
1921 ArrayList impl_list = new ArrayList ();
1922 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
1925 | implement_clause_list COMMA qualified_identifier
1927 ArrayList impl_list = (ArrayList) $1;
1928 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
1934 accessor_declarations
1935 : get_accessor_declaration opt_set_accessor_declaration
1937 $$ = new Pair ($1, $2);
1939 | set_accessor_declaration opt_get_accessor_declaration
1941 $$ = new Pair ($2, $1);
1945 opt_get_accessor_declaration
1946 : /* empty */ { $$ = null; }
1947 | get_accessor_declaration
1950 opt_set_accessor_declaration
1951 : /* empty */ { $$ = null; }
1952 | set_accessor_declaration
1955 get_accessor_declaration
1956 : opt_attributes GET logical_end_of_line
1958 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
1959 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
1961 current_local_parameters = get_parameters;
1963 lexer.PropertyParsing = false;
1966 // Add local var declaration
1968 ArrayList retval = new ArrayList ();
1969 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1970 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1973 END GET logical_end_of_line
1975 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1976 current_local_parameters = null;
1977 lexer.PropertyParsing = true;
1981 set_accessor_declaration
1982 : opt_attributes SET opt_set_parameter logical_end_of_line
1984 if ((current_modifiers & Modifiers.READONLY) != 0)
1985 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
1987 Parameter implicit_value_parameter = new Parameter (
1988 set_implicit_value_parameter_type,
1989 set_implicit_value_parameter_name,
1990 Parameter.Modifier.NONE, null);
1992 current_local_parameters = set_parameters;
1993 current_local_parameters.AppendParameter (implicit_value_parameter);
1996 lexer.PropertyParsing = false;
1999 END SET logical_end_of_line
2001 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2002 current_local_parameters = null;
2003 lexer.PropertyParsing = true;
2010 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2011 set_implicit_value_parameter_name = "Value";
2013 |OPEN_PARENS CLOSE_PARENS
2015 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2016 set_implicit_value_parameter_name = "Value";
2018 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2020 Parameter.Modifier pm = (Parameter.Modifier)$2;
2021 if ((pm | Parameter.Modifier.VAL) != 0)
2022 Report.Error (31065,
2024 "Set cannot have a paremeter modifier other than 'ByVal'");
2026 set_implicit_value_parameter_type = (Expression) $4;
2028 if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
2029 Report.Error (31064,
2031 "Set value parameter type can not be different from property type");
2034 set_implicit_value_parameter_name = (string) $3;
2036 set_implicit_value_parameter_name = "Value";
2042 variable_declarators logical_end_of_line
2044 int mod = (int) current_modifiers;
2046 VariableDeclaration.FixupTypes ((ArrayList) $2);
2047 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2049 if (current_container is Module)
2050 mod = mod | Modifiers.STATIC;
2052 // Structure members are Public by default
2053 if ((current_container is Struct) && (mod == 0))
2054 mod = Modifiers.PUBLIC;
2056 if ((mod & Modifiers.Accessibility) == 0)
2057 mod |= Modifiers.PRIVATE;
2059 foreach (VariableDeclaration var in (ArrayList) $2){
2060 Location l = var.Location;
2061 Field field = new Field (var.type, mod, var.identifier,
2062 var.expression_or_array_initializer,
2063 (Attributes) null, l);
2065 CheckDef (current_container.AddField (field), field.Name, l);
2070 withevents_declaration
2071 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2073 // Module members are static by default, but delegates *can't* be declared static
2074 // so we must fix it, if mbas was the one actually responsible for this
2075 // instead of triggering an error.
2076 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2077 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2079 /* WithEvents Fields must be resolved into properties
2080 with a bit of magic behind the scenes */
2082 VariableDeclaration.FixupTypes ((ArrayList) $3);
2084 foreach (VariableDeclaration var in (ArrayList) $3) {
2085 // 1 - We create a private field
2086 Location l = var.Location;
2088 if ((current_modifiers & Modifiers.STATIC) > 0)
2089 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2091 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2092 var.expression_or_array_initializer,
2093 (Attributes) null, l);
2095 CheckDef (current_container.AddField (field), field.Name, l);
2097 // 2 - Public property
2099 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2100 field, (int) current_modifiers,
2101 (Attributes) current_attributes, l);
2103 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2113 delegate_declaration
2115 identifier OPEN_PARENS
2116 opt_formal_parameter_list
2120 Location l = lexer.Location;
2121 // Module members are static by default, but delegates *can't* be declared static
2122 // so we must fix it, if mbas was the one actually responsible for this
2123 // instead of triggering an error.
2124 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2125 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2127 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2128 TypeManager.system_void_expr,
2129 (int) current_modifiers,
2130 MakeName ((string) $3), (Parameters) $5,
2131 (Attributes) current_attributes, l);
2133 del.Namespace = current_namespace;
2134 CheckDef (current_container.AddDelegate (del), del.Name, l);
2137 identifier OPEN_PARENS
2138 opt_formal_parameter_list
2139 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2141 Location l = lexer.Location;
2143 // Module members are static by default, but delegates *can't* be declared static
2144 // so we must fix it, if mbas was the one actually responsible for this
2145 // instead of triggering an error.
2146 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2147 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2149 Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2151 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2153 ftype, (int) current_modifiers, MakeName ((string) $3),
2154 (Parameters) $5, (Attributes) current_attributes, l);
2156 del.Namespace = current_namespace;
2157 CheckDef (current_container.AddDelegate (del), del.Name, l);
2164 | HANDLES qualified_identifier
2166 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
2173 /*| HANDLES MYBASE DOT qualified_identifier
2175 // FIXME: this is blatantly wrong and crash-prone
2176 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2180 constructor_declaration
2181 : SUB NEW opt_params logical_end_of_line
2183 current_local_parameters = (Parameters) $3;
2185 oob_stack.Push (lexer.Location);
2187 Location l = (Location) oob_stack.Pop ();
2188 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2193 Constructor c = (Constructor) $1;
2194 c.Block = (Block) end_block();
2195 c.ModFlags = (int) current_modifiers;
2196 c.OptAttributes = current_attributes;
2198 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2200 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2201 current_local_parameters = null;
2203 END SUB logical_end_of_line
2206 opt_formal_parameter_list
2209 $$ = Parameters.EmptyReadOnlyParameters;
2211 | formal_parameter_list
2214 //Parameter p = ((Parameters) $1).FixedParameters[0];
2218 formal_parameter_list
2221 ArrayList pars_list = (ArrayList) $1;
2222 Parameter [] pars = null;
2223 Parameter array_parameter = null;
2224 int non_array_count = pars_list.Count;
2225 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2226 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2227 non_array_count = pars_list.Count - 1;
2229 foreach (Parameter par in pars_list)
2230 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2231 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2232 non_array_count = 0;
2233 array_parameter = null;
2236 if (non_array_count > 0) {
2237 pars = new Parameter [non_array_count];
2238 pars_list.CopyTo (pars);
2240 $$ = new Parameters (pars, array_parameter, lexer.Location);
2247 ArrayList pars = new ArrayList ();
2252 | parameters COMMA parameter
2254 ArrayList pars = (ArrayList) $1;
2263 opt_parameter_modifier
2264 identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2266 Parameter.Modifier pm = (Parameter.Modifier)$2;
2267 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2270 if (opt_parm && ($7 == null))
2271 Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
2273 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2274 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2275 Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
2279 if ((pm & Parameter.Modifier.REF) !=0)
2280 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
2282 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
2285 if ($4 != null && $6 != null && $4 != $6)
2286 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2288 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2290 string t = ptype.ToString ();
2291 if (t.IndexOf('[') >= 0)
2292 Report.Error (31087, lexer.Location, "Array types specified in too many places");
2294 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
2296 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2297 Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
2298 $$ = new Parameter (ptype, (string) $3, pm,
2299 (Attributes) $1, (Expression) $7, opt_parm);
2303 opt_parameter_modifier
2304 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2305 | parameter_modifiers { $$ = $1; }
2309 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2310 | parameter_modifier { $$ = $1; }
2314 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2315 | BYVAL { $$ = Parameter.Modifier.VAL; }
2316 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2317 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2322 | statement_list end_of_stmt
2327 | statement_list end_of_stmt statement
2331 declaration_statement
2333 if ($1 != null && (Block) $1 != current_block){
2334 current_block.AddStatement ((Statement) $1);
2335 current_block = (Block) $1;
2338 | embedded_statement
2340 Statement s = (Statement) $1;
2342 current_block.AddStatement ((Statement) $1);
2345 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2347 AddHandler ((Expression) $2, (string) $5);
2349 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2351 RemoveHandler ((Expression) $2, (string) $5);
2353 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2355 RaiseEvent ((string) $2, (ArrayList) $3);
2357 /* | array_handling_statement */
2358 /* | empty_statement */
2361 Statement s = (Statement) $1;
2363 current_block.AddStatement ((Statement) $1);
2367 opt_raise_event_args
2368 : /* empty */ { $$ = null; }
2369 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2386 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2388 if (!current_block.AddLabel ((string) $1, labeled)){
2389 Location l = lexer.Location;
2390 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2392 current_block.AddStatement (labeled);
2396 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2398 if (!current_block.AddLabel ((string) $1, labeled)){
2399 Location l = lexer.Location;
2400 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2402 current_block.AddStatement (labeled);
2408 : expression_statement
2409 | selection_statement
2410 | iteration_statement
2412 | synclock_statement
2414 | array_handling_statement
2420 $$ = new EmptyStatement ();
2426 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2428 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2429 Expression e = (Expression) $2;
2436 Block b = end_block();
2443 array_handling_statement
2449 : REDIM opt_preserve redim_clauses
2451 ArrayList list = (ArrayList) $3;
2452 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2459 : /* empty */ { $$ = false; }
2460 | PRESERVE { $$ = true; }
2466 ArrayList clauses = new ArrayList ();
2471 | redim_clauses COMMA redim_clause
2473 ArrayList clauses = (ArrayList) ($1);
2481 : invocation_expression
2483 Invocation i = (Invocation) $1;
2484 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2490 : ERASE erase_clauses
2492 ArrayList list = (ArrayList) $2;
2493 foreach(Expression e in list)
2495 Erase r = new Erase (e, lexer.Location);
2504 ArrayList clauses = new ArrayList ();
2509 | erase_clauses COMMA erase_clause
2511 ArrayList clauses = (ArrayList) ($1);
2519 : primary_expression
2524 | continue_statement
2525 | */return_statement
2535 $$ = new Goto (current_block, (string) $2, lexer.Location);
2540 : THROW opt_expression
2542 $$ = new Throw ((Expression) $2, lexer.Location);
2549 $$ = new Exit ((ExitType)$2, lexer.Location);
2554 : DO { $$ = ExitType.DO; }
2555 | FOR { $$ = ExitType.FOR; }
2556 | WHILE { $$ = ExitType.WHILE; }
2557 | SELECT { $$ = ExitType.SELECT; }
2558 | SUB { $$ = ExitType.SUB; }
2559 | FUNCTION { $$ = ExitType.FUNCTION; }
2560 | PROPERTY { $$ = ExitType.PROPERTY; }
2561 | TRY { $$ = ExitType.TRY; }
2564 : RETURN opt_expression
2566 $$ = new Return ((Expression) $2, lexer.Location);
2578 : FOR EACH identifier IN
2580 oob_stack.Push (lexer.Location);
2582 expression end_of_stmt
2586 Block foreach_block = current_block;
2587 Location l = lexer.Location;
2588 LocalVariableReference v = null;
2591 vi = foreach_block.GetVariableInfo ((string) $3);
2593 // Get a reference to this variable.
2594 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2597 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2604 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2605 Block foreach_block = end_block();
2606 Location l = (Location) oob_stack.Pop ();
2610 f = new Foreach (null, v, (Expression) $6, foreach_block, l);
2620 if (!UseExtendedSyntax)
2626 if (iterator_container == null){
2627 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2630 iterator_container.SetYields ();
2631 $$ = new Yield ((Expression) $2, lexer.Location);
2636 if (!UseExtendedSyntax)
2642 if (iterator_container == null){
2643 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2646 iterator_container.SetYields ();
2647 $$ = new YieldBreak (lexer.Location);
2653 : SYNCLOCK expression end_of_stmt
2660 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2677 tmp_catch_clauses = (ArrayList) $5;
2686 ArrayList s = new ArrayList ();
2688 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2695 // Now s contains the list of specific catch clauses
2696 // and g contains the general one.
2697 Block b = end_block();
2699 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2706 tmp_block = end_block();
2716 ArrayList s = new ArrayList ();
2717 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2719 if (catch_list != null){
2720 foreach (Catch cc in catch_list) {
2728 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2734 : /* empty */ { $$ = null; }
2741 ArrayList l = new ArrayList ();
2746 | catch_clauses catch_clause
2748 ArrayList l = (ArrayList) $1;
2756 : /* empty */ { $$ = null; }
2761 : CATCH opt_catch_args end_of_stmt
2763 Expression type = null;
2767 DictionaryEntry cc = (DictionaryEntry) $2;
2768 type = (Expression) cc.Key;
2769 id = (string) cc.Value;
2772 ArrayList one = new ArrayList ();
2773 Location loc = lexer.Location;
2775 one.Add (new VariableDeclaration (id, type, loc));
2779 current_block = new Block (current_block);
2780 Block b = declare_local_variables (type, one, loc);
2786 opt_statement_list {
2787 Expression type = null;
2789 Block b_catch = current_block;
2792 DictionaryEntry cc = (DictionaryEntry) $2;
2793 type = (Expression) cc.Key;
2794 id = (string) cc.Value;
2798 // FIXME: I can change this for an assignment.
2800 while (current_block != (Block) $1)
2801 current_block = current_block.Parent;
2805 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2810 : /* empty */ { $$ = null; }
2815 : identifier AS type
2817 $$ = new DictionaryEntry ($3, $1);
2823 : DO opt_do_construct end_of_stmt
2826 oob_stack.Push (lexer.Location);
2829 LOOP opt_do_construct
2831 Expression t_before = (Expression) $2;
2832 Expression t_after = (Expression) $7;
2835 if ((t_before != null) && (t_after != null))
2836 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2838 if ((t_before == null) && (t_after == null))
2839 t = new BoolLiteral (true);
2841 t = (t_before != null) ? t_before : t_after;
2843 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2845 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2846 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2847 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2849 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2854 : /* empty */ { $$ = null; }
2855 | while_or_until boolean_expression
2857 do_type = (DoOptions)$1;
2858 $$ = (Expression) $2;
2863 : WHILE { $$ = DoOptions.WHILE; }
2864 | UNTIL { $$ = DoOptions.UNTIL; }
2871 oob_stack.Push (lexer.Location);
2873 boolean_expression end_of_stmt
2877 Location l = (Location) oob_stack.Pop ();
2878 Block b = end_block();
2879 Expression e = (Expression) $3;
2880 $$ = new While ((Expression) e, (Statement) b, l);
2886 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2893 Block statement = end_block();
2894 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2896 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2897 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2898 for_var, (Expression) $6, lexer.Location);
2899 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2900 for_var, (Expression) $7, lexer.Location), lexer.Location);
2902 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2903 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2905 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2910 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2911 | STEP expression { $$ = $2; }
2920 : if_statement_open opt_then if_statement_rest
2924 | if_statement_open THEN pre_embedded_statement
2926 Location l = (Location) oob_stack.Pop ();
2927 tmp_expr = (Expression)expr_stack.Pop();
2928 $$ = new If ((Expression) tmp_expr, end_block(), l);
2932 pre_embedded_statement
2933 : embedded_statement
2935 Statement s = (Statement) $1;
2937 current_block.AddStatement ((Statement) $1);
2942 : IF boolean_expression
2944 oob_stack.Push (lexer.Location);
2946 tmp_expr = (Expression) $2;
2947 expr_stack.Push(tmp_expr);
2961 Location l = (Location) oob_stack.Pop ();
2962 Expression expr = (Expression)expr_stack.Pop();
2963 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2969 Block bl = end_block();
2970 tmp_blocks.Push(bl);
2976 Location l = (Location) oob_stack.Pop ();
2977 tmp_expr = (Expression)expr_stack.Pop();
2978 tmp_block = (Block) tmp_blocks.Pop();
2979 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2983 ELSEIF boolean_expression opt_then
2985 tmp_expr = (Expression) $4;
2986 expr_stack.Push(tmp_expr);
2987 tmp_block = end_block();
2988 tmp_blocks.Push(tmp_block);
2991 else_if_statement_rest
2993 Statement stmt = (Statement) statement_stack.Pop();
2994 Block bl = (Block) tmp_blocks.Pop();
2995 Expression expr = (Expression)expr_stack.Pop();
2996 Location l = (Location) oob_stack.Pop ();
2997 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3002 else_if_statement_rest
3007 Location l = (Location) oob_stack.Pop ();
3009 Expression expr = (Expression)expr_stack.Pop();
3010 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3011 statement_stack.Push(stmt);
3017 Block bl = end_block();
3018 tmp_blocks.Push(bl);
3024 Location l = (Location) oob_stack.Pop ();
3026 Expression expr = (Expression)expr_stack.Pop();
3027 Block bl = (Block)tmp_blocks.Pop();
3028 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3029 statement_stack.Push(stmt);
3033 ELSEIF boolean_expression opt_then
3035 expr_stack.Push((Expression) $4);
3036 Block bl = end_block();
3037 tmp_blocks.Push(bl);
3040 else_if_statement_rest
3042 Location l = (Location) oob_stack.Pop ();
3044 Statement tmp_stmt = (Statement)statement_stack.Pop();
3045 Block bl = (Block) tmp_blocks.Pop();
3046 Expression expr = (Expression)expr_stack.Pop();
3047 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3048 statement_stack.Push(stmt);
3053 : SELECT opt_case expression end_of_stmt
3055 oob_stack.Push (lexer.Location);
3056 switch_stack.Push (current_block);
3061 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3062 current_block = (Block) switch_stack.Pop ();
3067 : /* empty */ { $$ = null; }
3068 | case_sections { $$ = $1; }
3072 : case_sections case_section
3074 ArrayList sections = (ArrayList) $1;
3081 ArrayList sections = new ArrayList ();
3095 : CASE case_clauses ends
3101 //Block topmost = current_block;
3102 Block topmost = end_block();
3104 while (topmost.Implicit)
3105 topmost = topmost.Parent;
3107 // FIXME: This is a horrible hack which MUST go
3108 topmost.statements.Add (new Break (lexer.Location));
3109 $$ = new SwitchSection ((ArrayList) $2, topmost);
3112 /* FIXME: we should somehow flag an error
3113 (BC30321 'Case' cannot follow a 'Case Else'
3114 in the same 'Select' statement.)
3115 if Case Else is not the last of the Case clauses
3122 //Block topmost = current_block;
3123 Block topmost = end_block();
3125 while (topmost.Implicit)
3126 topmost = topmost.Parent;
3128 // FIXME: This is a horrible hack which MUST go
3129 topmost.statements.Add (new Break (lexer.Location));
3131 ArrayList a = new ArrayList();
3132 a.Add (new SwitchLabel (null, lexer.Location));
3133 $$ = new SwitchSection ((ArrayList) a, topmost);
3140 ArrayList labels = new ArrayList ();
3145 | case_clauses COMMA case_clause
3147 ArrayList labels = (ArrayList) ($1);
3155 : opt_is comparison_operator expression
3158 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3180 expression_statement
3181 : statement_expression
3188 statement_expression
3189 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3190 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3191 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3194 object_creation_expression
3195 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3197 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3201 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3205 array_creation_expression
3206 : object_creation_expression opt_rank_specifiers array_initializer
3209 ArrayList dims = new ArrayList();
3211 if (n.Arguments != null) {
3212 foreach (Argument a in n.Arguments) {
3217 Expression atype = n.RequestedType;
3220 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
3222 ArrayList init = (ArrayList) $3;
3223 if (init.Count == 0)
3226 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3227 VariableDeclaration.VBFixIndexList (ref dims);
3228 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3232 string rank = VariableDeclaration.BuildRank (dims);
3233 $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location);
3235 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3240 : object_creation_expression
3241 | array_creation_expression
3244 declaration_statement
3245 : local_variable_declaration
3248 DictionaryEntry de = (DictionaryEntry) $1;
3250 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3253 | local_constant_declaration
3256 DictionaryEntry de = (DictionaryEntry) $1;
3258 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3263 local_variable_declaration
3264 : DIM variable_declarators
3266 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3271 local_constant_declaration
3272 : CONST constant_declarators
3275 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3281 constant_declarators
3282 : constant_declarator
3284 ArrayList decl = new ArrayList ();
3290 | constant_declarators COMMA constant_declarator
3292 ArrayList decls = (ArrayList) $1;
3301 : variable_name opt_type_decl opt_variable_initializer
3303 VarName vname = (VarName) $1;
3304 string varname = (string) vname.Name;
3305 current_rank_specifiers = (ArrayList) vname.Rank;
3306 object varinit = $3;
3307 ArrayList a_dims = null;
3309 if (varinit == null)
3311 30438, lexer.Location, "Constant should have a value"
3314 if (vname.Type != null && $2 != null)
3316 30302, lexer.Location,
3317 "Type character cannot be used with explicit type declaration" );
3319 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3321 if (current_rank_specifiers != null)
3323 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3327 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3331 variable_declarators
3332 : variable_declarator
3334 ArrayList decl = new ArrayList ();
3335 decl.AddRange ((ArrayList) $1);
3338 | variable_declarators COMMA variable_declarator
3340 ArrayList decls = (ArrayList) $1;
3341 decls.AddRange ((ArrayList) $3);
3347 : variable_names opt_type_decl opt_variable_initializer
3349 ArrayList names = (ArrayList) $1;
3350 object varinit = $3;
3351 ArrayList VarDeclarations = new ArrayList();
3353 ArrayList a_dims = null;
3355 if ((names.Count > 1) && (varinit != null))
3357 30671, lexer.Location,
3358 "Multiple variables with single type can not have " +
3359 "a explicit initialization" );
3362 foreach (VarName vname in names)
3364 string varname = (string) vname.Name;
3365 current_rank_specifiers = (ArrayList) vname.Rank;
3369 if(vname.Type != null && $2 != null)
3371 30302, lexer.Location,
3372 "Type character cannot be used with explicit type declaration" );
3374 // Some checking is required for particularly weird declarations
3375 // like Dim a As Integer(,)
3377 vartype = (Expression) ((Pair) $2).First;
3379 /*if ($3 != null && $3 is ArrayList)
3380 Report.Error (205, "End of statement expected.");*/
3382 ArrayList args = (ArrayList) ((Pair) $2).Second;
3383 if (current_rank_specifiers != null)
3384 Report.Error (31087, lexer.Location,
3385 "Array types specified in too many places");
3387 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3388 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3390 current_rank_specifiers = new ArrayList ();
3391 current_rank_specifiers.Add (args);
3394 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3396 // if the variable is an array with explicit bound
3397 // and having explicit initialization throw exception
3398 if (current_rank_specifiers != null && varinit != null)
3400 bool broken = false;
3401 foreach (ArrayList exprs in current_rank_specifiers)
3403 foreach (Expression expr in exprs)
3405 if (!((Expression)expr is EmptyExpression ))
3408 30672, lexer.Location,
3409 "Array declared with explicit bound " +
3410 " can not have explicit initialization");
3421 Check for a declaration like Dim a(2) or Dim a(2,3)
3422 If this is the case, we must generate an ArrayCreationExpression
3423 and, in case, add the initializer after the array has been created.
3425 if (VariableDeclaration.IsArrayDecl (this)) {
3426 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3427 a_dims = (ArrayList) current_rank_specifiers;
3428 VariableDeclaration.VBFixIndexLists (ref a_dims);
3429 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3431 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
3434 if (vartype is New) {
3435 if (varinit != null) {
3436 Report.Error (30205, lexer.Location, "End of statement expected");
3442 vartype = ((New)vartype).RequestedType;
3445 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3447 $$ = VarDeclarations;
3454 ArrayList list = new ArrayList ();
3458 | variable_names COMMA variable_name
3460 ArrayList list = (ArrayList) $1;
3467 : identifier opt_type_character opt_array_name_modifier
3469 $$ = new VarName ($1, $2, $3);
3480 $$ = (Expression) $2;
3486 | AS type rank_specifiers
3488 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
3493 : opt_type_with_ranks
3499 New n = new New ((Expression)$3, null, lexer.Location);
3500 $$ = (Expression) n;
3502 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3504 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3505 $$ = (Expression) n;
3507 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3509 ArrayList args = new ArrayList();
3510 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3513 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3514 $$ = (Expression) n;
3518 opt_array_name_modifier
3519 : /* empty */ { $$ = null; }
3520 | array_type_modifier { $$ = $1; }
3524 : rank_specifiers { $$ = $1; }
3527 opt_variable_initializer
3528 : /* empty */ { $$ = null; }
3529 | ASSIGN variable_initializer { $$ = $2; }
3532 variable_initializer
3545 : OPEN_BRACE CLOSE_BRACE
3547 ArrayList list = new ArrayList ();
3550 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3552 $$ = (ArrayList) $2;
3556 variable_initializer_list
3557 : variable_initializer
3559 ArrayList list = new ArrayList ();
3563 | variable_initializer_list COMMA variable_initializer
3565 ArrayList list = (ArrayList) $1;
3586 ArrayList rs = new ArrayList();
3590 | rank_specifiers rank_specifier
3592 ArrayList rs = (ArrayList) $1;
3599 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
3608 ArrayList ds = new ArrayList();
3609 ds.Add (new EmptyExpression());
3614 ArrayList ds = new ArrayList();
3615 ds.Add ((Expression) $1);
3618 | opt_dim_specifiers COMMA expression
3620 ArrayList ds = (ArrayList) $1;
3621 ds.Add ((Expression) $3);
3624 | opt_dim_specifiers COMMA
3626 ArrayList ds = (ArrayList) $1;
3627 ds.Add (new EmptyExpression());
3637 | parenthesized_expression
3640 | qualified_identifier
3642 string name = (string) $1;
3643 $$ = DecomposeQI (name, lexer.Location);
3645 //FIXME: address_of_expression is apparently missing here
3646 | get_type_expression
3648 | invocation_expression
3658 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3659 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3660 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3661 | NOTHING { $$ = NullLiteral.Null; }
3665 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3666 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3667 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3672 object v = lexer.Value;
3675 $$ = new IntLiteral ((Int32)v);
3676 else if (v is short)
3677 $$ = new ShortLiteral ((Int16)v);
3679 $$ = new LongLiteral ((Int64)v);
3681 Console.WriteLine ("OOPS. Unexpected result from scanner");
3687 : TRUE { $$ = new BoolLiteral (true); }
3688 | FALSE { $$ = new BoolLiteral (false); }
3691 parenthesized_expression
3692 : OPEN_PARENS expression CLOSE_PARENS
3697 : primary_expression DOT identifier
3700 string id_name = (string)$3;
3701 if (id_name.ToUpper() == "NEW")
3703 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3707 if (with_stack.Count > 0) {
3708 Expression e = (Expression) with_stack.Peek();
3709 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3717 /* | primary_expression DOT NEW
3719 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3721 | predefined_type DOT identifier
3724 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3727 if (with_stack.Count > 0) {
3728 Expression e = (Expression) with_stack.Peek();
3729 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3743 invocation_expression
3744 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3747 Location l = lexer.Location;
3748 Report.Error (1, l, "THIS IS CRAZY");
3750 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3751 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3756 : MYBASE DOT IDENTIFIER
3758 string id_name = (string) $3;
3759 if (id_name.ToUpper() == "NEW")
3761 $$ = new BaseAccess (id_name, lexer.Location);
3765 $$ = new BaseAccess ("New", lexer.Location);
3773 The 'argument' rule returns an 'empty' argument
3774 of type NoArg (used for default arguments in invocations)
3775 if no arguments are actually passed.
3777 If there is only one argument and it is o type NoArg,
3778 we return a null (empty) list
3780 ArrayList args = (ArrayList) $1;
3781 if (args.Count == 1 &&
3782 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3792 ArrayList list = new ArrayList ();
3796 | argument_list COMMA argument
3798 ArrayList list = (ArrayList) $1;
3807 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3809 | BYREF variable_reference
3811 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3815 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3817 | ADDRESSOF expression
3819 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
3824 : expression {/* note ("section 5.4"); */ $$ = $1; }
3829 : conditional_xor_expression { $$ = $1; }
3830 /*| assignment_expression*/
3841 $$ = new This (current_block, lexer.Location);
3845 // FIXME: This is actually somewhat different from Me
3846 // because it is for accessing static (classifier) methods/properties/fields
3847 $$ = new This (current_block, lexer.Location);
3852 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
3856 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3858 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3860 | cast_operator OPEN_PARENS expression CLOSE_PARENS
3862 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3867 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3868 | CBYTE { $$ = TypeManager.system_byte_expr; }
3869 | CCHAR { $$ = TypeManager.system_char_expr; }
3870 | CDATE { $$ = TypeManager.system_date_expr; }
3871 | CDBL { $$ = TypeManager.system_double_expr; }
3872 | CDEC { $$ = TypeManager.system_decimal_expr; }
3873 | CINT { $$ = TypeManager.system_int32_expr; }
3874 | CLNG { $$ = TypeManager.system_int64_expr; }
3875 | COBJ { $$ = TypeManager.system_object_expr; }
3876 | CSHORT { $$ = TypeManager.system_int16_expr; }
3877 | CSNG { $$ = TypeManager.system_single_expr; }
3878 | CSTR { $$ = TypeManager.system_string_expr; }
3882 : GETTYPE OPEN_PARENS type CLOSE_PARENS
3884 $$ = new TypeOf ((Expression) $3, lexer.Location);
3888 exponentiation_expression
3889 : primary_expression
3890 | exponentiation_expression OP_EXP primary_expression
3896 prefixed_unary_expression
3897 : exponentiation_expression
3898 | PLUS prefixed_unary_expression
3900 //FIXME: Is this rule correctly defined ?
3901 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3903 | MINUS prefixed_unary_expression
3905 //FIXME: Is this rule correctly defined ?
3906 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3910 multiplicative_expression
3911 : prefixed_unary_expression
3912 | multiplicative_expression STAR prefixed_unary_expression
3914 $$ = new Binary (Binary.Operator.Multiply,
3915 (Expression) $1, (Expression) $3, lexer.Location);
3917 | multiplicative_expression DIV prefixed_unary_expression
3919 $$ = new Binary (Binary.Operator.Division,
3920 (Expression) $1, (Expression) $3, lexer.Location);
3924 integer_division_expression
3925 : multiplicative_expression
3926 | integer_division_expression OP_IDIV multiplicative_expression
3928 //FIXME: Is this right ?
3929 $$ = new Binary (Binary.Operator.Division,
3930 (Expression) $1, (Expression) $3, lexer.Location);
3935 : integer_division_expression
3936 | mod_expression MOD integer_division_expression
3938 $$ = new Binary (Binary.Operator.Modulus,
3939 (Expression) $1, (Expression) $3, lexer.Location);
3945 | additive_expression PLUS mod_expression
3947 $$ = new Binary (Binary.Operator.Addition,
3948 (Expression) $1, (Expression) $3, lexer.Location);
3950 | additive_expression MINUS mod_expression
3952 $$ = new Binary (Binary.Operator.Subtraction,
3953 (Expression) $1, (Expression) $3, lexer.Location);
3958 : additive_expression
3959 | concat_expression OP_CONCAT additive_expression
3961 // FIXME: This should only work for String expressions
3962 // We probably need to use something from the runtime
3963 $$ = new Binary (Binary.Operator.Addition,
3964 (Expression) $1, (Expression) $3, lexer.Location);
3970 | shift_expression OP_SHIFT_LEFT concat_expression
3974 | shift_expression OP_SHIFT_RIGHT concat_expression
3980 relational_expression
3982 | relational_expression ASSIGN shift_expression
3984 $$ = new Binary (Binary.Operator.Equality,
3985 (Expression) $1, (Expression) $3, lexer.Location);
3987 | relational_expression OP_NE shift_expression
3989 $$ = new Binary (Binary.Operator.Inequality,
3990 (Expression) $1, (Expression) $3, lexer.Location);
3992 | relational_expression OP_LT shift_expression
3994 $$ = new Binary (Binary.Operator.LessThan,
3995 (Expression) $1, (Expression) $3, lexer.Location);
3997 | relational_expression OP_GT shift_expression
3999 $$ = new Binary (Binary.Operator.GreaterThan,
4000 (Expression) $1, (Expression) $3, lexer.Location);
4002 | relational_expression OP_LE shift_expression
4004 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4005 (Expression) $1, (Expression) $3, lexer.Location);
4007 | relational_expression OP_GE shift_expression
4009 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4010 (Expression) $1, (Expression) $3, lexer.Location);
4012 | relational_expression IS shift_expression
4014 //FIXME: Should be a different op for reference equality but allows tests to use Is
4015 $$ = new Binary (Binary.Operator.Equality,
4016 (Expression) $1, (Expression) $3, lexer.Location);
4018 | TYPEOF shift_expression IS type
4020 //FIXME: Is this rule correctly defined ?
4021 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4026 : relational_expression
4027 | NOT negation_expression
4029 //FIXME: Is this rule correctly defined ?
4030 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4034 conditional_and_expression
4035 : negation_expression
4036 | conditional_and_expression AND negation_expression
4038 $$ = new Binary (Binary.Operator.LogicalAnd,
4039 (Expression) $1, (Expression) $3, lexer.Location);
4041 | conditional_and_expression ANDALSO negation_expression
4042 { // FIXME: this is likely to be broken
4043 $$ = new Binary (Binary.Operator.LogicalAnd,
4044 (Expression) $1, (Expression) $3, lexer.Location);
4048 conditional_or_expression
4049 : conditional_and_expression
4050 | conditional_or_expression OR conditional_and_expression
4052 $$ = new Binary (Binary.Operator.LogicalOr,
4053 (Expression) $1, (Expression) $3, lexer.Location);
4055 | conditional_or_expression ORELSE conditional_and_expression
4056 { // FIXME: this is likely to be broken
4057 $$ = new Binary (Binary.Operator.LogicalOr,
4058 (Expression) $1, (Expression) $3, lexer.Location);
4062 conditional_xor_expression
4063 : conditional_or_expression
4064 | conditional_xor_expression XOR conditional_or_expression
4066 $$ = new Binary (Binary.Operator.ExclusiveOr,
4067 (Expression) $1, (Expression) $3, lexer.Location);
4071 assignment_expression
4072 : prefixed_unary_expression ASSIGN expression
4074 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4076 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4078 ArrayList args = new ArrayList();
4079 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4082 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4083 n.isDelegate = true;
4084 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4097 : namespace_or_type_name
4099 $$ = DecomposeQI ((string) $1, lexer.Location);
4108 ArrayList types = new ArrayList ();
4113 | type_list COMMA type
4115 ArrayList types = (ArrayList) $1;
4122 namespace_or_type_name
4123 : qualified_identifier
4127 : OBJECT { $$ = TypeManager.system_object_expr; }
4133 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4134 | DATE { $$ = TypeManager.system_date_expr; }
4135 | CHAR { $$ = TypeManager.system_char_expr; }
4136 | STRING { $$ = TypeManager.system_string_expr; }
4142 | floating_point_type
4143 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4148 | BYTE { $$ = TypeManager.system_byte_expr; }
4149 | SHORT { $$ = TypeManager.system_int16_expr; }
4150 | INTEGER { $$ = TypeManager.system_int32_expr; }
4151 | LONG { $$ = TypeManager.system_int64_expr; }
4155 : SINGLE { $$ = TypeManager.system_single_expr; }
4156 | DOUBLE { $$ = TypeManager.system_double_expr; }
4160 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4162 if(tokenizerController.IsAcceptingTokens)
4164 if(in_external_source)
4165 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4167 in_external_source = true;
4169 lexer.EffectiveSource = (string) $4;
4170 lexer.EffectiveLine = (int) $6;
4174 | HASH IDENTIFIER LITERAL_STRING EOL
4176 if(tokenizerController.IsAcceptingTokens)
4178 string id = ($2 as string);
4180 if(!($2 as string).ToLower().Equals("region"))
4181 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4188 | HASH END IDENTIFIER EOL
4190 if(tokenizerController.IsAcceptingTokens)
4192 if( ($3 as string).ToLower().Equals("externalsource")) {
4193 if(!in_external_source)
4194 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4196 in_external_source = false;
4197 lexer.EffectiveSource = lexer.Source;
4198 lexer.EffectiveLine = lexer.Line;
4201 else if(($3 as string).ToLower().Equals("region")) {
4202 if(in_marked_region > 0)
4205 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4208 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4212 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4214 if(tokenizerController.IsAcceptingTokens)
4221 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4224 ifElseStateMachine.HandleToken(tok);
4226 catch(ApplicationException) {
4227 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4230 boolean_literal opt_then EOL
4232 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4236 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4238 ifElseStateMachine.HandleToken(tok);
4240 catch(ApplicationException) {
4241 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4244 boolean_literal opt_then EOL
4246 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4250 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4252 ifElseStateMachine.HandleToken(tok);
4254 catch(ApplicationException) {
4255 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4260 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4264 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4266 ifElseStateMachine.HandleToken(tok);
4268 catch(ApplicationException) {
4269 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4274 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4278 if(tokenizerController.IsAcceptingTokens)
4279 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4281 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4291 public Tokenizer Lexer {
4297 public static Expression DecomposeQI (string name, Location loc)
4301 if (name.IndexOf ('.') == -1){
4302 return new SimpleName (name, loc);
4304 int pos = name.LastIndexOf (".");
4305 string left = name.Substring (0, pos);
4306 string right = name.Substring (pos + 1);
4308 o = DecomposeQI (left, loc);
4310 return new MemberAccess (o, right, loc);
4314 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4316 Block implicit_block;
4317 ArrayList inits = null;
4320 // We use the `Used' property to check whether statements
4321 // have been added to the current block. If so, we need
4322 // to create another block to contain the new declaration
4323 // otherwise, as an optimization, we use the same block to
4324 // add the declaration.
4326 // FIXME: A further optimization is to check if the statements
4327 // that were added were added as part of the initialization
4328 // below. In which case, no other statements have been executed
4329 // and we might be able to reduce the number of blocks for
4330 // situations like this:
4332 // int j = 1; int k = j + 1;
4335 VariableDeclaration.FixupTypes (variable_declarators);
4337 if (current_block.Used) {
4338 implicit_block = new Block (current_block, true, loc, Location.Null);
4339 implicit_block.AddChildVariableNames (current_block);
4341 implicit_block = current_block;
4343 foreach (VariableDeclaration decl in variable_declarators){
4344 Expression type = decl.type;
4345 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4346 if (decl.expression_or_array_initializer != null){
4348 inits = new ArrayList ();
4355 return implicit_block;
4357 foreach (VariableDeclaration decl in inits){
4360 Expression type = decl.type;
4362 if ((decl.expression_or_array_initializer is Expression) ||
4363 (decl.expression_or_array_initializer is New)) {
4364 expr = (Expression) decl.expression_or_array_initializer;
4366 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4368 expr = new ArrayCreation (type, "", init, decl.Location);
4371 LocalVariableReference var;
4372 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4374 assign = new Assign (var, expr, decl.Location);
4376 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4379 return implicit_block;
4382 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4384 Block implicit_block;
4385 VariableDeclaration.FixupTypes (variable_declarators);
4387 if (current_block.Used)
4388 implicit_block = new Block (current_block, true);
4390 implicit_block = current_block;
4392 foreach (VariableDeclaration decl in variable_declarators){
4393 Expression type = decl.type;
4394 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4395 current_local_parameters, decl.Location);
4398 return implicit_block;
4406 public VarName (object n, object t, object r)
4416 // A class used to pass around variable declarations and constants
4418 public class VariableDeclaration {
4419 public string identifier;
4420 public object expression_or_array_initializer;
4421 public Location Location;
4422 public Attributes OptAttributes;
4423 public Expression type;
4424 public ArrayList dims;
4426 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4428 this.identifier = id;
4429 this.expression_or_array_initializer = eoai;
4431 this.OptAttributes = opt_attrs;
4436 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4440 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4444 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4445 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4449 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4451 // FIXME : This is broken: only the first rank is parsed
4452 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4455 public static void FixupTypes (ArrayList vars)
4457 int varcount = vars.Count;
4458 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4460 if (last_var.type == null)
4461 last_var.type = TypeManager.system_object_expr;
4463 Expression cur_type = last_var.type;
4464 int n = varcount - 1;
4467 VariableDeclaration var = (VariableDeclaration) vars[n--];
4468 if (var.type == null)
4469 var.type = cur_type;
4471 cur_type = var.type;
4475 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4479 if (IndexList != null) {
4480 foreach (Expression e in IndexList)
4481 if (!(e is EmptyExpression)) {
4490 public static bool IndexesSpecified (ArrayList ranks)
4494 if (ranks != null) {
4495 foreach (ArrayList IndexList in ranks) {
4496 if (IndexesSpecifiedInRank (IndexList)) {
4505 public static string StripDims (string varname, ref string d)
4507 string res = varname;
4510 if (varname.IndexOf("[") >= 0) {
4511 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4512 res = varname.Substring(0, varname.IndexOf("["));
4518 public static string StripDims (string varname)
4522 return (StripDims(varname, ref dres));
4525 public static string StripIndexesFromDims (string dims)
4527 StringBuilder sb = new StringBuilder();
4529 foreach (char c in dims)
4530 if (c == ',' || c == ']' || c == '[')
4533 return sb.ToString();
4536 public static string BuildRank (ArrayList rank)
4539 return BuildRank(rank, out allEmpty);
4542 public static string BuildRank (ArrayList rank, out bool allEmpty)
4549 foreach (object e in rank) {
4550 if (!(e is EmptyExpression))
4561 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
4565 bool allEmpty = true;
4566 foreach (ArrayList rank in rank_specifiers) {
4568 res = BuildRank (rank, out tmp) + res;
4572 if (!allEmpty && mustBeEmpty)
4573 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
4578 public static void VBFixIndexList (ref ArrayList IndexList)
4580 if (IndexList != null) {
4581 for (int x = 0; x < IndexList.Count; x++) {
4582 Expression e = (Expression) IndexList[x];
4583 if (!(e is EmptyExpression)) {
4584 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4590 public static bool IsArrayDecl (Parser t)
4592 // return (varname.IndexOf("[") >= 0);
4593 return (t.current_rank_specifiers != null);
4596 public static void VBFixIndexLists (ref ArrayList ranks)
4598 if (ranks != null) {
4599 for (int x = 0; x < ranks.Count; x++) {
4600 ArrayList IndexList = (ArrayList) ranks[x];
4601 VBFixIndexList (ref IndexList);
4606 public static void FixupArrayTypes (ArrayList vars)
4608 int varcount = vars.Count;
4611 foreach (VariableDeclaration var in vars) {
4612 if (var.identifier.EndsWith(",")) {
4613 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4614 var.identifier.LastIndexOf(",")) + "]";
4615 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4616 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4623 public Property BuildSimpleProperty (Expression p_type, string name,
4624 Field p_fld, int mod_flags,
4625 Attributes attrs, Location loc)
4628 Block get_block, set_block;
4629 Accessor acc_set, acc_get;
4630 StatementExpression a_set;
4635 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4636 args = new Parameter [1];
4637 args [0] = implicit_value_parameter;
4639 Parameters set_params = new Parameters (args, null, loc);
4640 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4641 (Expression) new SimpleName("value", loc), loc), loc);
4643 set_block = new Block (current_block, set_params, loc, Location.Null);
4644 set_block.AddStatement ((Statement) a_set);
4645 acc_set = new Accessor (set_block, attrs);
4648 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4649 get_block = new Block (current_block, null, loc, Location.Null);
4650 get_block.AddStatement ((Statement) a_get);
4651 acc_get = new Accessor (get_block, attrs);
4653 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4660 current_block = new Block (current_block, current_local_parameters,
4661 lexer.Location, Location.Null);
4668 while (current_block.Implicit)
4669 current_block = current_block.Parent;
4671 res = current_block;
4673 current_block.SetEndLocation (lexer.Location);
4674 current_block = current_block.Parent;
4679 private void AddHandler (Expression evt_definition, string handler_name)
4681 AddHandler (current_block, evt_definition, handler_name);
4684 void CheckAttributeTarget (string a)
4688 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4692 Location l = lexer.Location;
4693 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4698 private void AddHandler (Block b, Expression evt_id, string handler_name)
4700 Location loc = lexer.Location;
4701 string evt_target = evt_id.ToString();
4702 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4703 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4707 private void RaiseEvent (string evt_name, ArrayList args)
4709 Location loc = lexer.Location;
4711 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4712 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4713 current_block.AddStatement (s);
4716 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4718 Location loc = lexer.Location;
4719 string evt_target = evt_definition.ToString();
4720 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4721 Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4726 // This method is used to get at the complete string representation of
4727 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4728 // This is necessary because local_variable_type admits primary_expression
4729 // as the type of the variable. So we do some extra checking
4731 string GetQualifiedIdentifier (Expression expr)
4733 if (expr is SimpleName)
4734 return ((SimpleName)expr).Name;
4735 else if (expr is MemberAccess)
4736 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4738 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4742 private void RemoveHandler (Expression evt_definition, string handler_name)
4744 RemoveHandler (current_block, evt_definition, handler_name);
4747 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4749 ConstructorInitializer ci = null;
4752 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4753 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4755 if (i.expr is BaseAccess) {
4756 BaseAccess ba = (BaseAccess) i.expr;
4757 if (ba.member == "New" || ba.member == ".ctor") {
4758 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4762 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4763 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4771 void Error_ExpectingTypeName (Location l, Expression expr)
4773 if (expr is Invocation){
4774 Report.Error (1002, l, "; expected");
4776 Report.Error (-1, l, "Invalid Type definition");
4780 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4784 private void ReportError9998()
4786 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4789 protected override int parse ()
4791 RootContext.InitializeImports(ImportsList);
4792 current_namespace = new Namespace (null, RootContext.RootNamespace);
4793 current_container = RootContext.Tree.Types;
4794 current_container.Namespace = current_namespace;
4795 oob_stack = new Stack ();
4796 switch_stack = new Stack ();
4797 expr_stack = new Stack ();
4798 tmp_blocks = new Stack();
4799 with_stack = new Stack();
4800 statement_stack = new Stack();
4802 UseExtendedSyntax = name.EndsWith(".mbs");
4803 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4804 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4805 OptionCompareBinary = InitialOptionCompareBinary;
4807 lexer = new Tokenizer (input, name, defines);
4809 ifElseStateMachine = new IfElseStateMachine();
4810 tokenizerController = new TokenizerController(lexer);
4812 StringBuilder value = new StringBuilder ();
4814 if (yacc_verbose_flag)
4815 yyparse (lexer, new yydebug.yyDebugSimple ());
4821 catch(MBASException e) {
4822 Report.Error(e.code, e.loc, e.Message);
4824 catch (Exception e) {
4825 Report.Error (29999, lexer.Location, "Parsing error");
4828 RootContext.VerifyImports();
4830 return Report.Errors;
4836 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
4838 catch(ApplicationException) {
4839 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4842 if(in_external_source)
4843 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
4845 if(in_marked_region > 0)
4846 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
4849 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
4852 tokenizerController.PositionTokenizerCursor(tok, expr);
4854 catch(ApplicationException) {
4855 tok = IfElseStateMachine.Token.EOF;
4857 ifElseStateMachine.HandleToken(tok);
4859 catch(ApplicationException) {
4860 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);