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 string evt_def = ((MemberAccess)$6).ToString();
1314 int pos = evt_def.LastIndexOf (".");
1315 string evt_target = evt_def.Substring (0, pos);
1318 if (current_container.Properties != null) {
1319 foreach (Property p in current_container.Properties) {
1320 if (p.Name == evt_target) {
1321 Location loc = lexer.Location;
1323 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1324 DecomposeQI((string) $2, loc),
1325 DecomposeQI(evt_target, loc), loc);
1327 current_container.AddEventHandler (addhnd);
1335 Report.Error(30506, lexer.Location,
1336 evt_target + " is not declared with WithEvents");
1343 : FUNCTION identifier opt_type_character
1344 opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1346 current_local_parameters = (Parameters) $4;
1347 member_location = lexer.Location;
1350 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1352 // Structure members are Public by default
1353 if ((current_container is Struct) && (current_modifiers == 0))
1354 current_modifiers = Modifiers.PUBLIC;
1355 // Add local var declaration
1357 ArrayList retval = new ArrayList ();
1358 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1359 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1362 END FUNCTION logical_end_of_line
1364 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1366 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1367 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1368 (ArrayList) $6, member_location);
1369 method.Block = end_block();
1375 : STRUCTURE identifier logical_end_of_line
1376 opt_implement_clause
1379 string full_struct_name = MakeName ((string) $2);
1381 // Module members are static by default, but structures *can't* be declared static
1382 // so we must fix it, if mbas was the one actually responsible for this
1383 // instead of triggering an error.
1384 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1385 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1387 new_struct = new Struct (current_container, full_struct_name,
1388 (int) current_modifiers,
1389 (Attributes) current_attributes, lexer.Location);
1390 current_container = new_struct;
1391 current_container.Namespace = current_namespace;
1392 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1394 opt_struct_member_declarations
1396 Struct new_struct = (Struct) current_container;
1399 new_struct.Bases = (ArrayList) $4;
1401 current_container = current_container.Parent;
1402 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1405 END STRUCTURE logical_end_of_line
1408 opt_struct_member_declarations
1410 | struct_member_declarations
1413 struct_member_declarations
1414 : struct_member_declaration
1415 | struct_member_declarations struct_member_declaration
1418 struct_member_declaration
1420 struct_member_declarator
1423 struct_member_declarator
1425 | constant_declaration
1426 | constructor_declaration
1427 | method_declaration
1429 Method method = (Method) $1;
1430 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1432 | property_declaration
1434 | type_spec_declaration
1437 * This is only included so we can flag error 575:
1438 * destructors only allowed on class types
1440 //| destructor_declaration
1444 : EVENT identifier AS type opt_implement_clause logical_end_of_line
1446 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1448 Event e = new Event ((Expression) $4, var.identifier,
1449 null, current_modifiers, null, null,
1450 current_attributes, (ArrayList) $5,
1453 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1455 | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1457 string delName = null;
1460 delName = (string) $2;
1461 delName = delName + "EventHandler";
1462 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1463 (current_container, TypeManager.system_void_expr,
1464 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1465 (Attributes) current_attributes, lexer.Location);
1467 del.Namespace = current_namespace;
1468 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1470 ArrayList impls = (ArrayList) $4;
1471 if (impls.Count > 1) {
1472 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1473 "' can not be implemented with Event '" +
1474 (string) $2 + "', since it's delegate type does not match " +
1475 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1476 Report.Error (31407, lexer.Location, expstr);
1478 Expression impl = (Expression) impls[0];
1479 delName = impl.ToString();
1480 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1481 delName = delName + "EventHandler";
1484 Event e = new Event (DecomposeQI (delName, lexer.Location),
1486 null, current_modifiers, null, null,
1487 current_attributes, (ArrayList) $4,
1490 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1495 : ENUM identifier opt_type_spec logical_end_of_line
1496 opt_enum_member_declarations
1498 Location enum_location = lexer.Location;
1499 string full_name = MakeName ((string) $2);
1500 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1501 ArrayList enum_members = (ArrayList) $5;
1503 if (enum_members.Count == 0)
1504 Report.Error (30280, enum_location,
1505 "Enum can not have empty member list");
1507 // Module members are static by default, but enums *can't* be declared static
1508 // so we must fix it if mbas was the one actually responsible for this
1509 // instead of triggering an error.
1510 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1511 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1513 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1514 (int) current_modifiers, full_name,
1515 (Attributes) current_attributes, enum_location);
1517 foreach (VariableDeclaration ev in enum_members) {
1518 Location loc = (Location) ev.Location;
1520 CheckDef (e.AddEnumMember (ev.identifier,
1521 (Expression) ev.expression_or_array_initializer,
1522 loc, ev.OptAttributes), ev.identifier, loc);
1525 e.Namespace = current_namespace;
1527 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1528 RootContext.Tree.RecordDecl (full_name, e);
1531 END ENUM logical_end_of_line
1534 opt_enum_member_declarations
1535 : /* empty */ { $$ = new ArrayList (); }
1536 | enum_member_declarations { $$ = $1; }
1539 enum_member_declarations
1540 : enum_member_declaration
1542 ArrayList l = new ArrayList ();
1547 | enum_member_declarations enum_member_declaration
1549 ArrayList l = (ArrayList) $1;
1557 enum_member_declaration
1558 : opt_attributes identifier logical_end_of_line
1560 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1562 | opt_attributes identifier
1564 $$ = lexer.Location;
1566 ASSIGN expression logical_end_of_line
1568 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1572 interface_declaration
1573 : INTERFACE identifier logical_end_of_line
1575 Interface new_interface;
1576 string full_interface_name = MakeName ((string) $2);
1578 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1579 (Attributes) current_attributes, lexer.Location);
1580 if (current_interface != null) {
1581 Location l = lexer.Location;
1582 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1584 current_interface = new_interface;
1585 new_interface.Namespace = current_namespace;
1586 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1591 Interface new_interface = (Interface) current_interface;
1594 new_interface.Bases = (ArrayList) $5;
1596 current_interface = null;
1597 CheckDef (current_container.AddInterface (new_interface),
1598 new_interface.Name, new_interface.Location);
1601 END INTERFACE logical_end_of_line
1605 : /* empty */ { $$ = null; }
1611 | interface_bases interface_base
1613 ArrayList bases = (ArrayList) $1;
1614 bases.AddRange ((ArrayList) $2);
1620 : INHERITS type_list logical_end_of_line { $$ = $2; }
1624 : opt_interface_member_declarations
1627 opt_interface_member_declarations
1629 | interface_member_declarations
1632 interface_member_declarations
1633 : interface_member_declaration
1634 | interface_member_declarations interface_member_declaration
1637 interface_member_declaration
1641 current_attributes = (Attributes) $1;
1642 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
1644 interface_member_declarator
1650 interface_member_declarator
1651 : interface_method_declaration
1653 Method m = (Method) $1;
1654 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1656 | interface_property_declaration
1657 | interface_event_declaration
1660 interface_method_declaration
1661 : SUB identifier opt_params logical_end_of_line
1663 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1664 (Parameters) $3, current_attributes, null, lexer.Location);
1668 | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
1670 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.
1671 system_object_expr : (Expression) $3 ) : (Expression) $5;
1673 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1674 (string) $2,(Parameters) $4, current_attributes, null,
1681 interface_property_declaration
1682 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line
1684 Expression ftype = ($5 == null) ? (($3 == null) ?
1685 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1687 current_local_parameters = (Parameters) $4;
1688 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1689 get_parameters = current_local_parameters.Copy (lexer.Location);
1690 set_parameters = current_local_parameters.Copy (lexer.Location);
1692 Parameter implicit_value_parameter = new Parameter (
1693 ftype, "Value", Parameter.Modifier.NONE, null);
1695 set_parameters.AppendParameter (implicit_value_parameter);
1699 get_parameters = Parameters.EmptyReadOnlyParameters;
1700 set_parameters = new Parameters (null, null ,lexer.Location);
1702 Parameter implicit_value_parameter = new Parameter (
1703 ftype, "Value", Parameter.Modifier.NONE, null);
1705 set_parameters.AppendParameter (implicit_value_parameter);
1707 lexer.PropertyParsing = true;
1709 Accessor get_block = new Accessor (null, null);
1710 Accessor set_block = new Accessor (null, null);
1712 Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
1713 get_block, set_block, current_attributes, lexer.Location,
1714 null, get_parameters, set_parameters, null);
1716 CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
1718 get_implicit_value_parameter_type = null;
1719 set_implicit_value_parameter_type = null;
1720 get_parameters = null;
1721 set_parameters = null;
1722 current_local_parameters = null;
1726 interface_event_declaration
1727 : EVENT identifier AS type logical_end_of_line
1729 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1731 Event e = new Event ((Expression) $4, var.identifier,
1732 null, current_modifiers, null, null,
1733 current_attributes, lexer.Location);
1735 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1738 | EVENT identifier opt_params logical_end_of_line
1740 string delName = (string) $2;
1741 delName = delName + "EventHandler";
1742 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
1743 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1744 (current_container, TypeManager.system_void_expr,
1745 (int) delModifiers, MakeName(delName), (Parameters) $3,
1746 (Attributes) current_attributes, lexer.Location);
1748 del.Namespace = current_namespace;
1749 CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
1751 Event e = new Event (DecomposeQI (delName, lexer.Location),
1753 null, current_modifiers, null, null,
1754 current_attributes, lexer.Location);
1756 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1760 property_declaration
1761 : abstract_propery_declaration
1762 | non_abstract_propery_declaration
1765 abstract_propery_declaration
1766 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line
1768 Expression ftype = ($6 == null) ? (($4 == null) ?
1769 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
1771 if (current_container is Module)
1772 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1774 if (current_container is Struct)
1775 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1777 current_modifiers |= Modifiers.ABSTRACT;
1779 current_local_parameters = (Parameters) $5;
1780 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1781 get_parameters = current_local_parameters.Copy (lexer.Location);
1782 set_parameters = current_local_parameters.Copy (lexer.Location);
1784 Parameter implicit_value_parameter = new Parameter (
1785 ftype, "Value", Parameter.Modifier.NONE, null);
1787 set_parameters.AppendParameter (implicit_value_parameter);
1791 get_parameters = Parameters.EmptyReadOnlyParameters;
1792 set_parameters = new Parameters (null, null ,lexer.Location);
1794 Parameter implicit_value_parameter = new Parameter (
1795 ftype, "Value", Parameter.Modifier.NONE, null);
1797 set_parameters.AppendParameter (implicit_value_parameter);
1799 lexer.PropertyParsing = true;
1801 Accessor get_block = new Accessor (null, null);
1802 Accessor set_block = new Accessor (null, null);
1804 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1805 get_block, set_block, current_attributes, lexer.Location,
1806 null, get_parameters, set_parameters, null);
1808 if (!(current_container is Class))
1809 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1811 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1813 get_implicit_value_parameter_type = null;
1814 set_implicit_value_parameter_type = null;
1815 get_parameters = null;
1816 set_parameters = null;
1817 current_local_parameters = null;
1822 non_abstract_propery_declaration
1823 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec opt_implement_clause logical_end_of_line
1825 get_implicit_value_parameter_type =
1826 ($5 == null) ? (($3 == null) ?
1827 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1828 get_implicit_value_parameter_name = (string) $2;
1830 current_local_parameters = (Parameters) $4;
1831 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1832 get_parameters = current_local_parameters.Copy (lexer.Location);
1833 set_parameters = current_local_parameters.Copy (lexer.Location);
1837 get_parameters = Parameters.EmptyReadOnlyParameters;
1838 set_parameters = new Parameters (null, null ,lexer.Location);
1840 lexer.PropertyParsing = true;
1842 $$ = lexer.Location;
1844 accessor_declarations
1845 END PROPERTY logical_end_of_line
1847 lexer.PropertyParsing = false;
1850 Pair pair = (Pair) $9;
1852 Accessor get_block = null;
1853 Accessor set_block = null;
1855 if (pair.First != null){
1856 get_block = (Accessor) pair.First;
1859 if (pair.Second != null) {
1860 set_block = (Accessor) pair.Second;
1863 Location loc = lexer.Location;
1865 // Structure members are Public by default
1866 if ((current_container is Struct) && (current_modifiers == 0))
1867 current_modifiers = Modifiers.PUBLIC;
1869 prop = new Property ((Expression) get_implicit_value_parameter_type,
1870 (string) $2, current_modifiers, get_block, set_block,
1871 current_attributes, loc, set_implicit_value_parameter_name,
1872 get_parameters, set_parameters, (ArrayList) $6);
1874 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1875 get_implicit_value_parameter_type = null;
1876 set_implicit_value_parameter_type = null;
1877 get_parameters = null;
1878 set_parameters = null;
1879 current_local_parameters = null;
1883 opt_property_parameters
1886 $$ = Parameters.EmptyReadOnlyParameters;
1888 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1894 opt_implement_clause
1899 | IMPLEMENTS implement_clause_list
1905 implement_clause_list
1906 : qualified_identifier
1908 ArrayList impl_list = new ArrayList ();
1909 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
1912 | implement_clause_list COMMA qualified_identifier
1914 ArrayList impl_list = (ArrayList) $1;
1915 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
1921 accessor_declarations
1922 : get_accessor_declaration opt_set_accessor_declaration
1924 $$ = new Pair ($1, $2);
1926 | set_accessor_declaration opt_get_accessor_declaration
1928 $$ = new Pair ($2, $1);
1932 opt_get_accessor_declaration
1933 : /* empty */ { $$ = null; }
1934 | get_accessor_declaration
1937 opt_set_accessor_declaration
1938 : /* empty */ { $$ = null; }
1939 | set_accessor_declaration
1942 get_accessor_declaration
1943 : opt_attributes GET logical_end_of_line
1945 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
1946 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
1948 current_local_parameters = get_parameters;
1950 lexer.PropertyParsing = false;
1953 // Add local var declaration
1955 ArrayList retval = new ArrayList ();
1956 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1957 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1960 END GET logical_end_of_line
1962 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1963 current_local_parameters = null;
1964 lexer.PropertyParsing = true;
1968 set_accessor_declaration
1969 : opt_attributes SET opt_set_parameter logical_end_of_line
1971 if ((current_modifiers & Modifiers.READONLY) != 0)
1972 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
1974 Parameter implicit_value_parameter = new Parameter (
1975 set_implicit_value_parameter_type,
1976 set_implicit_value_parameter_name,
1977 Parameter.Modifier.NONE, null);
1979 current_local_parameters = set_parameters;
1980 current_local_parameters.AppendParameter (implicit_value_parameter);
1983 lexer.PropertyParsing = false;
1986 END SET logical_end_of_line
1988 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1989 current_local_parameters = null;
1990 lexer.PropertyParsing = true;
1997 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
1998 set_implicit_value_parameter_name = "Value";
2000 |OPEN_PARENS CLOSE_PARENS
2002 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2003 set_implicit_value_parameter_name = "Value";
2005 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_spec CLOSE_PARENS
2007 Parameter.Modifier pm = (Parameter.Modifier)$2;
2008 if ((pm | Parameter.Modifier.VAL) != 0)
2009 Report.Error (31065,
2011 "Set cannot have a paremeter modifier other than 'ByVal'");
2013 set_implicit_value_parameter_type = (Expression) $4;
2015 if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
2016 Report.Error (31064,
2018 "Set value parameter type can not be different from property type");
2021 set_implicit_value_parameter_name = (string) $3;
2023 set_implicit_value_parameter_name = "Value";
2029 variable_declarators logical_end_of_line
2031 int mod = (int) current_modifiers;
2033 VariableDeclaration.FixupTypes ((ArrayList) $2);
2034 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2036 if (current_container is Module)
2037 mod = mod | Modifiers.STATIC;
2039 // Structure members are Public by default
2040 if ((current_container is Struct) && (mod == 0))
2041 mod = Modifiers.PUBLIC;
2043 if ((mod & Modifiers.Accessibility) == 0)
2044 mod |= Modifiers.PRIVATE;
2046 foreach (VariableDeclaration var in (ArrayList) $2){
2047 Location l = var.Location;
2048 Field field = new Field (var.type, mod, var.identifier,
2049 var.expression_or_array_initializer,
2050 (Attributes) null, l);
2052 CheckDef (current_container.AddField (field), field.Name, l);
2057 withevents_declaration
2058 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2060 // Module members are static by default, but delegates *can't* be declared static
2061 // so we must fix it, if mbas was the one actually responsible for this
2062 // instead of triggering an error.
2063 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2064 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2066 /* WithEvents Fields must be resolved into properties
2067 with a bit of magic behind the scenes */
2069 VariableDeclaration.FixupTypes ((ArrayList) $3);
2071 foreach (VariableDeclaration var in (ArrayList) $3) {
2072 // 1 - We create a private field
2073 Location l = var.Location;
2075 if ((current_modifiers & Modifiers.STATIC) > 0)
2076 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2078 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2079 var.expression_or_array_initializer,
2080 (Attributes) null, l);
2082 CheckDef (current_container.AddField (field), field.Name, l);
2084 // 2 - Public property
2086 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2087 field, (int) current_modifiers,
2088 (Attributes) current_attributes, l);
2090 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2100 delegate_declaration
2102 identifier OPEN_PARENS
2103 opt_formal_parameter_list
2107 Location l = lexer.Location;
2108 // Module members are static by default, but delegates *can't* be declared static
2109 // so we must fix it, if mbas was the one actually responsible for this
2110 // instead of triggering an error.
2111 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2112 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2114 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2115 TypeManager.system_void_expr,
2116 (int) current_modifiers,
2117 MakeName ((string) $3), (Parameters) $5,
2118 (Attributes) current_attributes, l);
2120 del.Namespace = current_namespace;
2121 CheckDef (current_container.AddDelegate (del), del.Name, l);
2124 identifier OPEN_PARENS
2125 opt_formal_parameter_list
2126 CLOSE_PARENS opt_type_spec logical_end_of_line
2128 Location l = lexer.Location;
2130 // Module members are static by default, but delegates *can't* be declared static
2131 // so we must fix it, if mbas was the one actually responsible for this
2132 // instead of triggering an error.
2133 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2134 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2136 Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2138 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2140 ftype, (int) current_modifiers, MakeName ((string) $3),
2141 (Parameters) $5, (Attributes) current_attributes, l);
2143 del.Namespace = current_namespace;
2144 CheckDef (current_container.AddDelegate (del), del.Name, l);
2151 | HANDLES qualified_identifier
2153 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
2155 | HANDLES MYBASE DOT qualified_identifier
2157 // FIXME: this is blatantly wrong and crash-prone
2158 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2162 constructor_declaration
2163 : SUB NEW opt_params logical_end_of_line
2165 current_local_parameters = (Parameters) $3;
2167 oob_stack.Push (lexer.Location);
2169 Location l = (Location) oob_stack.Pop ();
2170 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2175 Constructor c = (Constructor) $1;
2176 c.Block = (Block) end_block();
2177 c.ModFlags = (int) current_modifiers;
2178 c.OptAttributes = current_attributes;
2180 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2182 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2183 current_local_parameters = null;
2185 END SUB logical_end_of_line
2188 opt_formal_parameter_list
2191 $$ = Parameters.EmptyReadOnlyParameters;
2193 | formal_parameter_list
2196 //Parameter p = ((Parameters) $1).FixedParameters[0];
2200 formal_parameter_list
2203 ArrayList pars_list = (ArrayList) $1;
2205 Parameter [] pars = new Parameter [pars_list.Count];
2206 pars_list.CopyTo (pars);
2207 $$ = new Parameters (pars, null, lexer.Location);
2209 | fixed_parameters COMMA parameter_array
2211 ArrayList pars_list = (ArrayList) $1;
2213 Parameter [] pars = new Parameter [pars_list.Count];
2214 pars_list.CopyTo (pars);
2216 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
2220 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
2227 ArrayList pars = new ArrayList ();
2232 | fixed_parameters COMMA fixed_parameter
2234 ArrayList pars = (ArrayList) $1;
2243 opt_parameter_modifier
2244 identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
2246 Parameter.Modifier pm = (Parameter.Modifier)$2;
2247 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2250 if (opt_parm && ($7 == null))
2251 Report.Error (30812, "Optional parameters must have a default value");
2254 if ((pm & Parameter.Modifier.REF) !=0)
2255 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
2257 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
2260 if ($4 != null && $6 != null && $4 != $6)
2261 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2263 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2265 string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
2266 ptype = DecomposeQI (t, lexer.Location);
2268 $$ = new Parameter (ptype, (string) $3, pm,
2269 (Attributes) $1, (Expression) $7, opt_parm);
2274 : PARAM_ARRAY identifier opt_parens AS type
2276 string s_patype = ((Expression) $5).ToString();
2280 Expression patype = DecomposeQI (s_patype, Location.Null);
2281 $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
2282 // note ("type must be a single-dimension array type");
2289 | OPEN_PARENS CLOSE_PARENS
2293 opt_parameter_modifier
2294 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2295 | parameter_modifiers { $$ = $1; }
2299 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2300 | parameter_modifier { $$ = $1; }
2304 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2305 | BYVAL { $$ = Parameter.Modifier.VAL; }
2306 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2311 | statement_list end_of_stmt
2316 | statement_list end_of_stmt statement
2320 declaration_statement
2322 if ($1 != null && (Block) $1 != current_block){
2323 current_block.AddStatement ((Statement) $1);
2324 current_block = (Block) $1;
2327 | embedded_statement
2329 Statement s = (Statement) $1;
2331 current_block.AddStatement ((Statement) $1);
2334 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2336 AddHandler ((Expression) $2, (string) $5);
2338 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2340 RemoveHandler ((Expression) $2, (string) $5);
2342 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2344 RaiseEvent ((string) $2, (ArrayList) $3);
2346 /* | array_handling_statement */
2347 /* | empty_statement */
2350 Statement s = (Statement) $1;
2352 current_block.AddStatement ((Statement) $1);
2356 opt_raise_event_args
2357 : /* empty */ { $$ = null; }
2358 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2375 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2377 if (!current_block.AddLabel ((string) $1, labeled)){
2378 Location l = lexer.Location;
2379 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2381 current_block.AddStatement (labeled);
2385 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2387 if (!current_block.AddLabel ((string) $1, labeled)){
2388 Location l = lexer.Location;
2389 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2391 current_block.AddStatement (labeled);
2397 : expression_statement
2398 | selection_statement
2399 | iteration_statement
2401 | synclock_statement
2403 | array_handling_statement
2409 $$ = new EmptyStatement ();
2415 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2417 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2418 Expression e = (Expression) $2;
2425 Block b = end_block();
2432 array_handling_statement
2438 : REDIM opt_preserve redim_clauses
2440 ArrayList list = (ArrayList) $3;
2441 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2448 : /* empty */ { $$ = false; }
2449 | PRESERVE { $$ = true; }
2455 ArrayList clauses = new ArrayList ();
2460 | redim_clauses COMMA redim_clause
2462 ArrayList clauses = (ArrayList) ($1);
2470 : invocation_expression
2472 Invocation i = (Invocation) $1;
2473 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2479 : ERASE erase_clauses
2481 ArrayList list = (ArrayList) $2;
2482 foreach(Expression e in list)
2484 Erase r = new Erase (e, lexer.Location);
2493 ArrayList clauses = new ArrayList ();
2498 | erase_clauses COMMA erase_clause
2500 ArrayList clauses = (ArrayList) ($1);
2508 : primary_expression
2513 | continue_statement
2514 | */return_statement
2524 $$ = new Goto (current_block, (string) $2, lexer.Location);
2529 : THROW opt_expression
2531 $$ = new Throw ((Expression) $2, lexer.Location);
2538 $$ = new Exit ((ExitType)$2, lexer.Location);
2543 : DO { $$ = ExitType.DO; }
2544 | FOR { $$ = ExitType.FOR; }
2545 | WHILE { $$ = ExitType.WHILE; }
2546 | SELECT { $$ = ExitType.SELECT; }
2547 | SUB { $$ = ExitType.SUB; }
2548 | FUNCTION { $$ = ExitType.FUNCTION; }
2549 | PROPERTY { $$ = ExitType.PROPERTY; }
2550 | TRY { $$ = ExitType.TRY; }
2553 : RETURN opt_expression
2555 $$ = new Return ((Expression) $2, lexer.Location);
2567 : FOR EACH identifier IN
2569 oob_stack.Push (lexer.Location);
2571 expression end_of_stmt
2575 Block foreach_block = current_block;
2576 Location l = lexer.Location;
2577 LocalVariableReference v = null;
2580 vi = foreach_block.GetVariableInfo ((string) $3);
2582 // Get a reference to this variable.
2583 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2586 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2593 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2594 Block foreach_block = end_block();
2595 Location l = (Location) oob_stack.Pop ();
2599 f = new Foreach (null, v, (Expression) $6, foreach_block, l);
2609 if (!UseExtendedSyntax)
2615 if (iterator_container == null){
2616 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2619 iterator_container.SetYields ();
2620 $$ = new Yield ((Expression) $2, lexer.Location);
2625 if (!UseExtendedSyntax)
2631 if (iterator_container == null){
2632 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2635 iterator_container.SetYields ();
2636 $$ = new YieldBreak (lexer.Location);
2642 : SYNCLOCK expression end_of_stmt
2649 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2666 tmp_catch_clauses = (ArrayList) $5;
2675 ArrayList s = new ArrayList ();
2677 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2684 // Now s contains the list of specific catch clauses
2685 // and g contains the general one.
2686 Block b = end_block();
2688 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2695 tmp_block = end_block();
2705 ArrayList s = new ArrayList ();
2706 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2708 if (catch_list != null){
2709 foreach (Catch cc in catch_list) {
2717 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2723 : /* empty */ { $$ = null; }
2730 ArrayList l = new ArrayList ();
2735 | catch_clauses catch_clause
2737 ArrayList l = (ArrayList) $1;
2745 : /* empty */ { $$ = null; }
2750 : CATCH opt_catch_args end_of_stmt
2752 Expression type = null;
2756 DictionaryEntry cc = (DictionaryEntry) $2;
2757 type = (Expression) cc.Key;
2758 id = (string) cc.Value;
2761 ArrayList one = new ArrayList ();
2762 Location loc = lexer.Location;
2764 one.Add (new VariableDeclaration (id, type, loc));
2768 current_block = new Block (current_block);
2769 Block b = declare_local_variables (type, one, loc);
2775 opt_statement_list {
2776 Expression type = null;
2778 Block b_catch = current_block;
2781 DictionaryEntry cc = (DictionaryEntry) $2;
2782 type = (Expression) cc.Key;
2783 id = (string) cc.Value;
2787 // FIXME: I can change this for an assignment.
2789 while (current_block != (Block) $1)
2790 current_block = current_block.Parent;
2794 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2799 : /* empty */ { $$ = null; }
2804 : identifier AS type
2806 $$ = new DictionaryEntry ($3, $1);
2812 : DO opt_do_construct end_of_stmt
2815 oob_stack.Push (lexer.Location);
2818 LOOP opt_do_construct
2820 Expression t_before = (Expression) $2;
2821 Expression t_after = (Expression) $7;
2824 if ((t_before != null) && (t_after != null))
2825 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2827 if ((t_before == null) && (t_after == null))
2828 t = new BoolLiteral (true);
2830 t = (t_before != null) ? t_before : t_after;
2832 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2834 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2835 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2836 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2838 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2843 : /* empty */ { $$ = null; }
2844 | while_or_until boolean_expression
2846 do_type = (DoOptions)$1;
2847 $$ = (Expression) $2;
2852 : WHILE { $$ = DoOptions.WHILE; }
2853 | UNTIL { $$ = DoOptions.UNTIL; }
2860 oob_stack.Push (lexer.Location);
2862 boolean_expression end_of_stmt
2866 Location l = (Location) oob_stack.Pop ();
2867 Block b = end_block();
2868 Expression e = (Expression) $3;
2869 $$ = new While ((Expression) e, (Statement) b, l);
2875 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2882 Block statement = end_block();
2883 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2885 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2886 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2887 for_var, (Expression) $6, lexer.Location);
2888 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2889 for_var, (Expression) $7, lexer.Location), lexer.Location);
2891 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2892 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2894 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2899 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2900 | STEP expression { $$ = $2; }
2909 : if_statement_open opt_then if_statement_rest
2913 | if_statement_open THEN pre_embedded_statement
2915 Location l = (Location) oob_stack.Pop ();
2916 tmp_expr = (Expression)expr_stack.Pop();
2917 $$ = new If ((Expression) tmp_expr, end_block(), l);
2921 pre_embedded_statement
2922 : embedded_statement
2924 Statement s = (Statement) $1;
2926 current_block.AddStatement ((Statement) $1);
2931 : IF boolean_expression
2933 oob_stack.Push (lexer.Location);
2935 tmp_expr = (Expression) $2;
2936 expr_stack.Push(tmp_expr);
2950 Location l = (Location) oob_stack.Pop ();
2951 Expression expr = (Expression)expr_stack.Pop();
2952 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2958 Block bl = end_block();
2959 tmp_blocks.Push(bl);
2965 Location l = (Location) oob_stack.Pop ();
2966 tmp_expr = (Expression)expr_stack.Pop();
2967 tmp_block = (Block) tmp_blocks.Pop();
2968 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2972 ELSEIF boolean_expression opt_then
2974 tmp_expr = (Expression) $4;
2975 expr_stack.Push(tmp_expr);
2976 tmp_block = end_block();
2977 tmp_blocks.Push(tmp_block);
2980 else_if_statement_rest
2982 Statement stmt = (Statement) statement_stack.Pop();
2983 Block bl = (Block) tmp_blocks.Pop();
2984 Expression expr = (Expression)expr_stack.Pop();
2985 Location l = (Location) oob_stack.Pop ();
2986 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
2991 else_if_statement_rest
2996 Location l = (Location) oob_stack.Pop ();
2998 Expression expr = (Expression)expr_stack.Pop();
2999 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3000 statement_stack.Push(stmt);
3006 Block bl = end_block();
3007 tmp_blocks.Push(bl);
3013 Location l = (Location) oob_stack.Pop ();
3015 Expression expr = (Expression)expr_stack.Pop();
3016 Block bl = (Block)tmp_blocks.Pop();
3017 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3018 statement_stack.Push(stmt);
3022 ELSEIF boolean_expression opt_then
3024 expr_stack.Push((Expression) $4);
3025 Block bl = end_block();
3026 tmp_blocks.Push(bl);
3029 else_if_statement_rest
3031 Location l = (Location) oob_stack.Pop ();
3033 Statement tmp_stmt = (Statement)statement_stack.Pop();
3034 Block bl = (Block) tmp_blocks.Pop();
3035 Expression expr = (Expression)expr_stack.Pop();
3036 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3037 statement_stack.Push(stmt);
3042 : SELECT opt_case expression end_of_stmt
3044 oob_stack.Push (lexer.Location);
3045 switch_stack.Push (current_block);
3050 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3051 current_block = (Block) switch_stack.Pop ();
3056 : /* empty */ { $$ = null; }
3057 | case_sections { $$ = $1; }
3061 : case_sections case_section
3063 ArrayList sections = (ArrayList) $1;
3070 ArrayList sections = new ArrayList ();
3084 : CASE case_clauses ends
3090 //Block topmost = current_block;
3091 Block topmost = end_block();
3093 while (topmost.Implicit)
3094 topmost = topmost.Parent;
3096 // FIXME: This is a horrible hack which MUST go
3097 topmost.statements.Add (new Break (lexer.Location));
3098 $$ = new SwitchSection ((ArrayList) $2, topmost);
3101 /* FIXME: we should somehow flag an error
3102 (BC30321 'Case' cannot follow a 'Case Else'
3103 in the same 'Select' statement.)
3104 if Case Else is not the last of the Case clauses
3111 //Block topmost = current_block;
3112 Block topmost = end_block();
3114 while (topmost.Implicit)
3115 topmost = topmost.Parent;
3117 // FIXME: This is a horrible hack which MUST go
3118 topmost.statements.Add (new Break (lexer.Location));
3120 ArrayList a = new ArrayList();
3121 a.Add (new SwitchLabel (null, lexer.Location));
3122 $$ = new SwitchSection ((ArrayList) a, topmost);
3129 ArrayList labels = new ArrayList ();
3134 | case_clauses COMMA case_clause
3136 ArrayList labels = (ArrayList) ($1);
3144 : opt_is comparison_operator expression
3147 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3169 expression_statement
3170 : statement_expression
3177 statement_expression
3178 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3179 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3180 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3183 object_creation_expression
3184 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3186 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3190 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3194 array_creation_expression
3195 : object_creation_expression array_initializer
3198 ArrayList dims = new ArrayList();
3200 if (n.Arguments != null) {
3201 foreach (Argument a in n.Arguments) {
3206 Expression atype = n.RequestedType;
3208 ArrayList init = (ArrayList) $2;
3209 if (init.Count == 0)
3212 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3213 VariableDeclaration.VBFixIndexList (ref dims);
3214 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3218 string rank = VariableDeclaration.BuildRank (dims);
3219 $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
3221 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3226 : object_creation_expression
3227 | array_creation_expression
3230 declaration_statement
3231 : local_variable_declaration
3234 DictionaryEntry de = (DictionaryEntry) $1;
3236 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3239 | local_constant_declaration
3242 DictionaryEntry de = (DictionaryEntry) $1;
3244 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3249 local_variable_declaration
3250 : DIM variable_declarators
3252 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3257 local_constant_declaration
3258 : CONST constant_declarators
3261 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3267 constant_declarators
3268 : constant_declarator
3270 ArrayList decl = new ArrayList ();
3276 | constant_declarators COMMA constant_declarator
3278 ArrayList decls = (ArrayList) $1;
3287 : variable_name opt_type_decl opt_variable_initializer
3289 VarName vname = (VarName) $1;
3290 string varname = (string) vname.Name;
3291 current_rank_specifiers = (ArrayList) vname.Rank;
3292 object varinit = $3;
3293 ArrayList a_dims = null;
3295 if (varinit == null)
3297 30438, lexer.Location, "Constant should have a value"
3300 if (vname.Type != null && $2 != null)
3302 30302, lexer.Location,
3303 "Type character cannot be used with explicit type declaration" );
3305 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3307 if (current_rank_specifiers != null)
3309 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3313 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3317 variable_declarators
3318 : variable_declarator
3320 ArrayList decl = new ArrayList ();
3321 decl.AddRange ((ArrayList) $1);
3324 | variable_declarators COMMA variable_declarator
3326 ArrayList decls = (ArrayList) $1;
3327 decls.AddRange ((ArrayList) $3);
3333 : variable_names opt_type_decl opt_variable_initializer
3335 ArrayList names = (ArrayList) $1;
3336 object varinit = $3;
3337 ArrayList VarDeclarations = new ArrayList();
3339 ArrayList a_dims = null;
3341 if ((names.Count > 1) && (varinit != null))
3343 30671, lexer.Location,
3344 "Multiple variables with single type can not have " +
3345 "a explicit initialization" );
3348 foreach (VarName vname in names)
3350 string varname = (string) vname.Name;
3351 current_rank_specifiers = (ArrayList) vname.Rank;
3355 if(vname.Type != null && $2 != null)
3357 30302, lexer.Location,
3358 "Type character cannot be used with explicit type declaration" );
3360 // Some checking is required for particularly weird declarations
3361 // like Dim a As Integer(,)
3363 vartype = (Expression) ((Pair) $2).First;
3365 /*if ($3 != null && $3 is ArrayList)
3366 Report.Error (205, "End of statement expected.");*/
3368 ArrayList args = (ArrayList) ((Pair) $2).Second;
3369 if (current_rank_specifiers != null)
3370 Report.Error (31087, lexer.Location,
3371 "Array types specified in too many places");
3373 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3374 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3376 current_rank_specifiers = new ArrayList ();
3377 current_rank_specifiers.Add (args);
3379 /*string s_vartype = vartype.ToString();
3382 for (int x = 0; x < args.Count; x++)
3386 vartype = DecomposeQI(s_vartype, Location.Null); */
3389 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3391 // if the variable is an array with explicit bound
3392 // and having explicit initialization throw exception
3393 if (current_rank_specifiers != null && varinit != null)
3395 bool broken = false;
3396 foreach (ArrayList exprs in current_rank_specifiers)
3398 foreach (Expression expr in exprs)
3400 if (!((Expression)expr is EmptyExpression ))
3403 30672, lexer.Location,
3404 "Array declared with explicit bound " +
3405 " can not have explicit initialization");
3416 Check for a declaration like Dim a(2) or Dim a(2,3)
3417 If this is the case, we must generate an ArrayCreationExpression
3418 and, in case, add the initializer after the array has been created.
3420 if (VariableDeclaration.IsArrayDecl (this)) {
3421 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3422 a_dims = (ArrayList) current_rank_specifiers;
3423 VariableDeclaration.VBFixIndexLists (ref a_dims);
3424 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3426 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
3429 if (vartype is New) {
3430 if (varinit != null) {
3431 Report.Error (30205, lexer.Location, "End of statement expected");
3437 vartype = ((New)vartype).RequestedType;
3440 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3442 $$ = VarDeclarations;
3449 ArrayList list = new ArrayList ();
3453 | variable_names COMMA variable_name
3455 ArrayList list = (ArrayList) $1;
3462 : identifier opt_type_character opt_array_name_modifier
3464 $$ = new VarName ($1, $2, $3);
3475 $$ = (Expression) $2;
3481 | AS type rank_specifiers
3483 $$ = TypeManager.system_object_expr;
3492 | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
3494 $$ = new Pair ($2, $4);
3498 New n = new New ((Expression)$3, null, lexer.Location);
3499 $$ = (Expression) n;
3501 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3503 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3504 $$ = (Expression) n;
3506 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3508 ArrayList args = new ArrayList();
3509 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3512 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3513 $$ = (Expression) n;
3517 opt_array_name_modifier
3518 : /* empty */ { $$ = null; }
3519 | array_type_modifier { $$ = $1; }
3523 : rank_specifiers { $$ = $1; }
3526 opt_variable_initializer
3527 : /* empty */ { $$ = null; }
3528 | ASSIGN variable_initializer { $$ = $2; }
3531 variable_initializer
3544 : OPEN_BRACE CLOSE_BRACE
3546 ArrayList list = new ArrayList ();
3549 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3551 $$ = (ArrayList) $2;
3555 variable_initializer_list
3556 : variable_initializer
3558 ArrayList list = new ArrayList ();
3562 | variable_initializer_list COMMA variable_initializer
3564 ArrayList list = (ArrayList) $1;
3585 ArrayList rs = new ArrayList();
3589 | rank_specifiers rank_specifier
3591 ArrayList rs = (ArrayList) $1;
3598 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
3607 ArrayList ds = new ArrayList();
3608 ds.Add (new EmptyExpression());
3613 ArrayList ds = (ArrayList) $1;
3614 ds.Add (new EmptyExpression());
3626 ArrayList ds = new ArrayList();
3627 ds.Add (new EmptyExpression());
3630 | dim_separators COMMA
3632 ArrayList ds = (ArrayList) $1;
3633 ds.Add (new EmptyExpression());
3641 ArrayList ds = new ArrayList();
3642 ds.Add ((Expression) $1);
3645 | dim_specifiers COMMA expression
3647 ArrayList ds = (ArrayList) $1;
3648 ds.Add ((Expression) $3);
3658 | parenthesized_expression
3661 | qualified_identifier
3663 string name = (string) $1;
3664 $$ = DecomposeQI (name, lexer.Location);
3666 //FIXME: address_of_expression is apparently missing here
3667 | get_type_expression
3669 | invocation_expression
3679 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3680 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3681 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3682 | NOTHING { $$ = NullLiteral.Null; }
3686 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3687 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3688 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3693 object v = lexer.Value;
3696 $$ = new IntLiteral ((Int32)v);
3697 else if (v is short)
3698 $$ = new ShortLiteral ((Int16)v);
3700 $$ = new LongLiteral ((Int64)v);
3702 Console.WriteLine ("OOPS. Unexpected result from scanner");
3708 : TRUE { $$ = new BoolLiteral (true); }
3709 | FALSE { $$ = new BoolLiteral (false); }
3712 parenthesized_expression
3713 : OPEN_PARENS expression CLOSE_PARENS
3718 : primary_expression DOT identifier
3721 string id_name = (string)$3;
3722 if (id_name.ToUpper() == "NEW")
3724 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3728 if (with_stack.Count > 0) {
3729 Expression e = (Expression) with_stack.Peek();
3730 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3738 /* | primary_expression DOT NEW
3740 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3742 | predefined_type DOT identifier
3745 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3748 if (with_stack.Count > 0) {
3749 Expression e = (Expression) with_stack.Peek();
3750 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3764 invocation_expression
3765 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3768 Location l = lexer.Location;
3769 Report.Error (1, l, "THIS IS CRAZY");
3771 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3772 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3777 : MYBASE DOT IDENTIFIER
3779 string id_name = (string) $3;
3780 if (id_name.ToUpper() == "NEW")
3782 $$ = new BaseAccess (id_name, lexer.Location);
3786 $$ = new BaseAccess ("New", lexer.Location);
3794 The 'argument' rule returns an 'empty' argument
3795 of type NoArg (used for default arguments in invocations)
3796 if no arguments are actually passed.
3798 If there is only one argument and it is o type NoArg,
3799 we return a null (empty) list
3801 ArrayList args = (ArrayList) $1;
3802 if (args.Count == 1 &&
3803 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3813 ArrayList list = new ArrayList ();
3817 | argument_list COMMA argument
3819 ArrayList list = (ArrayList) $1;
3828 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3830 | BYREF variable_reference
3832 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3836 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3838 | ADDRESSOF expression
3840 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
3845 : expression {/* note ("section 5.4"); */ $$ = $1; }
3850 : conditional_xor_expression { $$ = $1; }
3851 /*| assignment_expression*/
3862 $$ = new This (current_block, lexer.Location);
3866 // FIXME: This is actually somewhat different from Me
3867 // because it is for accessing static (classifier) methods/properties/fields
3868 $$ = new This (current_block, lexer.Location);
3873 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
3877 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3879 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3881 | cast_operator OPEN_PARENS expression CLOSE_PARENS
3883 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3888 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3889 | CBYTE { $$ = TypeManager.system_byte_expr; }
3890 | CCHAR { $$ = TypeManager.system_char_expr; }
3891 | CDATE { $$ = TypeManager.system_date_expr; }
3892 | CDBL { $$ = TypeManager.system_double_expr; }
3893 | CDEC { $$ = TypeManager.system_decimal_expr; }
3894 | CINT { $$ = TypeManager.system_int32_expr; }
3895 | CLNG { $$ = TypeManager.system_int64_expr; }
3896 | COBJ { $$ = TypeManager.system_object_expr; }
3897 | CSHORT { $$ = TypeManager.system_int16_expr; }
3898 | CSNG { $$ = TypeManager.system_single_expr; }
3899 | CSTR { $$ = TypeManager.system_string_expr; }
3903 : GETTYPE OPEN_PARENS type CLOSE_PARENS
3905 $$ = new TypeOf ((Expression) $3, lexer.Location);
3909 exponentiation_expression
3910 : primary_expression
3911 | exponentiation_expression OP_EXP primary_expression
3917 prefixed_unary_expression
3918 : exponentiation_expression
3919 | PLUS prefixed_unary_expression
3921 //FIXME: Is this rule correctly defined ?
3922 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3924 | MINUS prefixed_unary_expression
3926 //FIXME: Is this rule correctly defined ?
3927 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3931 multiplicative_expression
3932 : prefixed_unary_expression
3933 | multiplicative_expression STAR prefixed_unary_expression
3935 $$ = new Binary (Binary.Operator.Multiply,
3936 (Expression) $1, (Expression) $3, lexer.Location);
3938 | multiplicative_expression DIV prefixed_unary_expression
3940 $$ = new Binary (Binary.Operator.Division,
3941 (Expression) $1, (Expression) $3, lexer.Location);
3945 integer_division_expression
3946 : multiplicative_expression
3947 | integer_division_expression OP_IDIV multiplicative_expression
3949 //FIXME: Is this right ?
3950 $$ = new Binary (Binary.Operator.Division,
3951 (Expression) $1, (Expression) $3, lexer.Location);
3956 : integer_division_expression
3957 | mod_expression MOD integer_division_expression
3959 $$ = new Binary (Binary.Operator.Modulus,
3960 (Expression) $1, (Expression) $3, lexer.Location);
3966 | additive_expression PLUS mod_expression
3968 $$ = new Binary (Binary.Operator.Addition,
3969 (Expression) $1, (Expression) $3, lexer.Location);
3971 | additive_expression MINUS mod_expression
3973 $$ = new Binary (Binary.Operator.Subtraction,
3974 (Expression) $1, (Expression) $3, lexer.Location);
3979 : additive_expression
3980 | concat_expression OP_CONCAT additive_expression
3982 // FIXME: This should only work for String expressions
3983 // We probably need to use something from the runtime
3984 $$ = new Binary (Binary.Operator.Addition,
3985 (Expression) $1, (Expression) $3, lexer.Location);
3991 | shift_expression OP_SHIFT_LEFT concat_expression
3995 | shift_expression OP_SHIFT_RIGHT concat_expression
4001 relational_expression
4003 | relational_expression ASSIGN shift_expression
4005 $$ = new Binary (Binary.Operator.Equality,
4006 (Expression) $1, (Expression) $3, lexer.Location);
4008 | relational_expression OP_NE shift_expression
4010 $$ = new Binary (Binary.Operator.Inequality,
4011 (Expression) $1, (Expression) $3, lexer.Location);
4013 | relational_expression OP_LT shift_expression
4015 $$ = new Binary (Binary.Operator.LessThan,
4016 (Expression) $1, (Expression) $3, lexer.Location);
4018 | relational_expression OP_GT shift_expression
4020 $$ = new Binary (Binary.Operator.GreaterThan,
4021 (Expression) $1, (Expression) $3, lexer.Location);
4023 | relational_expression OP_LE shift_expression
4025 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4026 (Expression) $1, (Expression) $3, lexer.Location);
4028 | relational_expression OP_GE shift_expression
4030 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4031 (Expression) $1, (Expression) $3, lexer.Location);
4033 | relational_expression IS shift_expression
4035 //FIXME: Should be a different op for reference equality but allows tests to use Is
4036 $$ = new Binary (Binary.Operator.Equality,
4037 (Expression) $1, (Expression) $3, lexer.Location);
4039 | TYPEOF shift_expression IS type
4041 //FIXME: Is this rule correctly defined ?
4042 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4047 : relational_expression
4048 | NOT negation_expression
4050 //FIXME: Is this rule correctly defined ?
4051 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4055 conditional_and_expression
4056 : negation_expression
4057 | conditional_and_expression AND negation_expression
4059 $$ = new Binary (Binary.Operator.LogicalAnd,
4060 (Expression) $1, (Expression) $3, lexer.Location);
4062 | conditional_and_expression ANDALSO negation_expression
4063 { // FIXME: this is likely to be broken
4064 $$ = new Binary (Binary.Operator.LogicalAnd,
4065 (Expression) $1, (Expression) $3, lexer.Location);
4069 conditional_or_expression
4070 : conditional_and_expression
4071 | conditional_or_expression OR conditional_and_expression
4073 $$ = new Binary (Binary.Operator.LogicalOr,
4074 (Expression) $1, (Expression) $3, lexer.Location);
4076 | conditional_or_expression ORELSE conditional_and_expression
4077 { // FIXME: this is likely to be broken
4078 $$ = new Binary (Binary.Operator.LogicalOr,
4079 (Expression) $1, (Expression) $3, lexer.Location);
4083 conditional_xor_expression
4084 : conditional_or_expression
4085 | conditional_xor_expression XOR conditional_or_expression
4087 $$ = new Binary (Binary.Operator.ExclusiveOr,
4088 (Expression) $1, (Expression) $3, lexer.Location);
4092 assignment_expression
4093 : prefixed_unary_expression ASSIGN expression
4095 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4097 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4099 ArrayList args = new ArrayList();
4100 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4103 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4104 n.isDelegate = true;
4105 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4118 : namespace_or_type_name
4120 $$ = DecomposeQI ((string) $1, lexer.Location);
4129 ArrayList types = new ArrayList ();
4134 | type_list COMMA type
4136 ArrayList types = (ArrayList) $1;
4143 namespace_or_type_name
4144 : qualified_identifier
4148 : OBJECT { $$ = TypeManager.system_object_expr; }
4154 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4155 | DATE { $$ = TypeManager.system_date_expr; }
4156 | CHAR { $$ = TypeManager.system_char_expr; }
4157 | STRING { $$ = TypeManager.system_string_expr; }
4163 | floating_point_type
4164 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4169 | BYTE { $$ = TypeManager.system_byte_expr; }
4170 | SHORT { $$ = TypeManager.system_int16_expr; }
4171 | INTEGER { $$ = TypeManager.system_int32_expr; }
4172 | LONG { $$ = TypeManager.system_int64_expr; }
4176 : SINGLE { $$ = TypeManager.system_single_expr; }
4177 | DOUBLE { $$ = TypeManager.system_double_expr; }
4181 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4183 if(tokenizerController.IsAcceptingTokens)
4185 if(in_external_source)
4186 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4188 in_external_source = true;
4190 lexer.EffectiveSource = (string) $4;
4191 lexer.EffectiveLine = (int) $6;
4195 | HASH IDENTIFIER LITERAL_STRING EOL
4197 if(tokenizerController.IsAcceptingTokens)
4199 string id = ($2 as string);
4201 if(!($2 as string).ToLower().Equals("region"))
4202 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4209 | HASH END IDENTIFIER EOL
4211 if(tokenizerController.IsAcceptingTokens)
4213 if( ($3 as string).ToLower().Equals("externalsource")) {
4214 if(!in_external_source)
4215 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4217 in_external_source = false;
4218 lexer.EffectiveSource = lexer.Source;
4219 lexer.EffectiveLine = lexer.Line;
4222 else if(($3 as string).ToLower().Equals("region")) {
4223 if(in_marked_region > 0)
4226 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4229 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4233 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4235 if(tokenizerController.IsAcceptingTokens)
4242 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4245 ifElseStateMachine.HandleToken(tok);
4247 catch(ApplicationException) {
4248 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4251 boolean_literal opt_then EOL
4253 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4257 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4259 ifElseStateMachine.HandleToken(tok);
4261 catch(ApplicationException) {
4262 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4265 boolean_literal opt_then EOL
4267 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4271 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4273 ifElseStateMachine.HandleToken(tok);
4275 catch(ApplicationException) {
4276 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4281 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4285 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4287 ifElseStateMachine.HandleToken(tok);
4289 catch(ApplicationException) {
4290 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4295 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4299 if(tokenizerController.IsAcceptingTokens)
4300 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4302 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4312 public Tokenizer Lexer {
4318 public static Expression DecomposeQI (string name, Location loc)
4322 if (name.IndexOf ('.') == -1){
4323 return new SimpleName (name, loc);
4325 int pos = name.LastIndexOf (".");
4326 string left = name.Substring (0, pos);
4327 string right = name.Substring (pos + 1);
4329 o = DecomposeQI (left, loc);
4331 return new MemberAccess (o, right, loc);
4335 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4337 Block implicit_block;
4338 ArrayList inits = null;
4341 // We use the `Used' property to check whether statements
4342 // have been added to the current block. If so, we need
4343 // to create another block to contain the new declaration
4344 // otherwise, as an optimization, we use the same block to
4345 // add the declaration.
4347 // FIXME: A further optimization is to check if the statements
4348 // that were added were added as part of the initialization
4349 // below. In which case, no other statements have been executed
4350 // and we might be able to reduce the number of blocks for
4351 // situations like this:
4353 // int j = 1; int k = j + 1;
4356 VariableDeclaration.FixupTypes (variable_declarators);
4358 if (current_block.Used) {
4359 implicit_block = new Block (current_block, true, loc, Location.Null);
4360 implicit_block.AddChildVariableNames (current_block);
4362 implicit_block = current_block;
4364 foreach (VariableDeclaration decl in variable_declarators){
4365 Expression type = decl.type;
4366 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4367 if (decl.expression_or_array_initializer != null){
4369 inits = new ArrayList ();
4376 return implicit_block;
4378 foreach (VariableDeclaration decl in inits){
4381 Expression type = decl.type;
4383 if ((decl.expression_or_array_initializer is Expression) ||
4384 (decl.expression_or_array_initializer is New)) {
4385 expr = (Expression) decl.expression_or_array_initializer;
4387 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4389 expr = new ArrayCreation (type, "", init, decl.Location);
4392 LocalVariableReference var;
4393 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4395 assign = new Assign (var, expr, decl.Location);
4397 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4400 return implicit_block;
4403 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4405 Block implicit_block;
4406 VariableDeclaration.FixupTypes (variable_declarators);
4408 if (current_block.Used)
4409 implicit_block = new Block (current_block, true);
4411 implicit_block = current_block;
4413 foreach (VariableDeclaration decl in variable_declarators){
4414 Expression type = decl.type;
4415 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4416 current_local_parameters, decl.Location);
4419 return implicit_block;
4427 public VarName (object n, object t, object r)
4437 // A class used to pass around variable declarations and constants
4439 public class VariableDeclaration {
4440 public string identifier;
4441 public object expression_or_array_initializer;
4442 public Location Location;
4443 public Attributes OptAttributes;
4444 public Expression type;
4445 public ArrayList dims;
4447 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4449 this.identifier = id;
4450 this.expression_or_array_initializer = eoai;
4452 this.OptAttributes = opt_attrs;
4457 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4461 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4465 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4466 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4470 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4472 // FIXME : This is broken: only the first rank is parsed
4473 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4476 public static void FixupTypes (ArrayList vars)
4478 int varcount = vars.Count;
4479 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4481 if (last_var.type == null)
4482 last_var.type = TypeManager.system_object_expr;
4484 Expression cur_type = last_var.type;
4485 int n = varcount - 1;
4488 VariableDeclaration var = (VariableDeclaration) vars[n--];
4489 if (var.type == null)
4490 var.type = cur_type;
4492 cur_type = var.type;
4496 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4500 if (IndexList != null) {
4501 foreach (Expression e in IndexList)
4502 if (!(e is EmptyExpression)) {
4511 public static bool IndexesSpecified (ArrayList ranks)
4515 if (ranks != null) {
4516 foreach (ArrayList IndexList in ranks) {
4517 if (IndexesSpecifiedInRank (IndexList)) {
4526 public static string StripDims (string varname, ref string d)
4528 string res = varname;
4531 if (varname.IndexOf("[") >= 0) {
4532 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4533 res = varname.Substring(0, varname.IndexOf("["));
4539 public static string StripDims (string varname)
4543 return (StripDims(varname, ref dres));
4546 public static string StripIndexesFromDims (string dims)
4548 StringBuilder sb = new StringBuilder();
4550 foreach (char c in dims)
4551 if (c == ',' || c == ']' || c == '[')
4554 return sb.ToString();
4557 public static string BuildRank (ArrayList rank)
4562 for (int x = 0; x < (rank.Count -1 ); x++)
4569 public static string BuildRanks (Parser t)
4573 foreach (ArrayList rank in t.current_rank_specifiers)
4574 res += BuildRank (rank);
4579 public static void VBFixIndexList (ref ArrayList IndexList)
4581 if (IndexList != null) {
4582 for (int x = 0; x < IndexList.Count; x++) {
4583 Expression e = (Expression) IndexList[x];
4584 if (!(e is EmptyExpression)) {
4585 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4591 public static bool IsArrayDecl (Parser t)
4593 // return (varname.IndexOf("[") >= 0);
4594 return (t.current_rank_specifiers != null);
4597 public static void VBFixIndexLists (ref ArrayList ranks)
4599 if (ranks != null) {
4600 for (int x = 0; x < ranks.Count; x++) {
4601 ArrayList IndexList = (ArrayList) ranks[x];
4602 VBFixIndexList (ref IndexList);
4607 public static void FixupArrayTypes (ArrayList vars)
4609 int varcount = vars.Count;
4612 foreach (VariableDeclaration var in vars) {
4613 if (var.identifier.EndsWith(",")) {
4614 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4615 var.identifier.LastIndexOf(",")) + "]";
4616 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4617 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4624 public Property BuildSimpleProperty (Expression p_type, string name,
4625 Field p_fld, int mod_flags,
4626 Attributes attrs, Location loc)
4629 Block get_block, set_block;
4630 Accessor acc_set, acc_get;
4631 StatementExpression a_set;
4636 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4637 args = new Parameter [1];
4638 args [0] = implicit_value_parameter;
4640 Parameters set_params = new Parameters (args, null, loc);
4641 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4642 (Expression) new SimpleName("value", loc), loc), loc);
4644 set_block = new Block (current_block, set_params, loc, Location.Null);
4645 set_block.AddStatement ((Statement) a_set);
4646 acc_set = new Accessor (set_block, attrs);
4649 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4650 get_block = new Block (current_block, null, loc, Location.Null);
4651 get_block.AddStatement ((Statement) a_get);
4652 acc_get = new Accessor (get_block, attrs);
4654 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4661 current_block = new Block (current_block, current_local_parameters,
4662 lexer.Location, Location.Null);
4669 while (current_block.Implicit)
4670 current_block = current_block.Parent;
4672 res = current_block;
4674 current_block.SetEndLocation (lexer.Location);
4675 current_block = current_block.Parent;
4680 private void AddHandler (Expression evt_definition, string handler_name)
4682 AddHandler (current_block, evt_definition, handler_name);
4685 void CheckAttributeTarget (string a)
4689 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4693 Location l = lexer.Location;
4694 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4699 private void AddHandler (Block b, Expression evt_id, string handler_name)
4701 Location loc = lexer.Location;
4702 string evt_target = evt_id.ToString();
4703 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4704 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4708 private void RaiseEvent (string evt_name, ArrayList args)
4710 Location loc = lexer.Location;
4712 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4713 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4714 current_block.AddStatement (s);
4717 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4719 Location loc = lexer.Location;
4720 string evt_target = evt_definition.ToString();
4721 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4722 Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4727 // This method is used to get at the complete string representation of
4728 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4729 // This is necessary because local_variable_type admits primary_expression
4730 // as the type of the variable. So we do some extra checking
4732 string GetQualifiedIdentifier (Expression expr)
4734 if (expr is SimpleName)
4735 return ((SimpleName)expr).Name;
4736 else if (expr is MemberAccess)
4737 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4739 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4743 private void RemoveHandler (Expression evt_definition, string handler_name)
4745 RemoveHandler (current_block, evt_definition, handler_name);
4748 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4750 ConstructorInitializer ci = null;
4753 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4754 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4756 if (i.expr is BaseAccess) {
4757 BaseAccess ba = (BaseAccess) i.expr;
4758 if (ba.member == "New" || ba.member == ".ctor") {
4759 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4763 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4764 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4772 void Error_ExpectingTypeName (Location l, Expression expr)
4774 if (expr is Invocation){
4775 Report.Error (1002, l, "; expected");
4777 Report.Error (-1, l, "Invalid Type definition");
4781 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4785 private void ReportError9998()
4787 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4790 protected override int parse ()
4792 RootContext.InitializeImports(ImportsList);
4793 current_namespace = new Namespace (null, RootContext.RootNamespace);
4794 current_container = RootContext.Tree.Types;
4795 current_container.Namespace = current_namespace;
4796 oob_stack = new Stack ();
4797 switch_stack = new Stack ();
4798 expr_stack = new Stack ();
4799 tmp_blocks = new Stack();
4800 with_stack = new Stack();
4801 statement_stack = new Stack();
4803 UseExtendedSyntax = name.EndsWith(".mbs");
4804 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4805 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4806 OptionCompareBinary = InitialOptionCompareBinary;
4808 lexer = new Tokenizer (input, name, defines);
4810 ifElseStateMachine = new IfElseStateMachine();
4811 tokenizerController = new TokenizerController(lexer);
4813 StringBuilder value = new StringBuilder ();
4815 if (yacc_verbose_flag)
4816 yyparse (lexer, new yydebug.yyDebugSimple ());
4822 catch(MBASException e) {
4823 Report.Error(e.code, e.loc, e.Message);
4825 catch (Exception e) {
4826 Report.Error (29999, lexer.Location, "Parsing error");
4829 RootContext.VerifyImports();
4831 return Report.Errors;
4837 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
4839 catch(ApplicationException) {
4840 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4843 if(in_external_source)
4844 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
4846 if(in_marked_region > 0)
4847 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
4850 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
4853 tokenizerController.PositionTokenizerCursor(tok, expr);
4855 catch(ApplicationException) {
4856 tok = IfElseStateMachine.Token.EOF;
4858 ifElseStateMachine.HandleToken(tok);
4860 catch(ApplicationException) {
4861 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);