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"
569 /* VB.NET 2003 new bit-shift operators */
570 %token OP_SHIFT_LEFT "<<"
571 %token OP_SHIFT_RIGHT ">>"
574 %token LITERAL_INTEGER "int literal"
575 %token LITERAL_SINGLE "float literal"
576 %token LITERAL_DOUBLE "double literal"
577 %token LITERAL_DECIMAL "decimal literal"
578 %token LITERAL_CHARACTER "character literal"
579 %token LITERAL_STRING "string literal"
580 %token LITERAL_DATE "datetime literal"
584 /* Add precedence rules to solve dangling else s/r conflict */
593 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
595 %left STAR DIV PERCENT
596 %right BITWISE_NOT CARRET UMINUS
597 %nonassoc OP_INC OP_DEC
599 %left OPEN_BRACKET OPEN_BRACE
604 %start compilation_unit
608 : logical_end_of_line
614 | logical_end_of_line pp_directive
618 : logical_end_of_line
619 opt_option_directives
620 opt_imports_directives
621 opt_global_attributes
630 opt_option_directives
637 | option_directives option_directive
641 : option_explicit_directive
642 | option_strict_directive
643 | option_compare_directive
672 option_explicit_directive
673 : OPTION EXPLICIT on_off logical_end_of_line
675 if (!UseExtendedSyntax)
676 OptionExplicit = (bool)$3;
679 9999, lexer.Location,
680 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
685 option_strict_directive
686 : OPTION STRICT on_off logical_end_of_line
688 if (!UseExtendedSyntax)
689 OptionStrict = (bool)$3;
692 9999, lexer.Location,
693 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
697 option_compare_directive
698 : OPTION COMPARE text_or_binary logical_end_of_line
700 OptionCompareBinary = (bool)$3;
711 | declarations declaration
715 : namespace_declaration
721 if ($1 is Class || $1 is Struct || $1 is Module ){
722 TypeContainer c = (TypeContainer) $1;
723 mod_flags = c.ModFlags;
728 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
730 1527, lexer.Location,
731 "Namespace elements cannot be explicitly " +
732 "declared private or protected in '" + name + "'");
747 : PERCENT { $$ = TypeManager.system_int32_expr; }
748 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
749 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
750 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
751 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
752 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
756 : /* empty */ { $$ = null; }
757 | type_character { $$ = $1; }
763 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
765 $$ = (($1).ToString ()) + "." + ($3.ToString ());
769 opt_imports_directives
776 | imports_directives imports_directive
780 : IMPORTS imports_terms logical_end_of_line
785 | imports_terms COMMA imports_term
789 : namespace_or_type_name
791 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
793 | identifier ASSIGN namespace_or_type_name
795 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
800 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
801 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
802 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
810 Report.Error (658, lexer.Location, "`" + (string)$1 + "' is an invalid attribute target");
814 global_attribute_list
816 | global_attribute_list COMMA global_attribute
820 : attribute_modifier COLON attribute
823 global_attributes_definition
824 : attr_begin global_attribute_list attr_end
828 : global_attributes_definition
829 | global_attributes global_attributes_definition
830 | global_attributes end_of_stmt global_attributes_definition
833 opt_global_attributes
835 | global_attributes end_of_stmt
840 | attributes { $$ = $1; }
852 : attr_begin attribute_list attr_end
854 AttributeSection sect = new AttributeSection (null, (ArrayList) $2);
855 $$ = new Attributes (sect, lexer.Location);
857 | attr_begin global_attribute_list attr_end logical_end_of_line
863 ArrayList attrs = new ArrayList ();
869 | attribute_list COMMA attribute
871 ArrayList attrs = (ArrayList) $1;
883 opt_attribute_arguments
885 $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
890 : namespace_or_type_name
893 opt_attribute_arguments
894 : /* empty */ { $$ = null; }
895 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
901 opt_attribute_arguments_list
903 | attribute_arguments_list
906 attribute_arguments_list
907 : positional_argument_list
909 ArrayList args = new ArrayList ();
914 | positional_argument_list COMMA named_argument_list
916 ArrayList args = new ArrayList ();
922 | named_argument_list
924 ArrayList args = new ArrayList ();
932 positional_argument_list
933 : constant_expression
935 ArrayList args = new ArrayList ();
936 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
940 | positional_argument_list COMMA constant_expression
942 ArrayList args = (ArrayList) $1;
943 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
952 ArrayList args = new ArrayList ();
957 | named_argument_list COMMA named_argument
959 ArrayList args = (ArrayList) $1;
967 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
969 $$ = new DictionaryEntry (
971 new Argument ((Expression) $3, Argument.AType.Expression));
975 namespace_declaration
976 : NAMESPACE qualified_identifier logical_end_of_line
978 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2);
981 END NAMESPACE logical_end_of_line
983 current_namespace = current_namespace.Parent;
991 current_attributes = (Attributes) $1;
992 current_modifiers = (int) $2;
994 type_spec_declaration
997 type_spec_declaration
1000 | interface_declaration
1001 | delegate_declaration
1002 | struct_declaration
1007 : CLASS identifier logical_end_of_line opt_inherits opt_implements
1009 // Module members are static by default, but Class *can't* be declared static
1010 // so we must fix it, if mbas was the one actually responsible for this
1011 // instead of triggering an error.
1012 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1013 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1018 name = MakeName ((string) $2);
1019 new_class = new Class (current_container, name, current_modifiers,
1020 (Attributes) current_attributes, lexer.Location);
1022 current_container = new_class;
1023 current_container.Namespace = current_namespace;
1024 RootContext.Tree.RecordDecl (name, new_class);
1026 opt_class_member_declarations
1027 END CLASS logical_end_of_line
1029 Class new_class = (Class) current_container;
1031 ArrayList bases = (ArrayList) $4;
1033 ArrayList ifaces = (ArrayList) $5;
1034 if (ifaces != null){
1036 bases.AddRange(ifaces);
1040 new_class.Bases = bases;
1042 current_container = current_container.Parent;
1043 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1050 : /* empty */ { $$ = null; }
1051 | INHERITS type_list logical_end_of_line { $$ = $2; }
1055 : /* empty */ { $$ = null; }
1056 | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
1060 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1061 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1066 | modifiers modifier
1071 if ((m1 & m2) != 0) {
1072 Location l = lexer.Location;
1073 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1075 $$ = (int) (m1 | m2);
1080 : PUBLIC { $$ = Modifiers.PUBLIC; }
1081 | PROTECTED { $$ = Modifiers.PROTECTED; }
1082 | PRIVATE { $$ = Modifiers.PRIVATE; }
1083 | SHARED { $$ = Modifiers.STATIC; }
1084 | FRIEND { $$ = Modifiers.INTERNAL; }
1085 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1086 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1087 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1088 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1089 | OVERLOADS { $$ = Modifiers.NEW; }
1090 | SHADOWS { $$ = Modifiers.SHADOWS; }
1091 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1092 | READONLY { $$ = Modifiers.READONLY; }
1093 | DEFAULT { $$ = Modifiers.DEFAULT; }
1094 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1098 : MODULE identifier logical_end_of_line
1102 name = MakeName((string) $2);
1103 new_module = new Module(current_container,
1105 current_modifiers, // already checks then
1106 (Attributes) current_attributes,
1108 current_container = new_module;
1109 current_container.Namespace = current_namespace;
1110 RootContext.Tree.RecordDecl(name, new_module);
1112 opt_module_member_declarations
1113 END MODULE logical_end_of_line
1115 Module new_module = (Module)current_container;
1117 current_container = current_container.Parent;
1118 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1120 TypeManager.AddStandardModule(new_module);
1126 opt_module_member_declarations
1128 | module_member_declarations
1131 module_member_declarations
1132 : module_member_declaration
1133 | module_member_declarations module_member_declaration
1136 module_member_declaration
1140 current_attributes = (Attributes) $1;
1141 current_modifiers = ((int)$2) | Modifiers.STATIC;
1142 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1143 implicit_modifiers = (!explicit_static);
1145 module_member_declarator
1147 implicit_modifiers = false;
1152 module_member_declarator
1153 : constructor_declaration
1154 | method_declaration
1156 Method method = (Method) $1;
1157 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1160 | withevents_declaration /* This is a field but must be treated specially, see below */
1161 | constant_declaration
1162 | property_declaration
1164 | type_spec_declaration
1167 constant_declaration
1168 : CONST constant_declarators logical_end_of_line
1170 // Module members are static by default, but constants *can't* be declared static
1171 // so we must fix it, if mbas was the one actually responsible for this
1172 // instead of triggering an error.
1173 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1174 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1176 int mod = (int) current_modifiers;
1178 // Structure members are Public by default
1179 if ((current_container is Struct) && (mod == 0))
1180 mod = Modifiers.PUBLIC;
1182 ArrayList consts = (ArrayList) $2;
1183 if(consts.Count > 0)
1185 VariableDeclaration.FixupTypes ((ArrayList) $2);
1186 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1188 foreach (VariableDeclaration var in (ArrayList) $2){
1189 Location l = var.Location;
1190 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1191 (Expression)var.expression_or_array_initializer,
1192 mod, (Attributes) null, l);
1194 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1200 opt_class_member_declarations
1202 | class_member_declarations
1205 class_member_declarations
1206 : class_member_declaration
1207 | class_member_declarations class_member_declaration
1210 class_member_declaration
1214 current_attributes = (Attributes) $1;
1215 current_modifiers = (int) $2;
1217 class_member_declarator
1223 class_member_declarator
1224 : constructor_declaration
1225 | method_declaration
1227 Method method = (Method) $1;
1228 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1231 | constant_declaration
1232 | property_declaration
1234 | withevents_declaration /* This is a field but must be treated specially, see below */
1235 | type_spec_declaration
1242 | must_override_declaration
1245 must_override_declaration
1246 : must_override_sub_declaration
1247 | must_override_func_declaration
1250 must_override_sub_declaration
1251 : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
1253 if (current_container is Module)
1254 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1256 if (current_container is Struct)
1257 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1259 current_modifiers |= Modifiers.ABSTRACT;
1261 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1262 (Parameters) $4, null, (ArrayList) $5, lexer.Location);
1264 if (!(current_container is Class))
1265 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1272 must_override_func_declaration
1273 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1275 Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.
1276 system_object_expr : (Expression) $4 ) : (Expression) $6;
1278 if (current_container is Module)
1279 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1281 if (current_container is Struct)
1282 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1284 current_modifiers |= Modifiers.ABSTRACT;
1286 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1287 (string) $3,(Parameters) $5, null, (ArrayList) $7,
1290 if (!(current_container is Class))
1291 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1298 : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1300 current_local_parameters = (Parameters) $3;
1303 // Structure members are Public by default
1304 if ((current_container is Struct) && (current_modifiers == 0))
1305 current_modifiers = Modifiers.PUBLIC;
1307 member_location = lexer.Location;
1310 END SUB logical_end_of_line
1312 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1313 (Parameters) current_local_parameters, (Attributes) current_attributes,
1314 (ArrayList) $5, member_location);
1316 method.Block = (Block) end_block();
1320 // we have an event handler to take care of
1322 Expression handles_exp = (Expression) $4;
1323 Location loc = lexer.Location;
1325 if (handles_exp is MemberAccess) {
1326 string evt_def = ((MemberAccess)$4).ToString();
1327 int pos = evt_def.LastIndexOf (".");
1328 string evt_target = evt_def.Substring (0, pos);
1331 if (current_container.Properties != null) {
1332 foreach (Property p in current_container.Properties) {
1333 if (p.Name == evt_target) {
1336 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1337 DecomposeQI((string) $2, loc),
1338 DecomposeQI(evt_target, loc), loc);
1340 current_container.AddEventHandler (addhnd);
1348 Report.Error(30506, lexer.Location,
1349 evt_target + " is not declared with WithEvents");
1351 } else if (handles_exp is BaseAccess) {
1352 string evt_id = ((BaseAccess) $4).member;
1353 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1354 DecomposeQI((string) $2, loc),
1355 (Expression) $4, loc);
1357 current_container.AddEventHandler (addhnd);
1365 : FUNCTION identifier opt_type_character
1366 opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1368 current_local_parameters = (Parameters) $4;
1369 member_location = lexer.Location;
1372 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1374 // Structure members are Public by default
1375 if ((current_container is Struct) && (current_modifiers == 0))
1376 current_modifiers = Modifiers.PUBLIC;
1377 // Add local var declaration
1379 ArrayList retval = new ArrayList ();
1380 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1381 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1384 END FUNCTION logical_end_of_line
1386 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1388 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1389 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1390 (ArrayList) $6, member_location);
1391 method.Block = end_block();
1397 : STRUCTURE identifier logical_end_of_line
1398 opt_implement_clause
1401 string full_struct_name = MakeName ((string) $2);
1403 // Module members are static by default, but structures *can't* be declared static
1404 // so we must fix it, if mbas was the one actually responsible for this
1405 // instead of triggering an error.
1406 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1407 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1409 new_struct = new Struct (current_container, full_struct_name,
1410 (int) current_modifiers,
1411 (Attributes) current_attributes, lexer.Location);
1412 current_container = new_struct;
1413 current_container.Namespace = current_namespace;
1414 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1416 opt_struct_member_declarations
1418 Struct new_struct = (Struct) current_container;
1421 new_struct.Bases = (ArrayList) $4;
1423 current_container = current_container.Parent;
1424 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1427 END STRUCTURE logical_end_of_line
1430 opt_struct_member_declarations
1432 | struct_member_declarations
1435 struct_member_declarations
1436 : struct_member_declaration
1437 | struct_member_declarations struct_member_declaration
1440 struct_member_declaration
1442 struct_member_declarator
1445 struct_member_declarator
1447 | constant_declaration
1448 | constructor_declaration
1449 | method_declaration
1451 Method method = (Method) $1;
1452 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1454 | property_declaration
1456 | type_spec_declaration
1459 * This is only included so we can flag error 575:
1460 * destructors only allowed on class types
1462 //| destructor_declaration
1466 : EVENT identifier AS type opt_implement_clause logical_end_of_line
1468 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1470 Event e = new Event ((Expression) $4, var.identifier,
1471 null, current_modifiers, null, null,
1472 current_attributes, (ArrayList) $5,
1475 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1477 | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1479 string delName = null;
1482 delName = (string) $2;
1483 delName = delName + "EventHandler";
1484 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1485 (current_container, TypeManager.system_void_expr,
1486 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1487 (Attributes) current_attributes, lexer.Location);
1489 del.Namespace = current_namespace;
1490 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1492 ArrayList impls = (ArrayList) $4;
1493 if (impls.Count > 1) {
1494 string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1495 "' can not be implemented with Event '" +
1496 (string) $2 + "', since it's delegate type does not match " +
1497 "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1498 Report.Error (31407, lexer.Location, expstr);
1500 Expression impl = (Expression) impls[0];
1501 delName = impl.ToString();
1502 delName = delName.Substring (delName.LastIndexOf(".") + 1);
1503 delName = delName + "EventHandler";
1506 Event e = new Event (DecomposeQI (delName, lexer.Location),
1508 null, current_modifiers, null, null,
1509 current_attributes, (ArrayList) $4,
1512 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1517 : ENUM identifier opt_type_spec logical_end_of_line
1518 opt_enum_member_declarations
1520 Location enum_location = lexer.Location;
1521 string full_name = MakeName ((string) $2);
1522 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1523 ArrayList enum_members = (ArrayList) $5;
1525 if (enum_members.Count == 0)
1526 Report.Error (30280, enum_location,
1527 "Enum can not have empty member list");
1529 // Module members are static by default, but enums *can't* be declared static
1530 // so we must fix it if mbas was the one actually responsible for this
1531 // instead of triggering an error.
1532 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1533 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1535 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1536 (int) current_modifiers, full_name,
1537 (Attributes) current_attributes, enum_location);
1539 foreach (VariableDeclaration ev in enum_members) {
1540 Location loc = (Location) ev.Location;
1542 CheckDef (e.AddEnumMember (ev.identifier,
1543 (Expression) ev.expression_or_array_initializer,
1544 loc, ev.OptAttributes), ev.identifier, loc);
1547 e.Namespace = current_namespace;
1549 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1550 RootContext.Tree.RecordDecl (full_name, e);
1553 END ENUM logical_end_of_line
1556 opt_enum_member_declarations
1557 : /* empty */ { $$ = new ArrayList (); }
1558 | enum_member_declarations { $$ = $1; }
1561 enum_member_declarations
1562 : enum_member_declaration
1564 ArrayList l = new ArrayList ();
1569 | enum_member_declarations enum_member_declaration
1571 ArrayList l = (ArrayList) $1;
1579 enum_member_declaration
1580 : opt_attributes identifier logical_end_of_line
1582 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1584 | opt_attributes identifier
1586 $$ = lexer.Location;
1588 ASSIGN expression logical_end_of_line
1590 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1594 interface_declaration
1595 : INTERFACE identifier logical_end_of_line
1597 Interface new_interface;
1598 string full_interface_name = MakeName ((string) $2);
1600 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1601 (Attributes) current_attributes, lexer.Location);
1602 if (current_interface != null) {
1603 Location l = lexer.Location;
1604 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1606 current_interface = new_interface;
1607 new_interface.Namespace = current_namespace;
1608 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1613 Interface new_interface = (Interface) current_interface;
1616 new_interface.Bases = (ArrayList) $5;
1618 current_interface = null;
1619 CheckDef (current_container.AddInterface (new_interface),
1620 new_interface.Name, new_interface.Location);
1623 END INTERFACE logical_end_of_line
1627 : /* empty */ { $$ = null; }
1633 | interface_bases interface_base
1635 ArrayList bases = (ArrayList) $1;
1636 bases.AddRange ((ArrayList) $2);
1642 : INHERITS type_list logical_end_of_line { $$ = $2; }
1646 : opt_interface_member_declarations
1649 opt_interface_member_declarations
1651 | interface_member_declarations
1654 interface_member_declarations
1655 : interface_member_declaration
1656 | interface_member_declarations interface_member_declaration
1659 interface_member_declaration
1663 current_attributes = (Attributes) $1;
1664 current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
1666 interface_member_declarator
1672 interface_member_declarator
1673 : interface_method_declaration
1675 Method m = (Method) $1;
1676 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1678 | interface_property_declaration
1679 | interface_event_declaration
1682 interface_method_declaration
1683 : SUB identifier opt_params logical_end_of_line
1685 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1686 (Parameters) $3, current_attributes, null, lexer.Location);
1690 | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
1692 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.
1693 system_object_expr : (Expression) $3 ) : (Expression) $5;
1695 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1696 (string) $2,(Parameters) $4, current_attributes, null,
1703 interface_property_declaration
1704 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1706 Expression ftype = ($5 == null) ? (($3 == null) ?
1707 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1709 current_local_parameters = (Parameters) $4;
1710 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1711 get_parameters = current_local_parameters.Copy (lexer.Location);
1712 set_parameters = current_local_parameters.Copy (lexer.Location);
1714 Parameter implicit_value_parameter = new Parameter (
1715 ftype, "Value", Parameter.Modifier.NONE, null);
1717 set_parameters.AppendParameter (implicit_value_parameter);
1721 get_parameters = Parameters.EmptyReadOnlyParameters;
1722 set_parameters = new Parameters (null, null ,lexer.Location);
1724 Parameter implicit_value_parameter = new Parameter (
1725 ftype, "Value", Parameter.Modifier.NONE, null);
1727 set_parameters.AppendParameter (implicit_value_parameter);
1729 lexer.PropertyParsing = true;
1731 Accessor get_block = new Accessor (null, null);
1732 Accessor set_block = new Accessor (null, null);
1734 Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
1735 get_block, set_block, current_attributes, lexer.Location,
1736 null, get_parameters, set_parameters, null);
1738 CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
1740 get_implicit_value_parameter_type = null;
1741 set_implicit_value_parameter_type = null;
1742 get_parameters = null;
1743 set_parameters = null;
1744 current_local_parameters = null;
1748 interface_event_declaration
1749 : EVENT identifier AS type logical_end_of_line
1751 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1753 Event e = new Event ((Expression) $4, var.identifier,
1754 null, current_modifiers, null, null,
1755 current_attributes, lexer.Location);
1757 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1760 | EVENT identifier opt_params logical_end_of_line
1762 string delName = (string) $2;
1763 delName = delName + "EventHandler";
1764 int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
1765 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1766 (current_container, TypeManager.system_void_expr,
1767 (int) delModifiers, MakeName(delName), (Parameters) $3,
1768 (Attributes) current_attributes, lexer.Location);
1770 del.Namespace = current_namespace;
1771 CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
1773 Event e = new Event (DecomposeQI (delName, lexer.Location),
1775 null, current_modifiers, null, null,
1776 current_attributes, lexer.Location);
1778 CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1782 property_declaration
1783 : abstract_propery_declaration
1784 | non_abstract_propery_declaration
1787 abstract_propery_declaration
1788 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1790 Expression ftype = ($6 == null) ? (($4 == null) ?
1791 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
1793 if (current_container is Module)
1794 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1796 if (current_container is Struct)
1797 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1799 current_modifiers |= Modifiers.ABSTRACT;
1801 current_local_parameters = (Parameters) $5;
1802 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1803 get_parameters = current_local_parameters.Copy (lexer.Location);
1804 set_parameters = current_local_parameters.Copy (lexer.Location);
1806 Parameter implicit_value_parameter = new Parameter (
1807 ftype, "Value", Parameter.Modifier.NONE, null);
1809 set_parameters.AppendParameter (implicit_value_parameter);
1813 get_parameters = Parameters.EmptyReadOnlyParameters;
1814 set_parameters = new Parameters (null, null ,lexer.Location);
1816 Parameter implicit_value_parameter = new Parameter (
1817 ftype, "Value", Parameter.Modifier.NONE, null);
1819 set_parameters.AppendParameter (implicit_value_parameter);
1821 lexer.PropertyParsing = true;
1823 Accessor get_block = new Accessor (null, null);
1824 Accessor set_block = new Accessor (null, null);
1826 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1827 get_block, set_block, current_attributes, lexer.Location,
1828 null, get_parameters, set_parameters, null);
1830 if (!(current_container is Class))
1831 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1833 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1835 get_implicit_value_parameter_type = null;
1836 set_implicit_value_parameter_type = null;
1837 get_parameters = null;
1838 set_parameters = null;
1839 current_local_parameters = null;
1844 non_abstract_propery_declaration
1845 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
1847 get_implicit_value_parameter_type =
1848 ($5 == null) ? (($3 == null) ?
1849 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1850 get_implicit_value_parameter_name = (string) $2;
1852 current_local_parameters = (Parameters) $4;
1853 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1854 get_parameters = current_local_parameters.Copy (lexer.Location);
1855 set_parameters = current_local_parameters.Copy (lexer.Location);
1859 get_parameters = Parameters.EmptyReadOnlyParameters;
1860 set_parameters = new Parameters (null, null ,lexer.Location);
1862 lexer.PropertyParsing = true;
1864 $$ = lexer.Location;
1866 accessor_declarations
1867 END PROPERTY logical_end_of_line
1869 lexer.PropertyParsing = false;
1872 Pair pair = (Pair) $9;
1874 Accessor get_block = null;
1875 Accessor set_block = null;
1877 if (pair.First != null){
1878 get_block = (Accessor) pair.First;
1881 if (pair.Second != null) {
1882 set_block = (Accessor) pair.Second;
1885 Location loc = lexer.Location;
1887 // Structure members are Public by default
1888 if ((current_container is Struct) && (current_modifiers == 0))
1889 current_modifiers = Modifiers.PUBLIC;
1891 prop = new Property ((Expression) get_implicit_value_parameter_type,
1892 (string) $2, current_modifiers, get_block, set_block,
1893 current_attributes, loc, set_implicit_value_parameter_name,
1894 get_parameters, set_parameters, (ArrayList) $6);
1896 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1897 get_implicit_value_parameter_type = null;
1898 set_implicit_value_parameter_type = null;
1899 get_parameters = null;
1900 set_parameters = null;
1901 current_local_parameters = null;
1905 opt_property_parameters
1908 $$ = Parameters.EmptyReadOnlyParameters;
1910 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1916 opt_implement_clause
1921 | IMPLEMENTS implement_clause_list
1927 implement_clause_list
1928 : qualified_identifier
1930 ArrayList impl_list = new ArrayList ();
1931 impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
1934 | implement_clause_list COMMA qualified_identifier
1936 ArrayList impl_list = (ArrayList) $1;
1937 impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
1943 accessor_declarations
1944 : get_accessor_declaration opt_set_accessor_declaration
1946 $$ = new Pair ($1, $2);
1948 | set_accessor_declaration opt_get_accessor_declaration
1950 $$ = new Pair ($2, $1);
1954 opt_get_accessor_declaration
1955 : /* empty */ { $$ = null; }
1956 | get_accessor_declaration
1959 opt_set_accessor_declaration
1960 : /* empty */ { $$ = null; }
1961 | set_accessor_declaration
1964 get_accessor_declaration
1965 : opt_attributes GET logical_end_of_line
1967 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
1968 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
1970 current_local_parameters = get_parameters;
1972 lexer.PropertyParsing = false;
1975 // Add local var declaration
1977 ArrayList retval = new ArrayList ();
1978 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1979 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1982 END GET logical_end_of_line
1984 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1985 current_local_parameters = null;
1986 lexer.PropertyParsing = true;
1990 set_accessor_declaration
1991 : opt_attributes SET opt_set_parameter logical_end_of_line
1993 if ((current_modifiers & Modifiers.READONLY) != 0)
1994 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
1996 Parameter implicit_value_parameter = new Parameter (
1997 set_implicit_value_parameter_type,
1998 set_implicit_value_parameter_name,
1999 Parameter.Modifier.NONE, null);
2001 current_local_parameters = set_parameters;
2002 current_local_parameters.AppendParameter (implicit_value_parameter);
2005 lexer.PropertyParsing = false;
2008 END SET logical_end_of_line
2010 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
2011 current_local_parameters = null;
2012 lexer.PropertyParsing = true;
2019 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2020 set_implicit_value_parameter_name = "Value";
2022 |OPEN_PARENS CLOSE_PARENS
2024 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2025 set_implicit_value_parameter_name = "Value";
2027 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2029 Parameter.Modifier pm = (Parameter.Modifier)$2;
2030 if ((pm | Parameter.Modifier.VAL) != 0)
2031 Report.Error (31065,
2033 "Set cannot have a paremeter modifier other than 'ByVal'");
2035 set_implicit_value_parameter_type = (Expression) $4;
2037 if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
2038 Report.Error (31064,
2040 "Set value parameter type can not be different from property type");
2043 set_implicit_value_parameter_name = (string) $3;
2045 set_implicit_value_parameter_name = "Value";
2051 variable_declarators logical_end_of_line
2053 int mod = (int) current_modifiers;
2055 VariableDeclaration.FixupTypes ((ArrayList) $2);
2056 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2058 if (current_container is Module)
2059 mod = mod | Modifiers.STATIC;
2061 // Structure members are Public by default
2062 if ((current_container is Struct) && (mod == 0))
2063 mod = Modifiers.PUBLIC;
2065 if ((mod & Modifiers.Accessibility) == 0)
2066 mod |= Modifiers.PRIVATE;
2068 foreach (VariableDeclaration var in (ArrayList) $2){
2069 Location l = var.Location;
2070 Field field = new Field (var.type, mod, var.identifier,
2071 var.expression_or_array_initializer,
2072 (Attributes) null, l);
2074 CheckDef (current_container.AddField (field), field.Name, l);
2079 withevents_declaration
2080 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2082 // Module members are static by default, but delegates *can't* be declared static
2083 // so we must fix it, if mbas was the one actually responsible for this
2084 // instead of triggering an error.
2085 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2086 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2088 /* WithEvents Fields must be resolved into properties
2089 with a bit of magic behind the scenes */
2091 VariableDeclaration.FixupTypes ((ArrayList) $3);
2093 foreach (VariableDeclaration var in (ArrayList) $3) {
2094 // 1 - We create a private field
2095 Location l = var.Location;
2097 if ((current_modifiers & Modifiers.STATIC) > 0)
2098 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2100 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2101 var.expression_or_array_initializer,
2102 (Attributes) null, l);
2104 CheckDef (current_container.AddField (field), field.Name, l);
2106 // 2 - Public property
2108 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2109 field, (int) current_modifiers,
2110 (Attributes) current_attributes, l);
2112 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2122 delegate_declaration
2124 identifier OPEN_PARENS
2125 opt_formal_parameter_list
2129 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 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2137 TypeManager.system_void_expr,
2138 (int) current_modifiers,
2139 MakeName ((string) $3), (Parameters) $5,
2140 (Attributes) current_attributes, l);
2142 del.Namespace = current_namespace;
2143 CheckDef (current_container.AddDelegate (del), del.Name, l);
2146 identifier OPEN_PARENS
2147 opt_formal_parameter_list
2148 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2150 Location l = lexer.Location;
2152 // Module members are static by default, but delegates *can't* be declared static
2153 // so we must fix it, if mbas was the one actually responsible for this
2154 // instead of triggering an error.
2155 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2156 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2158 Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2160 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2162 ftype, (int) current_modifiers, MakeName ((string) $3),
2163 (Parameters) $5, (Attributes) current_attributes, l);
2165 del.Namespace = current_namespace;
2166 CheckDef (current_container.AddDelegate (del), del.Name, l);
2173 | HANDLES qualified_identifier
2175 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
2182 /*| HANDLES MYBASE DOT qualified_identifier
2184 // FIXME: this is blatantly wrong and crash-prone
2185 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2189 constructor_declaration
2190 : SUB NEW opt_params logical_end_of_line
2192 current_local_parameters = (Parameters) $3;
2194 oob_stack.Push (lexer.Location);
2196 Location l = (Location) oob_stack.Pop ();
2197 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2202 Constructor c = (Constructor) $1;
2203 c.Block = (Block) end_block();
2204 c.ModFlags = (int) current_modifiers;
2205 c.OptAttributes = current_attributes;
2207 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2209 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2210 current_local_parameters = null;
2212 END SUB logical_end_of_line
2215 opt_formal_parameter_list
2218 $$ = Parameters.EmptyReadOnlyParameters;
2220 | formal_parameter_list
2223 //Parameter p = ((Parameters) $1).FixedParameters[0];
2227 formal_parameter_list
2230 ArrayList pars_list = (ArrayList) $1;
2231 Parameter [] pars = null;
2232 Parameter array_parameter = null;
2233 int non_array_count = pars_list.Count;
2234 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2235 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2236 non_array_count = pars_list.Count - 1;
2238 foreach (Parameter par in pars_list)
2239 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2240 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2241 non_array_count = 0;
2242 array_parameter = null;
2245 if (non_array_count > 0) {
2246 pars = new Parameter [non_array_count];
2247 pars_list.CopyTo (0, pars, 0, non_array_count);
2249 $$ = new Parameters (pars, array_parameter, lexer.Location);
2256 ArrayList pars = new ArrayList ();
2261 | parameters COMMA parameter
2263 ArrayList pars = (ArrayList) $1;
2272 opt_parameter_modifier
2273 identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2275 Parameter.Modifier pm = (Parameter.Modifier)$2;
2276 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2279 if (opt_parm && ($7 == null))
2280 Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
2282 if (!opt_parm && ($7 != null))
2283 Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
2285 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2286 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2287 Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
2290 if ((pm & Parameter.Modifier.REF) !=0)
2291 pm |= Parameter.Modifier.ISBYREF;
2293 if ($4 != null && $6 != null && $4 != $6)
2294 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2296 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2298 string t = ptype.ToString ();
2299 if (t.IndexOf('[') >= 0)
2300 Report.Error (31087, lexer.Location, "Array types specified in too many places");
2302 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
2304 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2305 Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
2306 $$ = new Parameter (ptype, (string) $3, pm,
2307 (Attributes) $1, (Expression) $7, opt_parm);
2311 opt_parameter_modifier
2312 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2313 | parameter_modifiers { $$ = $1; }
2317 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2318 | parameter_modifier { $$ = $1; }
2322 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2323 | BYVAL { $$ = Parameter.Modifier.VAL; }
2324 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2325 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2330 | statement_list end_of_stmt
2335 | statement_list end_of_stmt statement
2339 declaration_statement
2341 if ($1 != null && (Block) $1 != current_block){
2342 current_block.AddStatement ((Statement) $1);
2343 current_block = (Block) $1;
2346 | embedded_statement
2348 Statement s = (Statement) $1;
2350 current_block.AddStatement ((Statement) $1);
2353 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2355 AddHandler ((Expression) $2, (string) $5);
2357 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2359 RemoveHandler ((Expression) $2, (string) $5);
2361 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2363 RaiseEvent ((string) $2, (ArrayList) $3);
2365 /* | array_handling_statement */
2366 /* | empty_statement */
2369 Statement s = (Statement) $1;
2371 current_block.AddStatement ((Statement) $1);
2375 opt_raise_event_args
2376 : /* empty */ { $$ = null; }
2377 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2394 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2396 if (!current_block.AddLabel ((string) $1, labeled)){
2397 Location l = lexer.Location;
2398 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2400 current_block.AddStatement (labeled);
2404 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2406 if (!current_block.AddLabel ((string) $1, labeled)){
2407 Location l = lexer.Location;
2408 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2410 current_block.AddStatement (labeled);
2416 : expression_statement
2417 | selection_statement
2418 | iteration_statement
2420 | synclock_statement
2422 | array_handling_statement
2428 $$ = new EmptyStatement ();
2434 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2436 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2437 Expression e = (Expression) $2;
2444 Block b = end_block();
2451 array_handling_statement
2457 : REDIM opt_preserve redim_clauses
2459 ArrayList list = (ArrayList) $3;
2460 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2467 : /* empty */ { $$ = false; }
2468 | PRESERVE { $$ = true; }
2474 ArrayList clauses = new ArrayList ();
2479 | redim_clauses COMMA redim_clause
2481 ArrayList clauses = (ArrayList) ($1);
2489 : invocation_expression
2491 Invocation i = (Invocation) $1;
2492 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2498 : ERASE erase_clauses
2500 ArrayList list = (ArrayList) $2;
2501 foreach(Expression e in list)
2503 Erase r = new Erase (e, lexer.Location);
2512 ArrayList clauses = new ArrayList ();
2517 | erase_clauses COMMA erase_clause
2519 ArrayList clauses = (ArrayList) ($1);
2527 : primary_expression
2532 | continue_statement
2533 | */return_statement
2543 $$ = new Goto (current_block, (string) $2, lexer.Location);
2548 : THROW opt_expression
2550 $$ = new Throw ((Expression) $2, lexer.Location);
2557 $$ = new Exit ((ExitType)$2, lexer.Location);
2562 : DO { $$ = ExitType.DO; }
2563 | FOR { $$ = ExitType.FOR; }
2564 | WHILE { $$ = ExitType.WHILE; }
2565 | SELECT { $$ = ExitType.SELECT; }
2566 | SUB { $$ = ExitType.SUB; }
2567 | FUNCTION { $$ = ExitType.FUNCTION; }
2568 | PROPERTY { $$ = ExitType.PROPERTY; }
2569 | TRY { $$ = ExitType.TRY; }
2572 : RETURN opt_expression
2574 $$ = new Return ((Expression) $2, lexer.Location);
2586 : FOR EACH identifier IN
2588 oob_stack.Push (lexer.Location);
2590 expression end_of_stmt
2594 Block foreach_block = current_block;
2595 Location l = lexer.Location;
2596 LocalVariableReference v = null;
2599 vi = foreach_block.GetVariableInfo ((string) $3);
2601 // Get a reference to this variable.
2602 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2605 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2612 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2613 Block foreach_block = end_block();
2614 Location l = (Location) oob_stack.Pop ();
2618 f = new Foreach (null, v, (Expression) $6, foreach_block, l);
2628 if (!UseExtendedSyntax)
2634 if (iterator_container == null){
2635 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2638 iterator_container.SetYields ();
2639 $$ = new Yield ((Expression) $2, lexer.Location);
2644 if (!UseExtendedSyntax)
2650 if (iterator_container == null){
2651 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2654 iterator_container.SetYields ();
2655 $$ = new YieldBreak (lexer.Location);
2661 : SYNCLOCK expression end_of_stmt
2668 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2685 tmp_catch_clauses = (ArrayList) $5;
2694 ArrayList s = new ArrayList ();
2696 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2703 // Now s contains the list of specific catch clauses
2704 // and g contains the general one.
2705 Block b = end_block();
2707 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2714 tmp_block = end_block();
2724 ArrayList s = new ArrayList ();
2725 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2727 if (catch_list != null){
2728 foreach (Catch cc in catch_list) {
2736 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2742 : /* empty */ { $$ = null; }
2749 ArrayList l = new ArrayList ();
2754 | catch_clauses catch_clause
2756 ArrayList l = (ArrayList) $1;
2764 : /* empty */ { $$ = null; }
2769 : CATCH opt_catch_args end_of_stmt
2771 Expression type = null;
2775 DictionaryEntry cc = (DictionaryEntry) $2;
2776 type = (Expression) cc.Key;
2777 id = (string) cc.Value;
2780 ArrayList one = new ArrayList ();
2781 Location loc = lexer.Location;
2783 one.Add (new VariableDeclaration (id, type, loc));
2787 current_block = new Block (current_block);
2788 Block b = declare_local_variables (type, one, loc);
2794 opt_statement_list {
2795 Expression type = null;
2797 Block b_catch = current_block;
2800 DictionaryEntry cc = (DictionaryEntry) $2;
2801 type = (Expression) cc.Key;
2802 id = (string) cc.Value;
2806 // FIXME: I can change this for an assignment.
2808 while (current_block != (Block) $1)
2809 current_block = current_block.Parent;
2813 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2818 : /* empty */ { $$ = null; }
2823 : identifier AS type
2825 $$ = new DictionaryEntry ($3, $1);
2831 : DO opt_do_construct end_of_stmt
2834 oob_stack.Push (lexer.Location);
2837 LOOP opt_do_construct
2839 Expression t_before = (Expression) $2;
2840 Expression t_after = (Expression) $7;
2843 if ((t_before != null) && (t_after != null))
2844 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2846 if ((t_before == null) && (t_after == null))
2847 t = new BoolLiteral (true);
2849 t = (t_before != null) ? t_before : t_after;
2851 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2853 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2854 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2855 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2857 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2862 : /* empty */ { $$ = null; }
2863 | while_or_until boolean_expression
2865 do_type = (DoOptions)$1;
2866 $$ = (Expression) $2;
2871 : WHILE { $$ = DoOptions.WHILE; }
2872 | UNTIL { $$ = DoOptions.UNTIL; }
2879 oob_stack.Push (lexer.Location);
2881 boolean_expression end_of_stmt
2885 Location l = (Location) oob_stack.Pop ();
2886 Block b = end_block();
2887 Expression e = (Expression) $3;
2888 $$ = new While ((Expression) e, (Statement) b, l);
2894 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2901 Block statement = end_block();
2902 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2904 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2905 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2906 for_var, (Expression) $6, lexer.Location);
2907 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2908 for_var, (Expression) $7, lexer.Location), lexer.Location);
2910 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2911 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2913 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2918 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2919 | STEP expression { $$ = $2; }
2928 : if_statement_open opt_then if_statement_rest
2932 | if_statement_open THEN pre_embedded_statement
2934 Location l = (Location) oob_stack.Pop ();
2935 tmp_expr = (Expression)expr_stack.Pop();
2936 $$ = new If ((Expression) tmp_expr, end_block(), l);
2940 pre_embedded_statement
2941 : embedded_statement
2943 Statement s = (Statement) $1;
2945 current_block.AddStatement ((Statement) $1);
2950 : IF boolean_expression
2952 oob_stack.Push (lexer.Location);
2954 tmp_expr = (Expression) $2;
2955 expr_stack.Push(tmp_expr);
2969 Location l = (Location) oob_stack.Pop ();
2970 Expression expr = (Expression)expr_stack.Pop();
2971 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2977 Block bl = end_block();
2978 tmp_blocks.Push(bl);
2984 Location l = (Location) oob_stack.Pop ();
2985 tmp_expr = (Expression)expr_stack.Pop();
2986 tmp_block = (Block) tmp_blocks.Pop();
2987 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2991 ELSEIF boolean_expression opt_then
2993 tmp_expr = (Expression) $4;
2994 expr_stack.Push(tmp_expr);
2995 tmp_block = end_block();
2996 tmp_blocks.Push(tmp_block);
2999 else_if_statement_rest
3001 Statement stmt = (Statement) statement_stack.Pop();
3002 Block bl = (Block) tmp_blocks.Pop();
3003 Expression expr = (Expression)expr_stack.Pop();
3004 Location l = (Location) oob_stack.Pop ();
3005 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3010 else_if_statement_rest
3015 Location l = (Location) oob_stack.Pop ();
3017 Expression expr = (Expression)expr_stack.Pop();
3018 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3019 statement_stack.Push(stmt);
3025 Block bl = end_block();
3026 tmp_blocks.Push(bl);
3032 Location l = (Location) oob_stack.Pop ();
3034 Expression expr = (Expression)expr_stack.Pop();
3035 Block bl = (Block)tmp_blocks.Pop();
3036 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3037 statement_stack.Push(stmt);
3041 ELSEIF boolean_expression opt_then
3043 expr_stack.Push((Expression) $4);
3044 Block bl = end_block();
3045 tmp_blocks.Push(bl);
3048 else_if_statement_rest
3050 Location l = (Location) oob_stack.Pop ();
3052 Statement tmp_stmt = (Statement)statement_stack.Pop();
3053 Block bl = (Block) tmp_blocks.Pop();
3054 Expression expr = (Expression)expr_stack.Pop();
3055 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3056 statement_stack.Push(stmt);
3061 : SELECT opt_case expression end_of_stmt
3063 oob_stack.Push (lexer.Location);
3064 switch_stack.Push (current_block);
3069 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3070 current_block = (Block) switch_stack.Pop ();
3075 : /* empty */ { $$ = null; }
3076 | case_sections { $$ = $1; }
3080 : case_sections case_section
3082 ArrayList sections = (ArrayList) $1;
3089 ArrayList sections = new ArrayList ();
3103 : CASE case_clauses ends
3109 //Block topmost = current_block;
3110 Block topmost = end_block();
3112 while (topmost.Implicit)
3113 topmost = topmost.Parent;
3115 // FIXME: This is a horrible hack which MUST go
3116 topmost.statements.Add (new Break (lexer.Location));
3117 $$ = new SwitchSection ((ArrayList) $2, topmost);
3120 /* FIXME: we should somehow flag an error
3121 (BC30321 'Case' cannot follow a 'Case Else'
3122 in the same 'Select' statement.)
3123 if Case Else is not the last of the Case clauses
3130 //Block topmost = current_block;
3131 Block topmost = end_block();
3133 while (topmost.Implicit)
3134 topmost = topmost.Parent;
3136 // FIXME: This is a horrible hack which MUST go
3137 topmost.statements.Add (new Break (lexer.Location));
3139 ArrayList a = new ArrayList();
3140 a.Add (new SwitchLabel (null, lexer.Location));
3141 $$ = new SwitchSection ((ArrayList) a, topmost);
3148 ArrayList labels = new ArrayList ();
3153 | case_clauses COMMA case_clause
3155 ArrayList labels = (ArrayList) ($1);
3163 : opt_is comparison_operator expression
3166 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3188 expression_statement
3189 : statement_expression
3196 statement_expression
3197 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3198 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3199 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3202 object_creation_expression
3203 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3205 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3209 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3213 array_creation_expression
3214 : object_creation_expression opt_rank_specifiers array_initializer
3217 ArrayList dims = new ArrayList();
3219 if (n.Arguments != null) {
3220 foreach (Argument a in n.Arguments) {
3225 Expression atype = n.RequestedType;
3228 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
3230 ArrayList init = (ArrayList) $3;
3231 if (init.Count == 0)
3234 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3235 VariableDeclaration.VBFixIndexList (ref dims);
3236 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3240 string rank = VariableDeclaration.BuildRank (dims);
3241 $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location);
3243 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3248 : object_creation_expression
3249 | array_creation_expression
3252 declaration_statement
3253 : local_variable_declaration
3256 DictionaryEntry de = (DictionaryEntry) $1;
3258 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3261 | local_constant_declaration
3264 DictionaryEntry de = (DictionaryEntry) $1;
3266 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3271 local_variable_declaration
3272 : DIM variable_declarators
3274 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3279 local_constant_declaration
3280 : CONST constant_declarators
3283 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3289 constant_declarators
3290 : constant_declarator
3292 ArrayList decl = new ArrayList ();
3298 | constant_declarators COMMA constant_declarator
3300 ArrayList decls = (ArrayList) $1;
3309 : variable_name opt_type_decl opt_variable_initializer
3311 VarName vname = (VarName) $1;
3312 string varname = (string) vname.Name;
3313 current_rank_specifiers = (ArrayList) vname.Rank;
3314 object varinit = $3;
3315 ArrayList a_dims = null;
3317 if (varinit == null)
3319 30438, lexer.Location, "Constant should have a value"
3322 if (vname.Type != null && $2 != null)
3324 30302, lexer.Location,
3325 "Type character cannot be used with explicit type declaration" );
3327 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3329 if (current_rank_specifiers != null)
3331 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3335 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3339 variable_declarators
3340 : variable_declarator
3342 ArrayList decl = new ArrayList ();
3343 decl.AddRange ((ArrayList) $1);
3346 | variable_declarators COMMA variable_declarator
3348 ArrayList decls = (ArrayList) $1;
3349 decls.AddRange ((ArrayList) $3);
3355 : variable_names opt_type_decl opt_variable_initializer
3357 ArrayList names = (ArrayList) $1;
3358 object varinit = $3;
3359 ArrayList VarDeclarations = new ArrayList();
3361 ArrayList a_dims = null;
3363 if ((names.Count > 1) && (varinit != null))
3365 30671, lexer.Location,
3366 "Multiple variables with single type can not have " +
3367 "a explicit initialization" );
3370 foreach (VarName vname in names)
3372 string varname = (string) vname.Name;
3373 current_rank_specifiers = (ArrayList) vname.Rank;
3377 if(vname.Type != null && $2 != null)
3379 30302, lexer.Location,
3380 "Type character cannot be used with explicit type declaration" );
3382 // Some checking is required for particularly weird declarations
3383 // like Dim a As Integer(,)
3385 vartype = (Expression) ((Pair) $2).First;
3387 /*if ($3 != null && $3 is ArrayList)
3388 Report.Error (205, "End of statement expected.");*/
3390 ArrayList args = (ArrayList) ((Pair) $2).Second;
3391 if (current_rank_specifiers != null)
3392 Report.Error (31087, lexer.Location,
3393 "Array types specified in too many places");
3395 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3396 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3398 current_rank_specifiers = new ArrayList ();
3399 current_rank_specifiers.Add (args);
3402 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3404 // if the variable is an array with explicit bound
3405 // and having explicit initialization throw exception
3406 if (current_rank_specifiers != null && varinit != null)
3408 bool broken = false;
3409 foreach (ArrayList exprs in current_rank_specifiers)
3411 foreach (Expression expr in exprs)
3413 if (!((Expression)expr is EmptyExpression ))
3416 30672, lexer.Location,
3417 "Array declared with explicit bound " +
3418 " can not have explicit initialization");
3429 Check for a declaration like Dim a(2) or Dim a(2,3)
3430 If this is the case, we must generate an ArrayCreationExpression
3431 and, in case, add the initializer after the array has been created.
3433 if (VariableDeclaration.IsArrayDecl (this)) {
3434 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3435 a_dims = (ArrayList) current_rank_specifiers;
3436 VariableDeclaration.VBFixIndexLists (ref a_dims);
3437 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3439 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
3442 if (vartype is New) {
3443 if (varinit != null) {
3444 Report.Error (30205, lexer.Location, "End of statement expected");
3450 vartype = ((New)vartype).RequestedType;
3453 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3455 $$ = VarDeclarations;
3462 ArrayList list = new ArrayList ();
3466 | variable_names COMMA variable_name
3468 ArrayList list = (ArrayList) $1;
3475 : identifier opt_type_character opt_array_name_modifier
3477 $$ = new VarName ($1, $2, $3);
3488 $$ = (Expression) $2;
3494 | AS type rank_specifiers
3496 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
3501 : opt_type_with_ranks
3507 New n = new New ((Expression)$3, null, lexer.Location);
3508 $$ = (Expression) n;
3510 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3512 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3513 $$ = (Expression) n;
3515 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3517 ArrayList args = new ArrayList();
3518 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3521 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3522 $$ = (Expression) n;
3526 opt_array_name_modifier
3527 : /* empty */ { $$ = null; }
3528 | array_type_modifier { $$ = $1; }
3532 : rank_specifiers { $$ = $1; }
3535 opt_variable_initializer
3536 : /* empty */ { $$ = null; }
3537 | ASSIGN variable_initializer { $$ = $2; }
3540 variable_initializer
3553 : OPEN_BRACE CLOSE_BRACE
3555 ArrayList list = new ArrayList ();
3558 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3560 $$ = (ArrayList) $2;
3564 variable_initializer_list
3565 : variable_initializer
3567 ArrayList list = new ArrayList ();
3571 | variable_initializer_list COMMA variable_initializer
3573 ArrayList list = (ArrayList) $1;
3594 ArrayList rs = new ArrayList();
3598 | rank_specifiers rank_specifier
3600 ArrayList rs = (ArrayList) $1;
3607 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
3616 ArrayList ds = new ArrayList();
3617 ds.Add (new EmptyExpression());
3622 ArrayList ds = new ArrayList();
3623 ds.Add ((Expression) $1);
3626 | opt_dim_specifiers COMMA expression
3628 ArrayList ds = (ArrayList) $1;
3629 ds.Add ((Expression) $3);
3632 | opt_dim_specifiers COMMA
3634 ArrayList ds = (ArrayList) $1;
3635 ds.Add (new EmptyExpression());
3645 | parenthesized_expression
3648 | qualified_identifier
3650 string name = (string) $1;
3651 $$ = DecomposeQI (name, lexer.Location);
3653 //FIXME: address_of_expression is apparently missing here
3654 | get_type_expression
3656 | invocation_expression
3666 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3667 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3668 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3669 | NOTHING { $$ = NullLiteral.Null; }
3673 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3674 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3675 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3680 object v = lexer.Value;
3683 $$ = new IntLiteral ((Int32)v);
3684 else if (v is short)
3685 $$ = new ShortLiteral ((Int16)v);
3687 $$ = new LongLiteral ((Int64)v);
3689 Console.WriteLine ("OOPS. Unexpected result from scanner");
3695 : TRUE { $$ = new BoolLiteral (true); }
3696 | FALSE { $$ = new BoolLiteral (false); }
3699 parenthesized_expression
3700 : OPEN_PARENS expression CLOSE_PARENS
3705 : primary_expression DOT identifier
3708 string id_name = (string)$3;
3709 if (id_name.ToUpper() == "NEW")
3711 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3715 if (with_stack.Count > 0) {
3716 Expression e = (Expression) with_stack.Peek();
3717 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3725 /* | primary_expression DOT NEW
3727 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3729 | predefined_type DOT identifier
3732 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3735 if (with_stack.Count > 0) {
3736 Expression e = (Expression) with_stack.Peek();
3737 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3751 invocation_expression
3752 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3755 Location l = lexer.Location;
3756 Report.Error (1, l, "THIS IS CRAZY");
3758 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3759 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3764 : MYBASE DOT IDENTIFIER
3766 string id_name = (string) $3;
3767 if (id_name.ToUpper() == "NEW")
3769 $$ = new BaseAccess (id_name, lexer.Location);
3773 $$ = new BaseAccess ("New", lexer.Location);
3781 The 'argument' rule returns an 'empty' argument
3782 of type NoArg (used for default arguments in invocations)
3783 if no arguments are actually passed.
3785 If there is only one argument and it is o type NoArg,
3786 we return a null (empty) list
3788 ArrayList args = (ArrayList) $1;
3789 if (args.Count == 1 &&
3790 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3800 ArrayList list = new ArrayList ();
3804 | argument_list COMMA argument
3806 ArrayList list = (ArrayList) $1;
3815 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3817 | BYREF variable_reference
3819 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3823 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3825 | ADDRESSOF expression
3827 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
3832 : expression {/* note ("section 5.4"); */ $$ = $1; }
3837 : conditional_xor_expression { $$ = $1; }
3838 /*| assignment_expression*/
3849 $$ = new This (current_block, lexer.Location);
3853 // FIXME: This is actually somewhat different from Me
3854 // because it is for accessing static (classifier) methods/properties/fields
3855 $$ = new This (current_block, lexer.Location);
3860 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
3864 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3866 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3868 | cast_operator OPEN_PARENS expression CLOSE_PARENS
3870 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3875 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3876 | CBYTE { $$ = TypeManager.system_byte_expr; }
3877 | CCHAR { $$ = TypeManager.system_char_expr; }
3878 | CDATE { $$ = TypeManager.system_date_expr; }
3879 | CDBL { $$ = TypeManager.system_double_expr; }
3880 | CDEC { $$ = TypeManager.system_decimal_expr; }
3881 | CINT { $$ = TypeManager.system_int32_expr; }
3882 | CLNG { $$ = TypeManager.system_int64_expr; }
3883 | COBJ { $$ = TypeManager.system_object_expr; }
3884 | CSHORT { $$ = TypeManager.system_int16_expr; }
3885 | CSNG { $$ = TypeManager.system_single_expr; }
3886 | CSTR { $$ = TypeManager.system_string_expr; }
3890 : GETTYPE OPEN_PARENS type CLOSE_PARENS
3892 $$ = new TypeOf ((Expression) $3, lexer.Location);
3896 exponentiation_expression
3897 : primary_expression
3898 | exponentiation_expression OP_EXP primary_expression
3904 prefixed_unary_expression
3905 : exponentiation_expression
3906 | PLUS prefixed_unary_expression
3908 //FIXME: Is this rule correctly defined ?
3909 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3911 | MINUS prefixed_unary_expression
3913 //FIXME: Is this rule correctly defined ?
3914 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3918 multiplicative_expression
3919 : prefixed_unary_expression
3920 | multiplicative_expression STAR prefixed_unary_expression
3922 $$ = new Binary (Binary.Operator.Multiply,
3923 (Expression) $1, (Expression) $3, lexer.Location);
3925 | multiplicative_expression DIV prefixed_unary_expression
3927 $$ = new Binary (Binary.Operator.Division,
3928 (Expression) $1, (Expression) $3, lexer.Location);
3932 integer_division_expression
3933 : multiplicative_expression
3934 | integer_division_expression OP_IDIV multiplicative_expression
3936 //FIXME: Is this right ?
3937 $$ = new Binary (Binary.Operator.Division,
3938 (Expression) $1, (Expression) $3, lexer.Location);
3943 : integer_division_expression
3944 | mod_expression MOD integer_division_expression
3946 $$ = new Binary (Binary.Operator.Modulus,
3947 (Expression) $1, (Expression) $3, lexer.Location);
3953 | additive_expression PLUS mod_expression
3955 $$ = new Binary (Binary.Operator.Addition,
3956 (Expression) $1, (Expression) $3, lexer.Location);
3958 | additive_expression MINUS mod_expression
3960 $$ = new Binary (Binary.Operator.Subtraction,
3961 (Expression) $1, (Expression) $3, lexer.Location);
3966 : additive_expression
3967 | concat_expression OP_CONCAT additive_expression
3969 // FIXME: This should only work for String expressions
3970 // We probably need to use something from the runtime
3971 $$ = new Binary (Binary.Operator.Addition,
3972 (Expression) $1, (Expression) $3, lexer.Location);
3978 | shift_expression OP_SHIFT_LEFT concat_expression
3982 | shift_expression OP_SHIFT_RIGHT concat_expression
3988 relational_expression
3990 | relational_expression ASSIGN shift_expression
3992 $$ = new Binary (Binary.Operator.Equality,
3993 (Expression) $1, (Expression) $3, lexer.Location);
3995 | relational_expression OP_NE shift_expression
3997 $$ = new Binary (Binary.Operator.Inequality,
3998 (Expression) $1, (Expression) $3, lexer.Location);
4000 | relational_expression OP_LT shift_expression
4002 $$ = new Binary (Binary.Operator.LessThan,
4003 (Expression) $1, (Expression) $3, lexer.Location);
4005 | relational_expression OP_GT shift_expression
4007 $$ = new Binary (Binary.Operator.GreaterThan,
4008 (Expression) $1, (Expression) $3, lexer.Location);
4010 | relational_expression OP_LE shift_expression
4012 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4013 (Expression) $1, (Expression) $3, lexer.Location);
4015 | relational_expression OP_GE shift_expression
4017 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4018 (Expression) $1, (Expression) $3, lexer.Location);
4020 | relational_expression IS shift_expression
4022 //FIXME: Should be a different op for reference equality but allows tests to use Is
4023 $$ = new Binary (Binary.Operator.Equality,
4024 (Expression) $1, (Expression) $3, lexer.Location);
4026 | TYPEOF shift_expression IS type
4028 //FIXME: Is this rule correctly defined ?
4029 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4034 : relational_expression
4035 | NOT negation_expression
4037 //FIXME: Is this rule correctly defined ?
4038 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4042 conditional_and_expression
4043 : negation_expression
4044 | conditional_and_expression AND negation_expression
4046 $$ = new Binary (Binary.Operator.LogicalAnd,
4047 (Expression) $1, (Expression) $3, lexer.Location);
4049 | conditional_and_expression ANDALSO negation_expression
4050 { // FIXME: this is likely to be broken
4051 $$ = new Binary (Binary.Operator.LogicalAnd,
4052 (Expression) $1, (Expression) $3, lexer.Location);
4056 conditional_or_expression
4057 : conditional_and_expression
4058 | conditional_or_expression OR conditional_and_expression
4060 $$ = new Binary (Binary.Operator.LogicalOr,
4061 (Expression) $1, (Expression) $3, lexer.Location);
4063 | conditional_or_expression ORELSE conditional_and_expression
4064 { // FIXME: this is likely to be broken
4065 $$ = new Binary (Binary.Operator.LogicalOr,
4066 (Expression) $1, (Expression) $3, lexer.Location);
4070 conditional_xor_expression
4071 : conditional_or_expression
4072 | conditional_xor_expression XOR conditional_or_expression
4074 $$ = new Binary (Binary.Operator.ExclusiveOr,
4075 (Expression) $1, (Expression) $3, lexer.Location);
4079 assignment_expression
4080 : prefixed_unary_expression ASSIGN expression
4082 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4084 | prefixed_unary_expression STAR ASSIGN expression
4086 Location l = lexer.Location;
4088 $$ = new CompoundAssign (
4089 Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
4091 | prefixed_unary_expression DIV ASSIGN expression
4093 Location l = lexer.Location;
4095 $$ = new CompoundAssign (
4096 Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
4098 | prefixed_unary_expression PLUS ASSIGN expression
4100 Location l = lexer.Location;
4102 $$ = new CompoundAssign (
4103 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4105 | prefixed_unary_expression MINUS ASSIGN expression
4107 Location l = lexer.Location;
4109 $$ = new CompoundAssign (
4110 Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
4112 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
4114 Location l = lexer.Location;
4116 $$ = new CompoundAssign (
4117 Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
4119 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
4121 Location l = lexer.Location;
4123 $$ = new CompoundAssign (
4124 Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
4126 | prefixed_unary_expression OP_CONCAT ASSIGN expression
4128 Location l = lexer.Location;
4130 // FIXME should be strings only
4131 $$ = new CompoundAssign (
4132 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4134 | prefixed_unary_expression OP_EXP ASSIGN expression
4136 Location l = lexer.Location;
4138 /* TODO: $$ = new CompoundAssign (
4139 Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
4141 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4143 ArrayList args = new ArrayList();
4144 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4147 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4148 n.isDelegate = true;
4149 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4162 : namespace_or_type_name
4164 $$ = DecomposeQI ((string) $1, lexer.Location);
4173 ArrayList types = new ArrayList ();
4178 | type_list COMMA type
4180 ArrayList types = (ArrayList) $1;
4187 namespace_or_type_name
4188 : qualified_identifier
4192 : OBJECT { $$ = TypeManager.system_object_expr; }
4198 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4199 | DATE { $$ = TypeManager.system_date_expr; }
4200 | CHAR { $$ = TypeManager.system_char_expr; }
4201 | STRING { $$ = TypeManager.system_string_expr; }
4207 | floating_point_type
4208 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4213 | BYTE { $$ = TypeManager.system_byte_expr; }
4214 | SHORT { $$ = TypeManager.system_int16_expr; }
4215 | INTEGER { $$ = TypeManager.system_int32_expr; }
4216 | LONG { $$ = TypeManager.system_int64_expr; }
4220 : SINGLE { $$ = TypeManager.system_single_expr; }
4221 | DOUBLE { $$ = TypeManager.system_double_expr; }
4225 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4227 if(tokenizerController.IsAcceptingTokens)
4229 if(in_external_source)
4230 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4232 in_external_source = true;
4234 lexer.EffectiveSource = (string) $4;
4235 lexer.EffectiveLine = (int) $6;
4239 | HASH IDENTIFIER LITERAL_STRING EOL
4241 if(tokenizerController.IsAcceptingTokens)
4243 string id = ($2 as string);
4245 if(!($2 as string).ToLower().Equals("region"))
4246 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4253 | HASH END IDENTIFIER EOL
4255 if(tokenizerController.IsAcceptingTokens)
4257 if( ($3 as string).ToLower().Equals("externalsource")) {
4258 if(!in_external_source)
4259 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4261 in_external_source = false;
4262 lexer.EffectiveSource = lexer.Source;
4263 lexer.EffectiveLine = lexer.Line;
4266 else if(($3 as string).ToLower().Equals("region")) {
4267 if(in_marked_region > 0)
4270 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4273 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4277 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4279 if(tokenizerController.IsAcceptingTokens)
4286 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4289 ifElseStateMachine.HandleToken(tok);
4291 catch(ApplicationException) {
4292 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4295 boolean_literal opt_then EOL
4297 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4301 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4303 ifElseStateMachine.HandleToken(tok);
4305 catch(ApplicationException) {
4306 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4309 boolean_literal opt_then EOL
4311 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4315 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4317 ifElseStateMachine.HandleToken(tok);
4319 catch(ApplicationException) {
4320 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4325 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4329 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4331 ifElseStateMachine.HandleToken(tok);
4333 catch(ApplicationException) {
4334 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4339 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4343 if(tokenizerController.IsAcceptingTokens)
4344 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4346 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4356 public Tokenizer Lexer {
4362 public static Expression DecomposeQI (string name, Location loc)
4366 if (name.IndexOf ('.') == -1){
4367 return new SimpleName (name, loc);
4369 int pos = name.LastIndexOf (".");
4370 string left = name.Substring (0, pos);
4371 string right = name.Substring (pos + 1);
4373 o = DecomposeQI (left, loc);
4375 return new MemberAccess (o, right, loc);
4379 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4381 Block implicit_block;
4382 ArrayList inits = null;
4385 // We use the `Used' property to check whether statements
4386 // have been added to the current block. If so, we need
4387 // to create another block to contain the new declaration
4388 // otherwise, as an optimization, we use the same block to
4389 // add the declaration.
4391 // FIXME: A further optimization is to check if the statements
4392 // that were added were added as part of the initialization
4393 // below. In which case, no other statements have been executed
4394 // and we might be able to reduce the number of blocks for
4395 // situations like this:
4397 // int j = 1; int k = j + 1;
4400 VariableDeclaration.FixupTypes (variable_declarators);
4402 if (current_block.Used) {
4403 implicit_block = new Block (current_block, true, loc, Location.Null);
4404 implicit_block.AddChildVariableNames (current_block);
4406 implicit_block = current_block;
4408 foreach (VariableDeclaration decl in variable_declarators){
4409 Expression type = decl.type;
4410 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4411 if (decl.expression_or_array_initializer != null){
4413 inits = new ArrayList ();
4420 return implicit_block;
4422 foreach (VariableDeclaration decl in inits){
4425 Expression type = decl.type;
4427 if ((decl.expression_or_array_initializer is Expression) ||
4428 (decl.expression_or_array_initializer is New)) {
4429 expr = (Expression) decl.expression_or_array_initializer;
4431 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4433 expr = new ArrayCreation (type, "", init, decl.Location);
4436 LocalVariableReference var;
4437 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4439 assign = new Assign (var, expr, decl.Location);
4441 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4444 return implicit_block;
4447 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4449 Block implicit_block;
4450 VariableDeclaration.FixupTypes (variable_declarators);
4452 if (current_block.Used)
4453 implicit_block = new Block (current_block, true);
4455 implicit_block = current_block;
4457 foreach (VariableDeclaration decl in variable_declarators){
4458 Expression type = decl.type;
4459 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4460 current_local_parameters, decl.Location);
4463 return implicit_block;
4471 public VarName (object n, object t, object r)
4481 // A class used to pass around variable declarations and constants
4483 public class VariableDeclaration {
4484 public string identifier;
4485 public object expression_or_array_initializer;
4486 public Location Location;
4487 public Attributes OptAttributes;
4488 public Expression type;
4489 public ArrayList dims;
4491 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4493 this.identifier = id;
4494 this.expression_or_array_initializer = eoai;
4496 this.OptAttributes = opt_attrs;
4501 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4505 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4509 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4510 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4514 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4516 // FIXME : This is broken: only the first rank is parsed
4517 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4520 public static void FixupTypes (ArrayList vars)
4522 int varcount = vars.Count;
4523 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4525 if (last_var.type == null)
4526 last_var.type = TypeManager.system_object_expr;
4528 Expression cur_type = last_var.type;
4529 int n = varcount - 1;
4532 VariableDeclaration var = (VariableDeclaration) vars[n--];
4533 if (var.type == null)
4534 var.type = cur_type;
4536 cur_type = var.type;
4540 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4544 if (IndexList != null) {
4545 foreach (Expression e in IndexList)
4546 if (!(e is EmptyExpression)) {
4555 public static bool IndexesSpecified (ArrayList ranks)
4559 if (ranks != null) {
4560 foreach (ArrayList IndexList in ranks) {
4561 if (IndexesSpecifiedInRank (IndexList)) {
4570 public static string StripDims (string varname, ref string d)
4572 string res = varname;
4575 if (varname.IndexOf("[") >= 0) {
4576 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4577 res = varname.Substring(0, varname.IndexOf("["));
4583 public static string StripDims (string varname)
4587 return (StripDims(varname, ref dres));
4590 public static string StripIndexesFromDims (string dims)
4592 StringBuilder sb = new StringBuilder();
4594 foreach (char c in dims)
4595 if (c == ',' || c == ']' || c == '[')
4598 return sb.ToString();
4601 public static string BuildRank (ArrayList rank)
4604 return BuildRank(rank, out allEmpty);
4607 public static string BuildRank (ArrayList rank, out bool allEmpty)
4614 foreach (object e in rank) {
4615 if (!(e is EmptyExpression))
4626 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
4630 bool allEmpty = true;
4631 foreach (ArrayList rank in rank_specifiers) {
4633 res = BuildRank (rank, out tmp) + res;
4637 if (!allEmpty && mustBeEmpty)
4638 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
4643 public static void VBFixIndexList (ref ArrayList IndexList)
4645 if (IndexList != null) {
4646 for (int x = 0; x < IndexList.Count; x++) {
4647 Expression e = (Expression) IndexList[x];
4648 if (!(e is EmptyExpression)) {
4649 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4655 public static bool IsArrayDecl (Parser t)
4657 // return (varname.IndexOf("[") >= 0);
4658 return (t.current_rank_specifiers != null);
4661 public static void VBFixIndexLists (ref ArrayList ranks)
4663 if (ranks != null) {
4664 for (int x = 0; x < ranks.Count; x++) {
4665 ArrayList IndexList = (ArrayList) ranks[x];
4666 VBFixIndexList (ref IndexList);
4671 public static void FixupArrayTypes (ArrayList vars)
4673 int varcount = vars.Count;
4676 foreach (VariableDeclaration var in vars) {
4677 if (var.identifier.EndsWith(",")) {
4678 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4679 var.identifier.LastIndexOf(",")) + "]";
4680 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4681 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4688 public Property BuildSimpleProperty (Expression p_type, string name,
4689 Field p_fld, int mod_flags,
4690 Attributes attrs, Location loc)
4693 Block get_block, set_block;
4694 Accessor acc_set, acc_get;
4695 StatementExpression a_set;
4700 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4701 args = new Parameter [1];
4702 args [0] = implicit_value_parameter;
4704 Parameters set_params = new Parameters (args, null, loc);
4705 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4706 (Expression) new SimpleName("value", loc), loc), loc);
4708 set_block = new Block (current_block, set_params, loc, Location.Null);
4709 set_block.AddStatement ((Statement) a_set);
4710 acc_set = new Accessor (set_block, attrs);
4713 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4714 get_block = new Block (current_block, null, loc, Location.Null);
4715 get_block.AddStatement ((Statement) a_get);
4716 acc_get = new Accessor (get_block, attrs);
4718 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4725 current_block = new Block (current_block, current_local_parameters,
4726 lexer.Location, Location.Null);
4733 while (current_block.Implicit)
4734 current_block = current_block.Parent;
4736 res = current_block;
4738 current_block.SetEndLocation (lexer.Location);
4739 current_block = current_block.Parent;
4744 private void AddHandler (Expression evt_definition, string handler_name)
4746 AddHandler (current_block, evt_definition, handler_name);
4749 void CheckAttributeTarget (string a)
4753 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4757 Location l = lexer.Location;
4758 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4763 private void AddHandler (Block b, Expression evt_id, string handler_name)
4765 Location loc = lexer.Location;
4766 string evt_target = evt_id.ToString();
4767 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4768 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4772 private void RaiseEvent (string evt_name, ArrayList args)
4774 Location loc = lexer.Location;
4776 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4777 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4778 current_block.AddStatement (s);
4781 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4783 Location loc = lexer.Location;
4784 string evt_target = evt_definition.ToString();
4785 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4786 Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4791 // This method is used to get at the complete string representation of
4792 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4793 // This is necessary because local_variable_type admits primary_expression
4794 // as the type of the variable. So we do some extra checking
4796 string GetQualifiedIdentifier (Expression expr)
4798 if (expr is SimpleName)
4799 return ((SimpleName)expr).Name;
4800 else if (expr is MemberAccess)
4801 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4803 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4807 private void RemoveHandler (Expression evt_definition, string handler_name)
4809 RemoveHandler (current_block, evt_definition, handler_name);
4812 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4814 ConstructorInitializer ci = null;
4817 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4818 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4820 if (i.expr is BaseAccess) {
4821 BaseAccess ba = (BaseAccess) i.expr;
4822 if (ba.member == "New" || ba.member == ".ctor") {
4823 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4827 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4828 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4836 void Error_ExpectingTypeName (Location l, Expression expr)
4838 if (expr is Invocation){
4839 Report.Error (1002, l, "; expected");
4841 Report.Error (-1, l, "Invalid Type definition");
4845 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4849 private void ReportError9998()
4851 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4854 protected override int parse ()
4856 RootContext.InitializeImports(ImportsList);
4857 current_namespace = new Namespace (null, RootContext.RootNamespace);
4858 current_container = RootContext.Tree.Types;
4859 current_container.Namespace = current_namespace;
4860 oob_stack = new Stack ();
4861 switch_stack = new Stack ();
4862 expr_stack = new Stack ();
4863 tmp_blocks = new Stack();
4864 with_stack = new Stack();
4865 statement_stack = new Stack();
4867 UseExtendedSyntax = name.EndsWith(".mbs");
4868 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4869 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4870 OptionCompareBinary = InitialOptionCompareBinary;
4872 lexer = new Tokenizer (input, name, defines);
4874 ifElseStateMachine = new IfElseStateMachine();
4875 tokenizerController = new TokenizerController(lexer);
4877 StringBuilder value = new StringBuilder ();
4879 if (yacc_verbose_flag)
4880 yyparse (lexer, new yydebug.yyDebugSimple ());
4886 catch(MBASException e) {
4887 Report.Error(e.code, e.loc, e.Message);
4889 catch (Exception e) {
4890 if (Report.Stacktrace)
4891 Console.WriteLine(e);
4892 Report.Error (29999, lexer.Location, "Parsing error");
4895 RootContext.VerifyImports();
4897 return Report.Errors;
4903 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
4905 catch(ApplicationException) {
4906 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4909 if(in_external_source)
4910 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
4912 if(in_marked_region > 0)
4913 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
4916 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
4919 tokenizerController.PositionTokenizerCursor(tok, expr);
4921 catch(ApplicationException) {
4922 tok = IfElseStateMachine.Token.EOF;
4924 ifElseStateMachine.HandleToken(tok);
4926 catch(ApplicationException) {
4927 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);