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)$4).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);
2149 : /* empty */ { $$ = null; }
2150 | HANDLES qualified_identifier
2152 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
2154 | HANDLES MYBASE DOT qualified_identifier
2156 // FIXME: this is blatantly wrong and crash-prone
2157 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2161 constructor_declaration
2162 : SUB NEW opt_params logical_end_of_line
2164 current_local_parameters = (Parameters) $3;
2166 oob_stack.Push (lexer.Location);
2168 Location l = (Location) oob_stack.Pop ();
2169 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2174 Constructor c = (Constructor) $1;
2175 c.Block = (Block) end_block();
2176 c.ModFlags = (int) current_modifiers;
2177 c.OptAttributes = current_attributes;
2179 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2181 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2182 current_local_parameters = null;
2184 END SUB logical_end_of_line
2187 opt_formal_parameter_list
2190 $$ = Parameters.EmptyReadOnlyParameters;
2192 | formal_parameter_list
2195 //Parameter p = ((Parameters) $1).FixedParameters[0];
2199 formal_parameter_list
2202 ArrayList pars_list = (ArrayList) $1;
2204 Parameter [] pars = new Parameter [pars_list.Count];
2205 pars_list.CopyTo (pars);
2206 $$ = new Parameters (pars, null, lexer.Location);
2208 | fixed_parameters COMMA parameter_array
2210 ArrayList pars_list = (ArrayList) $1;
2212 Parameter [] pars = new Parameter [pars_list.Count];
2213 pars_list.CopyTo (pars);
2215 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
2219 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
2226 ArrayList pars = new ArrayList ();
2231 | fixed_parameters COMMA fixed_parameter
2233 ArrayList pars = (ArrayList) $1;
2242 opt_parameter_modifier
2243 identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
2245 Parameter.Modifier pm = (Parameter.Modifier)$2;
2246 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2249 if (opt_parm && ($7 == null))
2250 Report.Error (30812, "Optional parameters must have a default value");
2253 if ((pm & Parameter.Modifier.REF) !=0)
2254 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
2256 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
2259 if ($4 != null && $6 != null && $4 != $6)
2260 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2262 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2264 string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
2265 ptype = DecomposeQI (t, lexer.Location);
2267 $$ = new Parameter (ptype, (string) $3, pm,
2268 (Attributes) $1, (Expression) $7, opt_parm);
2273 : PARAM_ARRAY identifier opt_parens AS type
2275 string s_patype = ((Expression) $5).ToString();
2279 Expression patype = DecomposeQI (s_patype, Location.Null);
2280 $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
2281 // note ("type must be a single-dimension array type");
2288 | OPEN_PARENS CLOSE_PARENS
2292 opt_parameter_modifier
2293 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2294 | parameter_modifiers { $$ = $1; }
2298 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2299 | parameter_modifier { $$ = $1; }
2303 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2304 | BYVAL { $$ = Parameter.Modifier.VAL; }
2305 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2310 | statement_list end_of_stmt
2315 | statement_list end_of_stmt statement
2319 declaration_statement
2321 if ($1 != null && (Block) $1 != current_block){
2322 current_block.AddStatement ((Statement) $1);
2323 current_block = (Block) $1;
2326 | embedded_statement
2328 Statement s = (Statement) $1;
2330 current_block.AddStatement ((Statement) $1);
2333 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2335 AddHandler ((Expression) $2, (string) $5);
2337 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2339 RemoveHandler ((Expression) $2, (string) $5);
2341 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2343 RaiseEvent ((string) $2, (ArrayList) $3);
2345 /* | array_handling_statement */
2346 /* | empty_statement */
2349 Statement s = (Statement) $1;
2351 current_block.AddStatement ((Statement) $1);
2355 opt_raise_event_args
2356 : /* empty */ { $$ = null; }
2357 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2374 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2376 if (!current_block.AddLabel ((string) $1, labeled)){
2377 Location l = lexer.Location;
2378 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2380 current_block.AddStatement (labeled);
2384 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2386 if (!current_block.AddLabel ((string) $1, labeled)){
2387 Location l = lexer.Location;
2388 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2390 current_block.AddStatement (labeled);
2396 : expression_statement
2397 | selection_statement
2398 | iteration_statement
2400 | synclock_statement
2402 | array_handling_statement
2408 $$ = new EmptyStatement ();
2414 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2416 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2417 Expression e = (Expression) $2;
2424 Block b = end_block();
2431 array_handling_statement
2437 : REDIM opt_preserve redim_clauses
2439 ArrayList list = (ArrayList) $3;
2440 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2447 : /* empty */ { $$ = false; }
2448 | PRESERVE { $$ = true; }
2454 ArrayList clauses = new ArrayList ();
2459 | redim_clauses COMMA redim_clause
2461 ArrayList clauses = (ArrayList) ($1);
2469 : invocation_expression
2471 Invocation i = (Invocation) $1;
2472 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2478 : ERASE erase_clauses
2480 ArrayList list = (ArrayList) $2;
2481 foreach(Expression e in list)
2483 Erase r = new Erase (e, lexer.Location);
2492 ArrayList clauses = new ArrayList ();
2497 | erase_clauses COMMA erase_clause
2499 ArrayList clauses = (ArrayList) ($1);
2507 : primary_expression
2512 | continue_statement
2513 | */return_statement
2523 $$ = new Goto (current_block, (string) $2, lexer.Location);
2528 : THROW opt_expression
2530 $$ = new Throw ((Expression) $2, lexer.Location);
2537 $$ = new Exit ((ExitType)$2, lexer.Location);
2542 : DO { $$ = ExitType.DO; }
2543 | FOR { $$ = ExitType.FOR; }
2544 | WHILE { $$ = ExitType.WHILE; }
2545 | SELECT { $$ = ExitType.SELECT; }
2546 | SUB { $$ = ExitType.SUB; }
2547 | FUNCTION { $$ = ExitType.FUNCTION; }
2548 | PROPERTY { $$ = ExitType.PROPERTY; }
2549 | TRY { $$ = ExitType.TRY; }
2552 : RETURN opt_expression
2554 $$ = new Return ((Expression) $2, lexer.Location);
2566 : FOR EACH identifier IN
2568 oob_stack.Push (lexer.Location);
2570 expression end_of_stmt
2574 Block foreach_block = current_block;
2575 Location l = lexer.Location;
2576 LocalVariableReference v = null;
2579 vi = foreach_block.GetVariableInfo ((string) $3);
2581 // Get a reference to this variable.
2582 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2585 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2592 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2593 Block foreach_block = end_block();
2594 Location l = (Location) oob_stack.Pop ();
2598 f = new Foreach (null, v, (Expression) $6, foreach_block, l);
2608 if (!UseExtendedSyntax)
2614 if (iterator_container == null){
2615 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2618 iterator_container.SetYields ();
2619 $$ = new Yield ((Expression) $2, lexer.Location);
2624 if (!UseExtendedSyntax)
2630 if (iterator_container == null){
2631 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2634 iterator_container.SetYields ();
2635 $$ = new YieldBreak (lexer.Location);
2641 : SYNCLOCK expression end_of_stmt
2648 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2665 tmp_catch_clauses = (ArrayList) $5;
2674 ArrayList s = new ArrayList ();
2676 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2683 // Now s contains the list of specific catch clauses
2684 // and g contains the general one.
2685 Block b = end_block();
2687 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2694 tmp_block = end_block();
2704 ArrayList s = new ArrayList ();
2705 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2707 if (catch_list != null){
2708 foreach (Catch cc in catch_list) {
2716 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2722 : /* empty */ { $$ = null; }
2729 ArrayList l = new ArrayList ();
2734 | catch_clauses catch_clause
2736 ArrayList l = (ArrayList) $1;
2744 : /* empty */ { $$ = null; }
2749 : CATCH opt_catch_args end_of_stmt
2751 Expression type = null;
2755 DictionaryEntry cc = (DictionaryEntry) $2;
2756 type = (Expression) cc.Key;
2757 id = (string) cc.Value;
2760 ArrayList one = new ArrayList ();
2761 Location loc = lexer.Location;
2763 one.Add (new VariableDeclaration (id, type, loc));
2767 current_block = new Block (current_block);
2768 Block b = declare_local_variables (type, one, loc);
2774 opt_statement_list {
2775 Expression type = null;
2777 Block b_catch = current_block;
2780 DictionaryEntry cc = (DictionaryEntry) $2;
2781 type = (Expression) cc.Key;
2782 id = (string) cc.Value;
2786 // FIXME: I can change this for an assignment.
2788 while (current_block != (Block) $1)
2789 current_block = current_block.Parent;
2793 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2798 : /* empty */ { $$ = null; }
2803 : identifier AS type
2805 $$ = new DictionaryEntry ($3, $1);
2811 : DO opt_do_construct end_of_stmt
2814 oob_stack.Push (lexer.Location);
2817 LOOP opt_do_construct
2819 Expression t_before = (Expression) $2;
2820 Expression t_after = (Expression) $7;
2823 if ((t_before != null) && (t_after != null))
2824 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2826 if ((t_before == null) && (t_after == null))
2827 t = new BoolLiteral (true);
2829 t = (t_before != null) ? t_before : t_after;
2831 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2833 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2834 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2835 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2837 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2842 : /* empty */ { $$ = null; }
2843 | while_or_until boolean_expression
2845 do_type = (DoOptions)$1;
2846 $$ = (Expression) $2;
2851 : WHILE { $$ = DoOptions.WHILE; }
2852 | UNTIL { $$ = DoOptions.UNTIL; }
2859 oob_stack.Push (lexer.Location);
2861 boolean_expression end_of_stmt
2865 Location l = (Location) oob_stack.Pop ();
2866 Block b = end_block();
2867 Expression e = (Expression) $3;
2868 $$ = new While ((Expression) e, (Statement) b, l);
2874 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2881 Block statement = end_block();
2882 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2884 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2885 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2886 for_var, (Expression) $6, lexer.Location);
2887 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2888 for_var, (Expression) $7, lexer.Location), lexer.Location);
2890 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2891 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2893 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2898 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2899 | STEP expression { $$ = $2; }
2908 : if_statement_open opt_then if_statement_rest
2912 | if_statement_open THEN pre_embedded_statement
2914 Location l = (Location) oob_stack.Pop ();
2915 tmp_expr = (Expression)expr_stack.Pop();
2916 $$ = new If ((Expression) tmp_expr, end_block(), l);
2920 pre_embedded_statement
2921 : embedded_statement
2923 Statement s = (Statement) $1;
2925 current_block.AddStatement ((Statement) $1);
2930 : IF boolean_expression
2932 oob_stack.Push (lexer.Location);
2934 tmp_expr = (Expression) $2;
2935 expr_stack.Push(tmp_expr);
2949 Location l = (Location) oob_stack.Pop ();
2950 Expression expr = (Expression)expr_stack.Pop();
2951 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2957 Block bl = end_block();
2958 tmp_blocks.Push(bl);
2964 Location l = (Location) oob_stack.Pop ();
2965 tmp_expr = (Expression)expr_stack.Pop();
2966 tmp_block = (Block) tmp_blocks.Pop();
2967 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2971 ELSEIF boolean_expression opt_then
2973 tmp_expr = (Expression) $4;
2974 expr_stack.Push(tmp_expr);
2975 tmp_block = end_block();
2976 tmp_blocks.Push(tmp_block);
2979 else_if_statement_rest
2981 Statement stmt = (Statement) statement_stack.Pop();
2982 Block bl = (Block) tmp_blocks.Pop();
2983 Expression expr = (Expression)expr_stack.Pop();
2984 Location l = (Location) oob_stack.Pop ();
2985 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
2990 else_if_statement_rest
2995 Location l = (Location) oob_stack.Pop ();
2997 Expression expr = (Expression)expr_stack.Pop();
2998 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
2999 statement_stack.Push(stmt);
3005 Block bl = end_block();
3006 tmp_blocks.Push(bl);
3012 Location l = (Location) oob_stack.Pop ();
3014 Expression expr = (Expression)expr_stack.Pop();
3015 Block bl = (Block)tmp_blocks.Pop();
3016 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3017 statement_stack.Push(stmt);
3021 ELSEIF boolean_expression opt_then
3023 expr_stack.Push((Expression) $4);
3024 Block bl = end_block();
3025 tmp_blocks.Push(bl);
3028 else_if_statement_rest
3030 Location l = (Location) oob_stack.Pop ();
3032 Statement tmp_stmt = (Statement)statement_stack.Pop();
3033 Block bl = (Block) tmp_blocks.Pop();
3034 Expression expr = (Expression)expr_stack.Pop();
3035 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3036 statement_stack.Push(stmt);
3041 : SELECT opt_case expression end_of_stmt
3043 oob_stack.Push (lexer.Location);
3044 switch_stack.Push (current_block);
3049 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3050 current_block = (Block) switch_stack.Pop ();
3055 : /* empty */ { $$ = null; }
3056 | case_sections { $$ = $1; }
3060 : case_sections case_section
3062 ArrayList sections = (ArrayList) $1;
3069 ArrayList sections = new ArrayList ();
3083 : CASE case_clauses ends
3089 //Block topmost = current_block;
3090 Block topmost = end_block();
3092 while (topmost.Implicit)
3093 topmost = topmost.Parent;
3095 // FIXME: This is a horrible hack which MUST go
3096 topmost.statements.Add (new Break (lexer.Location));
3097 $$ = new SwitchSection ((ArrayList) $2, topmost);
3100 /* FIXME: we should somehow flag an error
3101 (BC30321 'Case' cannot follow a 'Case Else'
3102 in the same 'Select' statement.)
3103 if Case Else is not the last of the Case clauses
3110 //Block topmost = current_block;
3111 Block topmost = end_block();
3113 while (topmost.Implicit)
3114 topmost = topmost.Parent;
3116 // FIXME: This is a horrible hack which MUST go
3117 topmost.statements.Add (new Break (lexer.Location));
3119 ArrayList a = new ArrayList();
3120 a.Add (new SwitchLabel (null, lexer.Location));
3121 $$ = new SwitchSection ((ArrayList) a, topmost);
3128 ArrayList labels = new ArrayList ();
3133 | case_clauses COMMA case_clause
3135 ArrayList labels = (ArrayList) ($1);
3143 : opt_is comparison_operator expression
3146 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3168 expression_statement
3169 : statement_expression
3176 statement_expression
3177 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3178 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3179 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3182 object_creation_expression
3183 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3185 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3189 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3193 array_creation_expression
3194 : object_creation_expression array_initializer
3197 ArrayList dims = new ArrayList();
3199 if (n.Arguments != null) {
3200 foreach (Argument a in n.Arguments) {
3205 Expression atype = n.RequestedType;
3207 ArrayList init = (ArrayList) $2;
3208 if (init.Count == 0)
3211 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3212 VariableDeclaration.VBFixIndexList (ref dims);
3213 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3217 string rank = VariableDeclaration.BuildRank (dims);
3218 $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
3220 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3225 : object_creation_expression
3226 | array_creation_expression
3229 declaration_statement
3230 : local_variable_declaration
3233 DictionaryEntry de = (DictionaryEntry) $1;
3235 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3238 | local_constant_declaration
3241 DictionaryEntry de = (DictionaryEntry) $1;
3243 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3248 local_variable_declaration
3249 : DIM variable_declarators
3251 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3256 local_constant_declaration
3257 : CONST constant_declarators
3260 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3266 constant_declarators
3267 : constant_declarator
3269 ArrayList decl = new ArrayList ();
3275 | constant_declarators COMMA constant_declarator
3277 ArrayList decls = (ArrayList) $1;
3286 : variable_name opt_type_decl opt_variable_initializer
3288 VarName vname = (VarName) $1;
3289 string varname = (string) vname.Name;
3290 current_rank_specifiers = (ArrayList) vname.Rank;
3291 object varinit = $3;
3292 ArrayList a_dims = null;
3294 if (varinit == null)
3296 30438, lexer.Location, "Constant should have a value"
3299 if (vname.Type != null && $2 != null)
3301 30302, lexer.Location,
3302 "Type character cannot be used with explicit type declaration" );
3304 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3306 if (current_rank_specifiers != null)
3308 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3312 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3316 variable_declarators
3317 : variable_declarator
3319 ArrayList decl = new ArrayList ();
3320 decl.AddRange ((ArrayList) $1);
3323 | variable_declarators COMMA variable_declarator
3325 ArrayList decls = (ArrayList) $1;
3326 decls.AddRange ((ArrayList) $3);
3332 : variable_names opt_type_decl opt_variable_initializer
3334 ArrayList names = (ArrayList) $1;
3335 object varinit = $3;
3336 ArrayList VarDeclarations = new ArrayList();
3338 ArrayList a_dims = null;
3340 if ((names.Count > 1) && (varinit != null))
3342 30671, lexer.Location,
3343 "Multiple variables with single type can not have " +
3344 "a explicit initialization" );
3347 foreach (VarName vname in names)
3349 string varname = (string) vname.Name;
3350 current_rank_specifiers = (ArrayList) vname.Rank;
3354 if(vname.Type != null && $2 != null)
3356 30302, lexer.Location,
3357 "Type character cannot be used with explicit type declaration" );
3359 // Some checking is required for particularly weird declarations
3360 // like Dim a As Integer(,)
3362 vartype = (Expression) ((Pair) $2).First;
3364 /*if ($3 != null && $3 is ArrayList)
3365 Report.Error (205, "End of statement expected.");*/
3367 ArrayList args = (ArrayList) ((Pair) $2).Second;
3368 if (current_rank_specifiers != null)
3369 Report.Error (31087, lexer.Location,
3370 "Array types specified in too many places");
3372 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3373 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3375 current_rank_specifiers = new ArrayList ();
3376 current_rank_specifiers.Add (args);
3378 /*string s_vartype = vartype.ToString();
3381 for (int x = 0; x < args.Count; x++)
3385 vartype = DecomposeQI(s_vartype, Location.Null); */
3388 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3390 // if the variable is an array with explicit bound
3391 // and having explicit initialization throw exception
3392 if (current_rank_specifiers != null && varinit != null)
3394 bool broken = false;
3395 foreach (ArrayList exprs in current_rank_specifiers)
3397 foreach (Expression expr in exprs)
3399 if (!((Expression)expr is EmptyExpression ))
3402 30672, lexer.Location,
3403 "Array declared with explicit bound " +
3404 " can not have explicit initialization");
3415 Check for a declaration like Dim a(2) or Dim a(2,3)
3416 If this is the case, we must generate an ArrayCreationExpression
3417 and, in case, add the initializer after the array has been created.
3419 if (VariableDeclaration.IsArrayDecl (this)) {
3420 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3421 a_dims = (ArrayList) current_rank_specifiers;
3422 VariableDeclaration.VBFixIndexLists (ref a_dims);
3423 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3425 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
3428 if (vartype is New) {
3429 if (varinit != null) {
3430 Report.Error (30205, lexer.Location, "End of statement expected");
3436 vartype = ((New)vartype).RequestedType;
3439 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3441 $$ = VarDeclarations;
3448 ArrayList list = new ArrayList ();
3452 | variable_names COMMA variable_name
3454 ArrayList list = (ArrayList) $1;
3461 : identifier opt_type_character opt_array_name_modifier
3463 $$ = new VarName ($1, $2, $3);
3474 $$ = (Expression) $2;
3480 | AS type rank_specifiers
3482 $$ = TypeManager.system_object_expr;
3491 | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
3493 $$ = new Pair ($2, $4);
3497 New n = new New ((Expression)$3, null, lexer.Location);
3498 $$ = (Expression) n;
3500 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3502 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3503 $$ = (Expression) n;
3505 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3507 ArrayList args = new ArrayList();
3508 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3511 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3512 $$ = (Expression) n;
3516 opt_array_name_modifier
3517 : /* empty */ { $$ = null; }
3518 | array_type_modifier { $$ = $1; }
3522 : rank_specifiers { $$ = $1; }
3525 opt_variable_initializer
3526 : /* empty */ { $$ = null; }
3527 | ASSIGN variable_initializer { $$ = $2; }
3530 variable_initializer
3543 : OPEN_BRACE CLOSE_BRACE
3545 ArrayList list = new ArrayList ();
3548 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3550 $$ = (ArrayList) $2;
3554 variable_initializer_list
3555 : variable_initializer
3557 ArrayList list = new ArrayList ();
3561 | variable_initializer_list COMMA variable_initializer
3563 ArrayList list = (ArrayList) $1;
3584 ArrayList rs = new ArrayList();
3588 | rank_specifiers rank_specifier
3590 ArrayList rs = (ArrayList) $1;
3597 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
3606 ArrayList ds = new ArrayList();
3607 ds.Add (new EmptyExpression());
3612 ArrayList ds = (ArrayList) $1;
3613 ds.Add (new EmptyExpression());
3625 ArrayList ds = new ArrayList();
3626 ds.Add (new EmptyExpression());
3629 | dim_separators COMMA
3631 ArrayList ds = (ArrayList) $1;
3632 ds.Add (new EmptyExpression());
3640 ArrayList ds = new ArrayList();
3641 ds.Add ((Expression) $1);
3644 | dim_specifiers COMMA expression
3646 ArrayList ds = (ArrayList) $1;
3647 ds.Add ((Expression) $3);
3657 | parenthesized_expression
3660 | qualified_identifier
3662 string name = (string) $1;
3663 $$ = DecomposeQI (name, lexer.Location);
3665 //FIXME: address_of_expression is apparently missing here
3666 | get_type_expression
3668 | invocation_expression
3678 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3679 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3680 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3681 | NOTHING { $$ = NullLiteral.Null; }
3685 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3686 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3687 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3692 object v = lexer.Value;
3695 $$ = new IntLiteral ((Int32)v);
3696 else if (v is short)
3697 $$ = new ShortLiteral ((Int16)v);
3699 $$ = new LongLiteral ((Int64)v);
3701 Console.WriteLine ("OOPS. Unexpected result from scanner");
3707 : TRUE { $$ = new BoolLiteral (true); }
3708 | FALSE { $$ = new BoolLiteral (false); }
3711 parenthesized_expression
3712 : OPEN_PARENS expression CLOSE_PARENS
3717 : primary_expression DOT identifier
3720 string id_name = (string)$3;
3721 if (id_name.ToUpper() == "NEW")
3723 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3727 if (with_stack.Count > 0) {
3728 Expression e = (Expression) with_stack.Peek();
3729 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3737 /* | primary_expression DOT NEW
3739 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3741 | predefined_type DOT identifier
3744 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3747 if (with_stack.Count > 0) {
3748 Expression e = (Expression) with_stack.Peek();
3749 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3763 invocation_expression
3764 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3767 Location l = lexer.Location;
3768 Report.Error (1, l, "THIS IS CRAZY");
3770 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3771 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3776 : MYBASE DOT IDENTIFIER
3778 string id_name = (string) $3;
3779 if (id_name.ToUpper() == "NEW")
3781 $$ = new BaseAccess (id_name, lexer.Location);
3785 $$ = new BaseAccess ("New", lexer.Location);
3793 The 'argument' rule returns an 'empty' argument
3794 of type NoArg (used for default arguments in invocations)
3795 if no arguments are actually passed.
3797 If there is only one argument and it is o type NoArg,
3798 we return a null (empty) list
3800 ArrayList args = (ArrayList) $1;
3801 if (args.Count == 1 &&
3802 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3812 ArrayList list = new ArrayList ();
3816 | argument_list COMMA argument
3818 ArrayList list = (ArrayList) $1;
3827 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3829 | BYREF variable_reference
3831 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3835 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3837 | ADDRESSOF expression
3839 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
3844 : expression {/* note ("section 5.4"); */ $$ = $1; }
3849 : conditional_xor_expression { $$ = $1; }
3850 /*| assignment_expression*/
3861 $$ = new This (current_block, lexer.Location);
3865 // FIXME: This is actually somewhat different from Me
3866 // because it is for accessing static (classifier) methods/properties/fields
3867 $$ = new This (current_block, lexer.Location);
3872 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
3876 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3878 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3880 | cast_operator OPEN_PARENS expression CLOSE_PARENS
3882 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3887 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3888 | CBYTE { $$ = TypeManager.system_byte_expr; }
3889 | CCHAR { $$ = TypeManager.system_char_expr; }
3890 | CDATE { $$ = TypeManager.system_date_expr; }
3891 | CDBL { $$ = TypeManager.system_double_expr; }
3892 | CDEC { $$ = TypeManager.system_decimal_expr; }
3893 | CINT { $$ = TypeManager.system_int32_expr; }
3894 | CLNG { $$ = TypeManager.system_int64_expr; }
3895 | COBJ { $$ = TypeManager.system_object_expr; }
3896 | CSHORT { $$ = TypeManager.system_int16_expr; }
3897 | CSNG { $$ = TypeManager.system_single_expr; }
3898 | CSTR { $$ = TypeManager.system_string_expr; }
3902 : GETTYPE OPEN_PARENS type CLOSE_PARENS
3904 $$ = new TypeOf ((Expression) $3, lexer.Location);
3908 exponentiation_expression
3909 : primary_expression
3910 | exponentiation_expression OP_EXP primary_expression
3916 prefixed_unary_expression
3917 : exponentiation_expression
3918 | PLUS prefixed_unary_expression
3920 //FIXME: Is this rule correctly defined ?
3921 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3923 | MINUS prefixed_unary_expression
3925 //FIXME: Is this rule correctly defined ?
3926 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3930 multiplicative_expression
3931 : prefixed_unary_expression
3932 | multiplicative_expression STAR prefixed_unary_expression
3934 $$ = new Binary (Binary.Operator.Multiply,
3935 (Expression) $1, (Expression) $3, lexer.Location);
3937 | multiplicative_expression DIV prefixed_unary_expression
3939 $$ = new Binary (Binary.Operator.Division,
3940 (Expression) $1, (Expression) $3, lexer.Location);
3944 integer_division_expression
3945 : multiplicative_expression
3946 | integer_division_expression OP_IDIV multiplicative_expression
3948 //FIXME: Is this right ?
3949 $$ = new Binary (Binary.Operator.Division,
3950 (Expression) $1, (Expression) $3, lexer.Location);
3955 : integer_division_expression
3956 | mod_expression MOD integer_division_expression
3958 $$ = new Binary (Binary.Operator.Modulus,
3959 (Expression) $1, (Expression) $3, lexer.Location);
3965 | additive_expression PLUS mod_expression
3967 $$ = new Binary (Binary.Operator.Addition,
3968 (Expression) $1, (Expression) $3, lexer.Location);
3970 | additive_expression MINUS mod_expression
3972 $$ = new Binary (Binary.Operator.Subtraction,
3973 (Expression) $1, (Expression) $3, lexer.Location);
3978 : additive_expression
3979 | concat_expression OP_CONCAT additive_expression
3981 // FIXME: This should only work for String expressions
3982 // We probably need to use something from the runtime
3983 $$ = new Binary (Binary.Operator.Addition,
3984 (Expression) $1, (Expression) $3, lexer.Location);
3990 | shift_expression OP_SHIFT_LEFT concat_expression
3994 | shift_expression OP_SHIFT_RIGHT concat_expression
4000 relational_expression
4002 | relational_expression ASSIGN shift_expression
4004 $$ = new Binary (Binary.Operator.Equality,
4005 (Expression) $1, (Expression) $3, lexer.Location);
4007 | relational_expression OP_NE shift_expression
4009 $$ = new Binary (Binary.Operator.Inequality,
4010 (Expression) $1, (Expression) $3, lexer.Location);
4012 | relational_expression OP_LT shift_expression
4014 $$ = new Binary (Binary.Operator.LessThan,
4015 (Expression) $1, (Expression) $3, lexer.Location);
4017 | relational_expression OP_GT shift_expression
4019 $$ = new Binary (Binary.Operator.GreaterThan,
4020 (Expression) $1, (Expression) $3, lexer.Location);
4022 | relational_expression OP_LE shift_expression
4024 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4025 (Expression) $1, (Expression) $3, lexer.Location);
4027 | relational_expression OP_GE shift_expression
4029 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4030 (Expression) $1, (Expression) $3, lexer.Location);
4032 | relational_expression IS shift_expression
4034 //FIXME: Should be a different op for reference equality but allows tests to use Is
4035 $$ = new Binary (Binary.Operator.Equality,
4036 (Expression) $1, (Expression) $3, lexer.Location);
4038 | TYPEOF shift_expression IS type
4040 //FIXME: Is this rule correctly defined ?
4041 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4046 : relational_expression
4047 | NOT negation_expression
4049 //FIXME: Is this rule correctly defined ?
4050 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4054 conditional_and_expression
4055 : negation_expression
4056 | conditional_and_expression AND negation_expression
4058 $$ = new Binary (Binary.Operator.LogicalAnd,
4059 (Expression) $1, (Expression) $3, lexer.Location);
4061 | conditional_and_expression ANDALSO negation_expression
4062 { // FIXME: this is likely to be broken
4063 $$ = new Binary (Binary.Operator.LogicalAnd,
4064 (Expression) $1, (Expression) $3, lexer.Location);
4068 conditional_or_expression
4069 : conditional_and_expression
4070 | conditional_or_expression OR conditional_and_expression
4072 $$ = new Binary (Binary.Operator.LogicalOr,
4073 (Expression) $1, (Expression) $3, lexer.Location);
4075 | conditional_or_expression ORELSE conditional_and_expression
4076 { // FIXME: this is likely to be broken
4077 $$ = new Binary (Binary.Operator.LogicalOr,
4078 (Expression) $1, (Expression) $3, lexer.Location);
4082 conditional_xor_expression
4083 : conditional_or_expression
4084 | conditional_xor_expression XOR conditional_or_expression
4086 $$ = new Binary (Binary.Operator.ExclusiveOr,
4087 (Expression) $1, (Expression) $3, lexer.Location);
4091 assignment_expression
4092 : prefixed_unary_expression ASSIGN expression
4094 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4096 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4098 ArrayList args = new ArrayList();
4099 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4102 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4103 n.isDelegate = true;
4104 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4117 : namespace_or_type_name
4119 $$ = DecomposeQI ((string) $1, lexer.Location);
4128 ArrayList types = new ArrayList ();
4133 | type_list COMMA type
4135 ArrayList types = (ArrayList) $1;
4142 namespace_or_type_name
4143 : qualified_identifier
4147 : OBJECT { $$ = TypeManager.system_object_expr; }
4153 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4154 | DATE { $$ = TypeManager.system_date_expr; }
4155 | CHAR { $$ = TypeManager.system_char_expr; }
4156 | STRING { $$ = TypeManager.system_string_expr; }
4162 | floating_point_type
4163 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4168 | BYTE { $$ = TypeManager.system_byte_expr; }
4169 | SHORT { $$ = TypeManager.system_int16_expr; }
4170 | INTEGER { $$ = TypeManager.system_int32_expr; }
4171 | LONG { $$ = TypeManager.system_int64_expr; }
4175 : SINGLE { $$ = TypeManager.system_single_expr; }
4176 | DOUBLE { $$ = TypeManager.system_double_expr; }
4180 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4182 if(tokenizerController.IsAcceptingTokens)
4184 if(in_external_source)
4185 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4187 in_external_source = true;
4189 lexer.EffectiveSource = (string) $4;
4190 lexer.EffectiveLine = (int) $6;
4194 | HASH IDENTIFIER LITERAL_STRING EOL
4196 if(tokenizerController.IsAcceptingTokens)
4198 string id = ($2 as string);
4200 if(!($2 as string).ToLower().Equals("region"))
4201 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4208 | HASH END IDENTIFIER EOL
4210 if(tokenizerController.IsAcceptingTokens)
4212 if( ($3 as string).ToLower().Equals("externalsource")) {
4213 if(!in_external_source)
4214 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4216 in_external_source = false;
4217 lexer.EffectiveSource = lexer.Source;
4218 lexer.EffectiveLine = lexer.Line;
4221 else if(($3 as string).ToLower().Equals("region")) {
4222 if(in_marked_region > 0)
4225 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4228 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4232 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4234 if(tokenizerController.IsAcceptingTokens)
4241 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4244 ifElseStateMachine.HandleToken(tok);
4246 catch(ApplicationException) {
4247 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4250 boolean_literal opt_then EOL
4252 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4256 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4258 ifElseStateMachine.HandleToken(tok);
4260 catch(ApplicationException) {
4261 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4264 boolean_literal opt_then EOL
4266 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4270 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4272 ifElseStateMachine.HandleToken(tok);
4274 catch(ApplicationException) {
4275 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4280 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4284 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4286 ifElseStateMachine.HandleToken(tok);
4288 catch(ApplicationException) {
4289 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4294 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4298 if(tokenizerController.IsAcceptingTokens)
4299 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4301 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4311 public Tokenizer Lexer {
4317 public static Expression DecomposeQI (string name, Location loc)
4321 if (name.IndexOf ('.') == -1){
4322 return new SimpleName (name, loc);
4324 int pos = name.LastIndexOf (".");
4325 string left = name.Substring (0, pos);
4326 string right = name.Substring (pos + 1);
4328 o = DecomposeQI (left, loc);
4330 return new MemberAccess (o, right, loc);
4334 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4336 Block implicit_block;
4337 ArrayList inits = null;
4340 // We use the `Used' property to check whether statements
4341 // have been added to the current block. If so, we need
4342 // to create another block to contain the new declaration
4343 // otherwise, as an optimization, we use the same block to
4344 // add the declaration.
4346 // FIXME: A further optimization is to check if the statements
4347 // that were added were added as part of the initialization
4348 // below. In which case, no other statements have been executed
4349 // and we might be able to reduce the number of blocks for
4350 // situations like this:
4352 // int j = 1; int k = j + 1;
4355 VariableDeclaration.FixupTypes (variable_declarators);
4357 if (current_block.Used) {
4358 implicit_block = new Block (current_block, true, loc, Location.Null);
4359 implicit_block.AddChildVariableNames (current_block);
4361 implicit_block = current_block;
4363 foreach (VariableDeclaration decl in variable_declarators){
4364 Expression type = decl.type;
4365 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4366 if (decl.expression_or_array_initializer != null){
4368 inits = new ArrayList ();
4375 return implicit_block;
4377 foreach (VariableDeclaration decl in inits){
4380 Expression type = decl.type;
4382 if ((decl.expression_or_array_initializer is Expression) ||
4383 (decl.expression_or_array_initializer is New)) {
4384 expr = (Expression) decl.expression_or_array_initializer;
4386 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4388 expr = new ArrayCreation (type, "", init, decl.Location);
4391 LocalVariableReference var;
4392 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4394 assign = new Assign (var, expr, decl.Location);
4396 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4399 return implicit_block;
4402 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4404 Block implicit_block;
4405 VariableDeclaration.FixupTypes (variable_declarators);
4407 if (current_block.Used)
4408 implicit_block = new Block (current_block, true);
4410 implicit_block = current_block;
4412 foreach (VariableDeclaration decl in variable_declarators){
4413 Expression type = decl.type;
4414 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4415 current_local_parameters, decl.Location);
4418 return implicit_block;
4426 public VarName (object n, object t, object r)
4436 // A class used to pass around variable declarations and constants
4438 public class VariableDeclaration {
4439 public string identifier;
4440 public object expression_or_array_initializer;
4441 public Location Location;
4442 public Attributes OptAttributes;
4443 public Expression type;
4444 public ArrayList dims;
4446 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4448 this.identifier = id;
4449 this.expression_or_array_initializer = eoai;
4451 this.OptAttributes = opt_attrs;
4456 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4460 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4464 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4465 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4469 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4471 // FIXME : This is broken: only the first rank is parsed
4472 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4475 public static void FixupTypes (ArrayList vars)
4477 int varcount = vars.Count;
4478 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4480 if (last_var.type == null)
4481 last_var.type = TypeManager.system_object_expr;
4483 Expression cur_type = last_var.type;
4484 int n = varcount - 1;
4487 VariableDeclaration var = (VariableDeclaration) vars[n--];
4488 if (var.type == null)
4489 var.type = cur_type;
4491 cur_type = var.type;
4495 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4499 if (IndexList != null) {
4500 foreach (Expression e in IndexList)
4501 if (!(e is EmptyExpression)) {
4510 public static bool IndexesSpecified (ArrayList ranks)
4514 if (ranks != null) {
4515 foreach (ArrayList IndexList in ranks) {
4516 if (IndexesSpecifiedInRank (IndexList)) {
4525 public static string StripDims (string varname, ref string d)
4527 string res = varname;
4530 if (varname.IndexOf("[") >= 0) {
4531 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4532 res = varname.Substring(0, varname.IndexOf("["));
4538 public static string StripDims (string varname)
4542 return (StripDims(varname, ref dres));
4545 public static string StripIndexesFromDims (string dims)
4547 StringBuilder sb = new StringBuilder();
4549 foreach (char c in dims)
4550 if (c == ',' || c == ']' || c == '[')
4553 return sb.ToString();
4556 public static string BuildRank (ArrayList rank)
4561 for (int x = 0; x < (rank.Count -1 ); x++)
4568 public static string BuildRanks (Parser t)
4572 foreach (ArrayList rank in t.current_rank_specifiers)
4573 res += BuildRank (rank);
4578 public static void VBFixIndexList (ref ArrayList IndexList)
4580 if (IndexList != null) {
4581 for (int x = 0; x < IndexList.Count; x++) {
4582 Expression e = (Expression) IndexList[x];
4583 if (!(e is EmptyExpression)) {
4584 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4590 public static bool IsArrayDecl (Parser t)
4592 // return (varname.IndexOf("[") >= 0);
4593 return (t.current_rank_specifiers != null);
4596 public static void VBFixIndexLists (ref ArrayList ranks)
4598 if (ranks != null) {
4599 for (int x = 0; x < ranks.Count; x++) {
4600 ArrayList IndexList = (ArrayList) ranks[x];
4601 VBFixIndexList (ref IndexList);
4606 public static void FixupArrayTypes (ArrayList vars)
4608 int varcount = vars.Count;
4611 foreach (VariableDeclaration var in vars) {
4612 if (var.identifier.EndsWith(",")) {
4613 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4614 var.identifier.LastIndexOf(",")) + "]";
4615 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4616 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4623 public Property BuildSimpleProperty (Expression p_type, string name,
4624 Field p_fld, int mod_flags,
4625 Attributes attrs, Location loc)
4628 Block get_block, set_block;
4629 Accessor acc_set, acc_get;
4630 StatementExpression a_set;
4635 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4636 args = new Parameter [1];
4637 args [0] = implicit_value_parameter;
4639 Parameters set_params = new Parameters (args, null, loc);
4640 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4641 (Expression) new SimpleName("value", loc), loc), loc);
4643 set_block = new Block (current_block, set_params, loc, Location.Null);
4644 set_block.AddStatement ((Statement) a_set);
4645 acc_set = new Accessor (set_block, attrs);
4648 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4649 get_block = new Block (current_block, null, loc, Location.Null);
4650 get_block.AddStatement ((Statement) a_get);
4651 acc_get = new Accessor (get_block, attrs);
4653 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4660 current_block = new Block (current_block, current_local_parameters,
4661 lexer.Location, Location.Null);
4668 while (current_block.Implicit)
4669 current_block = current_block.Parent;
4671 res = current_block;
4673 current_block.SetEndLocation (lexer.Location);
4674 current_block = current_block.Parent;
4679 private void AddHandler (Expression evt_definition, string handler_name)
4681 AddHandler (current_block, evt_definition, handler_name);
4684 void CheckAttributeTarget (string a)
4688 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4692 Location l = lexer.Location;
4693 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4698 private void AddHandler (Block b, Expression evt_id, string handler_name)
4700 Location loc = lexer.Location;
4701 string evt_target = evt_id.ToString();
4702 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4703 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4707 private void RaiseEvent (string evt_name, ArrayList args)
4709 Location loc = lexer.Location;
4711 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4712 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4713 current_block.AddStatement (s);
4716 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4718 Location loc = lexer.Location;
4719 string evt_target = evt_definition.ToString();
4720 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4721 Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4726 // This method is used to get at the complete string representation of
4727 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4728 // This is necessary because local_variable_type admits primary_expression
4729 // as the type of the variable. So we do some extra checking
4731 string GetQualifiedIdentifier (Expression expr)
4733 if (expr is SimpleName)
4734 return ((SimpleName)expr).Name;
4735 else if (expr is MemberAccess)
4736 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4738 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4742 private void RemoveHandler (Expression evt_definition, string handler_name)
4744 RemoveHandler (current_block, evt_definition, handler_name);
4747 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4749 ConstructorInitializer ci = null;
4752 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4753 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4755 if (i.expr is BaseAccess) {
4756 BaseAccess ba = (BaseAccess) i.expr;
4757 if (ba.member == "New" || ba.member == ".ctor") {
4758 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4762 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4763 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4771 void Error_ExpectingTypeName (Location l, Expression expr)
4773 if (expr is Invocation){
4774 Report.Error (1002, l, "; expected");
4776 Report.Error (-1, l, "Invalid Type definition");
4780 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4784 private void ReportError9998()
4786 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4789 protected override int parse ()
4791 RootContext.InitializeImports(ImportsList);
4792 current_namespace = new Namespace (null, RootContext.RootNamespace);
4793 current_container = RootContext.Tree.Types;
4794 current_container.Namespace = current_namespace;
4795 oob_stack = new Stack ();
4796 switch_stack = new Stack ();
4797 expr_stack = new Stack ();
4798 tmp_blocks = new Stack();
4799 with_stack = new Stack();
4800 statement_stack = new Stack();
4802 UseExtendedSyntax = name.EndsWith(".mbs");
4803 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4804 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4805 OptionCompareBinary = InitialOptionCompareBinary;
4807 lexer = new Tokenizer (input, name, defines);
4809 ifElseStateMachine = new IfElseStateMachine();
4810 tokenizerController = new TokenizerController(lexer);
4812 StringBuilder value = new StringBuilder ();
4814 if (yacc_verbose_flag)
4815 yyparse (lexer, new yydebug.yyDebugSimple ());
4821 catch(MBASException e) {
4822 Report.Error(e.code, e.loc, e.Message);
4824 catch (Exception e) {
4825 Report.Error (29999, lexer.Location, "Parsing error");
4828 RootContext.VerifyImports();
4830 return Report.Errors;
4836 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
4838 catch(ApplicationException) {
4839 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4842 if(in_external_source)
4843 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
4845 if(in_marked_region > 0)
4846 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
4849 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
4852 tokenizerController.PositionTokenizerCursor(tok, expr);
4854 catch(ApplicationException) {
4855 tok = IfElseStateMachine.Token.EOF;
4857 ifElseStateMachine.HandleToken(tok);
4859 catch(ApplicationException) {
4860 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);