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),
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),
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);
2171 : /* empty */ { $$ = null; }
2172 | HANDLES evt_handler { $$ = $2; }
2176 : qualified_identifier
2178 $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);
2184 | ME DOT qualified_identifier
2186 $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);
2188 /*| MYBASE DOT qualified_identifier
2190 // FIXME: this is blatantly wrong and crash-prone
2191 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2195 constructor_declaration
2196 : SUB NEW opt_params logical_end_of_line
2198 current_local_parameters = (Parameters) $3;
2200 oob_stack.Push (lexer.Location);
2202 Location l = (Location) oob_stack.Pop ();
2203 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2208 Constructor c = (Constructor) $1;
2209 c.Block = (Block) end_block();
2210 c.ModFlags = (int) current_modifiers;
2211 c.OptAttributes = current_attributes;
2213 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2215 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2216 current_local_parameters = null;
2218 END SUB logical_end_of_line
2221 opt_formal_parameter_list
2224 $$ = Parameters.EmptyReadOnlyParameters;
2226 | formal_parameter_list
2229 //Parameter p = ((Parameters) $1).FixedParameters[0];
2233 formal_parameter_list
2236 ArrayList pars_list = (ArrayList) $1;
2237 Parameter [] pars = null;
2238 Parameter array_parameter = null;
2239 int non_array_count = pars_list.Count;
2240 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2241 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2242 non_array_count = pars_list.Count - 1;
2244 foreach (Parameter par in pars_list)
2245 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2246 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2247 non_array_count = 0;
2248 array_parameter = null;
2251 if (non_array_count > 0) {
2252 pars = new Parameter [non_array_count];
2253 pars_list.CopyTo (0, pars, 0, non_array_count);
2255 $$ = new Parameters (pars, array_parameter, lexer.Location);
2262 ArrayList pars = new ArrayList ();
2267 | parameters COMMA parameter
2269 ArrayList pars = (ArrayList) $1;
2278 opt_parameter_modifier
2279 identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2281 Parameter.Modifier pm = (Parameter.Modifier)$2;
2282 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2285 if (opt_parm && ($7 == null))
2286 Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
2288 if (!opt_parm && ($7 != null))
2289 Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
2291 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2292 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2293 Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
2296 if ((pm & Parameter.Modifier.REF) !=0)
2297 pm |= Parameter.Modifier.ISBYREF;
2299 if ($4 != null && $6 != null && $4 != $6)
2300 Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2302 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2304 string t = ptype.ToString ();
2305 if (t.IndexOf('[') >= 0)
2306 Report.Error (31087, lexer.Location, "Array types specified in too many places");
2308 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
2310 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2311 Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
2312 $$ = new Parameter (ptype, (string) $3, pm,
2313 (Attributes) $1, (Expression) $7, opt_parm);
2317 opt_parameter_modifier
2318 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2319 | parameter_modifiers { $$ = $1; }
2323 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2324 | parameter_modifier { $$ = $1; }
2328 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2329 | BYVAL { $$ = Parameter.Modifier.VAL; }
2330 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2331 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2336 | statement_list end_of_stmt
2341 | statement_list end_of_stmt statement
2345 : declaration_statement
2347 if ($1 != null && (Block) $1 != current_block){
2348 current_block.AddStatement ((Statement) $1);
2349 current_block = (Block) $1;
2352 | embedded_statement
2354 Statement s = (Statement) $1;
2356 current_block.AddStatement ((Statement) $1);
2359 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2361 AddHandler ((Expression) $2, (Expression) $5);
2363 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
2365 RemoveHandler ((Expression) $2, (Expression) $5);
2367 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2369 RaiseEvent ((string) $2, (ArrayList) $3);
2371 /* | array_handling_statement */
2372 /* | empty_statement */
2375 Statement s = (Statement) $1;
2377 current_block.AddStatement ((Statement) $1);
2381 opt_raise_event_args
2382 : /* empty */ { $$ = null; }
2383 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2400 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2402 if (!current_block.AddLabel ((string) $1, labeled)){
2403 Location l = lexer.Location;
2404 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2406 current_block.AddStatement (labeled);
2410 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2412 if (!current_block.AddLabel ((string) $1, labeled)){
2413 Location l = lexer.Location;
2414 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2416 current_block.AddStatement (labeled);
2422 : expression_statement
2423 | selection_statement
2424 | iteration_statement
2426 | synclock_statement
2428 | array_handling_statement
2434 $$ = new EmptyStatement ();
2440 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2442 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2443 Expression e = (Expression) $2;
2450 Block b = end_block();
2457 array_handling_statement
2463 : REDIM opt_preserve redim_clauses
2465 ArrayList list = (ArrayList) $3;
2466 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2473 : /* empty */ { $$ = false; }
2474 | PRESERVE { $$ = true; }
2480 ArrayList clauses = new ArrayList ();
2485 | redim_clauses COMMA redim_clause
2487 ArrayList clauses = (ArrayList) ($1);
2495 : invocation_expression
2497 Invocation i = (Invocation) $1;
2498 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2504 : ERASE erase_clauses
2506 ArrayList list = (ArrayList) $2;
2507 foreach(Expression e in list)
2509 Erase r = new Erase (e, lexer.Location);
2518 ArrayList clauses = new ArrayList ();
2523 | erase_clauses COMMA erase_clause
2525 ArrayList clauses = (ArrayList) ($1);
2533 : primary_expression
2538 | continue_statement
2539 | */return_statement
2549 $$ = new Goto (current_block, (string) $2, lexer.Location);
2554 : THROW opt_expression
2556 $$ = new Throw ((Expression) $2, lexer.Location);
2563 $$ = new Exit ((ExitType)$2, lexer.Location);
2568 : DO { $$ = ExitType.DO; }
2569 | FOR { $$ = ExitType.FOR; }
2570 | WHILE { $$ = ExitType.WHILE; }
2571 | SELECT { $$ = ExitType.SELECT; }
2572 | SUB { $$ = ExitType.SUB; }
2573 | FUNCTION { $$ = ExitType.FUNCTION; }
2574 | PROPERTY { $$ = ExitType.PROPERTY; }
2575 | TRY { $$ = ExitType.TRY; }
2578 : RETURN opt_expression
2580 $$ = new Return ((Expression) $2, lexer.Location);
2592 : FOR EACH identifier IN
2594 oob_stack.Push (lexer.Location);
2596 expression end_of_stmt
2600 Block foreach_block = current_block;
2601 Location l = lexer.Location;
2602 LocalVariableReference v = null;
2605 vi = foreach_block.GetVariableInfo ((string) $3);
2607 // Get a reference to this variable.
2608 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2611 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2618 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2619 Block foreach_block = end_block();
2620 Location l = (Location) oob_stack.Pop ();
2624 f = new Foreach (null, v, (Expression) $6, foreach_block, l);
2634 if (!UseExtendedSyntax)
2640 if (iterator_container == null){
2641 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2644 iterator_container.SetYields ();
2645 $$ = new Yield ((Expression) $2, lexer.Location);
2650 if (!UseExtendedSyntax)
2656 if (iterator_container == null){
2657 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2660 iterator_container.SetYields ();
2661 $$ = new YieldBreak (lexer.Location);
2667 : SYNCLOCK expression end_of_stmt
2674 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2691 tmp_catch_clauses = (ArrayList) $5;
2700 ArrayList s = new ArrayList ();
2702 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2709 // Now s contains the list of specific catch clauses
2710 // and g contains the general one.
2711 Block b = end_block();
2713 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2720 tmp_block = end_block();
2730 ArrayList s = new ArrayList ();
2731 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2733 if (catch_list != null){
2734 foreach (Catch cc in catch_list) {
2742 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2748 : /* empty */ { $$ = null; }
2755 ArrayList l = new ArrayList ();
2760 | catch_clauses catch_clause
2762 ArrayList l = (ArrayList) $1;
2770 : /* empty */ { $$ = null; }
2775 : CATCH opt_catch_args end_of_stmt
2777 Expression type = null;
2781 DictionaryEntry cc = (DictionaryEntry) $2;
2782 type = (Expression) cc.Key;
2783 id = (string) cc.Value;
2786 ArrayList one = new ArrayList ();
2787 Location loc = lexer.Location;
2789 one.Add (new VariableDeclaration (id, type, loc));
2793 current_block = new Block (current_block);
2794 Block b = declare_local_variables (type, one, loc);
2800 opt_statement_list {
2801 Expression type = null;
2803 Block b_catch = current_block;
2806 DictionaryEntry cc = (DictionaryEntry) $2;
2807 type = (Expression) cc.Key;
2808 id = (string) cc.Value;
2812 // FIXME: I can change this for an assignment.
2814 while (current_block != (Block) $1)
2815 current_block = current_block.Parent;
2819 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2824 : /* empty */ { $$ = null; }
2829 : identifier AS type
2831 $$ = new DictionaryEntry ($3, $1);
2837 : DO opt_do_construct end_of_stmt
2840 oob_stack.Push (lexer.Location);
2843 LOOP opt_do_construct
2845 Expression t_before = (Expression) $2;
2846 Expression t_after = (Expression) $7;
2849 if ((t_before != null) && (t_after != null))
2850 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2852 if ((t_before == null) && (t_after == null))
2853 t = new BoolLiteral (true);
2855 t = (t_before != null) ? t_before : t_after;
2857 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2859 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2860 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2861 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2863 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2868 : /* empty */ { $$ = null; }
2869 | while_or_until boolean_expression
2871 do_type = (DoOptions)$1;
2872 $$ = (Expression) $2;
2877 : WHILE { $$ = DoOptions.WHILE; }
2878 | UNTIL { $$ = DoOptions.UNTIL; }
2885 oob_stack.Push (lexer.Location);
2887 boolean_expression end_of_stmt
2891 Location l = (Location) oob_stack.Pop ();
2892 Block b = end_block();
2893 Expression e = (Expression) $3;
2894 $$ = new While ((Expression) e, (Statement) b, l);
2899 : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
2904 ArrayList VarDeclaration = new ArrayList ();
2905 VarDeclaration.Add (new VariableDeclaration ((string) $2,
2906 (Expression) $3, null, lexer.Location, null));
2908 DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
2909 Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2912 oob_stack.Push (lexer.Location);
2918 Block inner_statement = end_block();
\r
2919 Location l = (Location) oob_stack.Pop ();
\r
2920 Expression for_var = (Expression) DecomposeQI ((string)$2, l);
\r
2922 Expression assign_expr = new Assign (for_var, (Expression) $5, l);
\r
2923 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
\r
2924 for_var, (Expression) $7, l);
\r
2925 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
\r
2926 for_var, (Expression) $8, l), l);
\r
2928 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
\r
2929 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
\r
2931 For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
2934 current_block.AddStatement (f);
2943 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2944 | STEP expression { $$ = $2; }
2953 : if_statement_open opt_then if_statement_rest
2957 | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
2961 Location l = (Location) oob_stack.Pop ();
2962 tmp_expr = (Expression)expr_stack.Pop();
2963 $$ = new If ((Expression) tmp_expr, end_block(), l);
2967 Location l = (Location) oob_stack.Pop ();
2968 tmp_expr = (Expression)expr_stack.Pop();
2969 tmp_block = (Block) tmp_blocks.Pop ();
2970 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
2973 | if_statement_open THEN else_pre_embedded_statement
2975 Location l = (Location) oob_stack.Pop ();
2976 tmp_expr = (Expression)expr_stack.Pop();
2977 tmp_block = (Block) tmp_blocks.Pop ();
2978 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
2982 pre_embedded_statement
2983 : embedded_statement
2985 Statement s = (Statement) $1;
2987 current_block.AddStatement ((Statement) $1);
2991 opt_else_pre_embedded_statement
2993 | else_pre_embedded_statement
2996 else_pre_embedded_statement
2999 Block bl = end_block();
3000 tmp_blocks.Push(bl);
3004 | ELSE embedded_statement
3006 Block bl = end_block();
3007 tmp_blocks.Push(bl);
3010 Statement s = (Statement) $2;
3011 current_block.AddStatement ((Statement) $2);
3016 : IF boolean_expression
3018 oob_stack.Push (lexer.Location);
3020 tmp_expr = (Expression) $2;
3021 expr_stack.Push(tmp_expr);
3035 Location l = (Location) oob_stack.Pop ();
3036 Expression expr = (Expression)expr_stack.Pop();
3037 $$ = new If ((Expression) expr, (Statement) end_block(), l);
3043 Block bl = end_block();
3044 tmp_blocks.Push(bl);
3050 Location l = (Location) oob_stack.Pop ();
3051 tmp_expr = (Expression)expr_stack.Pop();
3052 tmp_block = (Block) tmp_blocks.Pop();
3053 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
3057 ELSEIF boolean_expression opt_then
3059 tmp_expr = (Expression) $4;
3060 expr_stack.Push(tmp_expr);
3061 tmp_block = end_block();
3062 tmp_blocks.Push(tmp_block);
3065 else_if_statement_rest
3067 Statement stmt = (Statement) statement_stack.Pop();
3068 Block bl = (Block) tmp_blocks.Pop();
3069 Expression expr = (Expression)expr_stack.Pop();
3070 Location l = (Location) oob_stack.Pop ();
3071 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
3076 else_if_statement_rest
3081 Location l = (Location) oob_stack.Pop ();
3083 Expression expr = (Expression)expr_stack.Pop();
3084 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
3085 statement_stack.Push(stmt);
3091 Block bl = end_block();
3092 tmp_blocks.Push(bl);
3098 Location l = (Location) oob_stack.Pop ();
3100 Expression expr = (Expression)expr_stack.Pop();
3101 Block bl = (Block)tmp_blocks.Pop();
3102 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
3103 statement_stack.Push(stmt);
3107 ELSEIF boolean_expression opt_then
3109 expr_stack.Push((Expression) $4);
3110 Block bl = end_block();
3111 tmp_blocks.Push(bl);
3114 else_if_statement_rest
3116 Location l = (Location) oob_stack.Pop ();
3118 Statement tmp_stmt = (Statement)statement_stack.Pop();
3119 Block bl = (Block) tmp_blocks.Pop();
3120 Expression expr = (Expression)expr_stack.Pop();
3121 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
3122 statement_stack.Push(stmt);
3127 : SELECT opt_case expression end_of_stmt
3129 oob_stack.Push (lexer.Location);
3130 switch_stack.Push (current_block);
3135 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3136 current_block = (Block) switch_stack.Pop ();
3141 : /* empty */ { $$ = null; }
3142 | case_sections { $$ = $1; }
3146 : case_sections case_section
3148 ArrayList sections = (ArrayList) $1;
3155 ArrayList sections = new ArrayList ();
3169 : CASE case_clauses ends
3175 //Block topmost = current_block;
3176 Block topmost = end_block();
3178 while (topmost.Implicit)
3179 topmost = topmost.Parent;
3181 // FIXME: This is a horrible hack which MUST go
3182 topmost.statements.Add (new Break (lexer.Location));
3183 $$ = new SwitchSection ((ArrayList) $2, topmost);
3186 /* FIXME: we should somehow flag an error
3187 (BC30321 'Case' cannot follow a 'Case Else'
3188 in the same 'Select' statement.)
3189 if Case Else is not the last of the Case clauses
3196 //Block topmost = current_block;
3197 Block topmost = end_block();
3199 while (topmost.Implicit)
3200 topmost = topmost.Parent;
3202 // FIXME: This is a horrible hack which MUST go
3203 topmost.statements.Add (new Break (lexer.Location));
3205 ArrayList a = new ArrayList();
3206 a.Add (new SwitchLabel (null, lexer.Location));
3207 $$ = new SwitchSection ((ArrayList) a, topmost);
3214 ArrayList labels = new ArrayList ();
3219 | case_clauses COMMA case_clause
3221 ArrayList labels = (ArrayList) ($1);
3229 : opt_is comparison_operator expression
3232 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3254 expression_statement
3255 : statement_expression
3262 statement_expression
3263 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3264 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3265 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3268 object_creation_expression
3269 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3271 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3275 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3279 array_creation_expression
3280 : object_creation_expression opt_rank_specifiers array_initializer
3283 ArrayList dims = new ArrayList();
3285 if (n.Arguments != null) {
3286 foreach (Argument a in n.Arguments) {
3291 Expression atype = n.RequestedType;
3294 atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
3296 ArrayList init = (ArrayList) $3;
3297 if (init.Count == 0)
3300 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3301 VariableDeclaration.VBFixIndexList (ref dims);
3302 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3306 string rank = VariableDeclaration.BuildRank (dims);
3307 $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location);
3309 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3314 : object_creation_expression
3315 | array_creation_expression
3318 declaration_statement
3319 : local_variable_declaration
3322 DictionaryEntry de = (DictionaryEntry) $1;
3324 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3327 | local_constant_declaration
3330 DictionaryEntry de = (DictionaryEntry) $1;
3332 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3337 local_variable_declaration
3338 : DIM variable_declarators
3340 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3345 local_constant_declaration
3346 : CONST constant_declarators
3349 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3355 constant_declarators
3356 : constant_declarator
3358 ArrayList decl = new ArrayList ();
3364 | constant_declarators COMMA constant_declarator
3366 ArrayList decls = (ArrayList) $1;
3375 : variable_name opt_type_decl opt_variable_initializer
3377 VarName vname = (VarName) $1;
3378 string varname = (string) vname.Name;
3379 current_rank_specifiers = (ArrayList) vname.Rank;
3380 object varinit = $3;
3381 ArrayList a_dims = null;
3383 if (varinit == null)
3385 30438, lexer.Location, "Constant should have a value"
3388 if (vname.Type != null && $2 != null)
3390 30302, lexer.Location,
3391 "Type character cannot be used with explicit type declaration" );
3393 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3395 if (current_rank_specifiers != null)
3397 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3401 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3405 variable_declarators
3406 : variable_declarator
3408 ArrayList decl = new ArrayList ();
3409 decl.AddRange ((ArrayList) $1);
3412 | variable_declarators COMMA variable_declarator
3414 ArrayList decls = (ArrayList) $1;
3415 decls.AddRange ((ArrayList) $3);
3421 : variable_names opt_type_decl opt_variable_initializer
3423 ArrayList names = (ArrayList) $1;
3424 object varinit = $3;
3425 ArrayList VarDeclarations = new ArrayList();
3427 ArrayList a_dims = null;
3429 if ((names.Count > 1) && (varinit != null))
3431 30671, lexer.Location,
3432 "Multiple variables with single type can not have " +
3433 "a explicit initialization" );
3436 foreach (VarName vname in names)
3438 string varname = (string) vname.Name;
3439 current_rank_specifiers = (ArrayList) vname.Rank;
3443 if(vname.Type != null && $2 != null)
3445 30302, lexer.Location,
3446 "Type character cannot be used with explicit type declaration" );
3448 // Some checking is required for particularly weird declarations
3449 // like Dim a As Integer(,)
3451 vartype = (Expression) ((Pair) $2).First;
3453 /*if ($3 != null && $3 is ArrayList)
3454 Report.Error (205, "End of statement expected.");*/
3456 ArrayList args = (ArrayList) ((Pair) $2).Second;
3457 if (current_rank_specifiers != null)
3458 Report.Error (31087, lexer.Location,
3459 "Array types specified in too many places");
3461 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3462 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3464 current_rank_specifiers = new ArrayList ();
3465 current_rank_specifiers.Add (args);
3468 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3470 // if the variable is an array with explicit bound
3471 // and having explicit initialization throw exception
3472 if (current_rank_specifiers != null && varinit != null)
3474 bool broken = false;
3475 foreach (ArrayList exprs in current_rank_specifiers)
3477 foreach (Expression expr in exprs)
3479 if (!((Expression)expr is EmptyExpression ))
3482 30672, lexer.Location,
3483 "Array declared with explicit bound " +
3484 " can not have explicit initialization");
3495 Check for a declaration like Dim a(2) or Dim a(2,3)
3496 If this is the case, we must generate an ArrayCreationExpression
3497 and, in case, add the initializer after the array has been created.
3499 if (VariableDeclaration.IsArrayDecl (this)) {
3500 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3501 a_dims = (ArrayList) current_rank_specifiers;
3502 VariableDeclaration.VBFixIndexLists (ref a_dims);
3503 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3505 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
3508 if (vartype is New) {
3509 if (varinit != null) {
3510 Report.Error (30205, lexer.Location, "End of statement expected");
3516 vartype = ((New)vartype).RequestedType;
3519 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3521 $$ = VarDeclarations;
3528 ArrayList list = new ArrayList ();
3532 | variable_names COMMA variable_name
3534 ArrayList list = (ArrayList) $1;
3541 : identifier opt_type_character opt_array_name_modifier
3543 $$ = new VarName ($1, $2, $3);
3554 $$ = (Expression) $2;
3560 | AS type rank_specifiers
3562 $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
3567 : opt_type_with_ranks
3573 New n = new New ((Expression)$3, null, lexer.Location);
3574 $$ = (Expression) n;
3576 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3578 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3579 $$ = (Expression) n;
3581 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3583 ArrayList args = new ArrayList();
3584 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3587 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3588 $$ = (Expression) n;
3592 opt_array_name_modifier
3593 : /* empty */ { $$ = null; }
3594 | array_type_modifier { $$ = $1; }
3598 : rank_specifiers { $$ = $1; }
3601 opt_variable_initializer
3602 : /* empty */ { $$ = null; }
3603 | ASSIGN variable_initializer { $$ = $2; }
3606 variable_initializer
3619 : OPEN_BRACE CLOSE_BRACE
3621 ArrayList list = new ArrayList ();
3624 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3626 $$ = (ArrayList) $2;
3630 variable_initializer_list
3631 : variable_initializer
3633 ArrayList list = new ArrayList ();
3637 | variable_initializer_list COMMA variable_initializer
3639 ArrayList list = (ArrayList) $1;
3660 ArrayList rs = new ArrayList();
3664 | rank_specifiers rank_specifier
3666 ArrayList rs = (ArrayList) $1;
3673 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
3682 ArrayList ds = new ArrayList();
3683 ds.Add (new EmptyExpression());
3688 ArrayList ds = new ArrayList();
3689 ds.Add ((Expression) $1);
3692 | opt_dim_specifiers COMMA expression
3694 ArrayList ds = (ArrayList) $1;
3695 ds.Add ((Expression) $3);
3698 | opt_dim_specifiers COMMA
3700 ArrayList ds = (ArrayList) $1;
3701 ds.Add (new EmptyExpression());
3711 | parenthesized_expression
3714 | qualified_identifier
3716 string name = (string) $1;
3717 $$ = DecomposeQI (name, lexer.Location);
3719 | get_type_expression
3721 | invocation_expression
3731 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3732 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3733 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3734 | NOTHING { $$ = NullLiteral.Null; }
3738 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3739 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3740 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3745 object v = lexer.Value;
3748 $$ = new IntLiteral ((Int32)v);
3749 else if (v is short)
3750 $$ = new ShortLiteral ((Int16)v);
3752 $$ = new LongLiteral ((Int64)v);
3754 Console.WriteLine ("OOPS. Unexpected result from scanner");
3760 : TRUE { $$ = new BoolLiteral (true); }
3761 | FALSE { $$ = new BoolLiteral (false); }
3764 parenthesized_expression
3765 : OPEN_PARENS expression CLOSE_PARENS
3770 : primary_expression DOT identifier
3773 string id_name = (string)$3;
3774 if (id_name.ToUpper() == "NEW")
3776 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3780 if (with_stack.Count > 0) {
3781 Expression e = (Expression) with_stack.Peek();
3782 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3790 /* | primary_expression DOT NEW
3792 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3794 | predefined_type DOT identifier
3797 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3800 if (with_stack.Count > 0) {
3801 Expression e = (Expression) with_stack.Peek();
3802 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3816 invocation_expression
3817 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3820 Location l = lexer.Location;
3821 Report.Error (1, l, "THIS IS CRAZY");
3823 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3824 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3826 | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3829 Location l = lexer.Location;
3830 Report.Error (1, l, "THIS IS CRAZY");
3832 $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
3833 // Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
3838 : MYBASE DOT IDENTIFIER
3840 string id_name = (string) $3;
3841 if (id_name.ToUpper() == "NEW")
3843 $$ = new BaseAccess (id_name, lexer.Location);
3847 $$ = new BaseAccess ("New", lexer.Location);
3855 The 'argument' rule returns an 'empty' argument
3856 of type NoArg (used for default arguments in invocations)
3857 if no arguments are actually passed.
3859 If there is only one argument and it is o type NoArg,
3860 we return a null (empty) list
3862 ArrayList args = (ArrayList) $1;
3863 if (args.Count == 1 &&
3864 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3874 ArrayList list = new ArrayList ();
3878 | argument_list COMMA argument
3880 ArrayList list = (ArrayList) $1;
3889 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3891 | BYREF variable_reference
3893 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3897 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3899 | ADDRESSOF expression
3901 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
3906 : expression {/* note ("section 5.4"); */ $$ = $1; }
3911 : conditional_xor_expression { $$ = $1; }
3912 /*| assignment_expression*/
3923 $$ = new This (current_block, lexer.Location);
3927 // FIXME: This is actually somewhat different from Me
3928 // because it is for accessing static (classifier) methods/properties/fields
3929 $$ = new This (current_block, lexer.Location);
3934 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
3938 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3940 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3942 | cast_operator OPEN_PARENS expression CLOSE_PARENS
3944 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3949 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3950 | CBYTE { $$ = TypeManager.system_byte_expr; }
3951 | CCHAR { $$ = TypeManager.system_char_expr; }
3952 | CDATE { $$ = TypeManager.system_date_expr; }
3953 | CDBL { $$ = TypeManager.system_double_expr; }
3954 | CDEC { $$ = TypeManager.system_decimal_expr; }
3955 | CINT { $$ = TypeManager.system_int32_expr; }
3956 | CLNG { $$ = TypeManager.system_int64_expr; }
3957 | COBJ { $$ = TypeManager.system_object_expr; }
3958 | CSHORT { $$ = TypeManager.system_int16_expr; }
3959 | CSNG { $$ = TypeManager.system_single_expr; }
3960 | CSTR { $$ = TypeManager.system_string_expr; }
3964 : GETTYPE OPEN_PARENS type CLOSE_PARENS
3966 $$ = new TypeOf ((Expression) $3, lexer.Location);
3970 exponentiation_expression
3971 : primary_expression
3972 | exponentiation_expression OP_EXP primary_expression
3978 prefixed_unary_expression
3979 : exponentiation_expression
3980 | PLUS prefixed_unary_expression
3982 //FIXME: Is this rule correctly defined ?
3983 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3985 | MINUS prefixed_unary_expression
3987 //FIXME: Is this rule correctly defined ?
3988 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3992 multiplicative_expression
3993 : prefixed_unary_expression
3994 | multiplicative_expression STAR prefixed_unary_expression
3996 $$ = new Binary (Binary.Operator.Multiply,
3997 (Expression) $1, (Expression) $3, lexer.Location);
3999 | multiplicative_expression DIV prefixed_unary_expression
4001 $$ = new Binary (Binary.Operator.Division,
4002 (Expression) $1, (Expression) $3, lexer.Location);
4006 integer_division_expression
4007 : multiplicative_expression
4008 | integer_division_expression OP_IDIV multiplicative_expression
4010 //FIXME: Is this right ?
4011 $$ = new Binary (Binary.Operator.Division,
4012 (Expression) $1, (Expression) $3, lexer.Location);
4017 : integer_division_expression
4018 | mod_expression MOD integer_division_expression
4020 $$ = new Binary (Binary.Operator.Modulus,
4021 (Expression) $1, (Expression) $3, lexer.Location);
4027 | additive_expression PLUS mod_expression
4029 $$ = new Binary (Binary.Operator.Addition,
4030 (Expression) $1, (Expression) $3, lexer.Location);
4032 | additive_expression MINUS mod_expression
4034 $$ = new Binary (Binary.Operator.Subtraction,
4035 (Expression) $1, (Expression) $3, lexer.Location);
4040 : additive_expression
4041 | concat_expression OP_CONCAT additive_expression
4043 // FIXME: This should only work for String expressions
4044 // We probably need to use something from the runtime
4045 $$ = new Binary (Binary.Operator.Addition,
4046 (Expression) $1, (Expression) $3, lexer.Location);
4052 | shift_expression OP_SHIFT_LEFT concat_expression
4056 | shift_expression OP_SHIFT_RIGHT concat_expression
4062 relational_expression
4064 | relational_expression ASSIGN shift_expression
4066 $$ = new Binary (Binary.Operator.Equality,
4067 (Expression) $1, (Expression) $3, lexer.Location);
4069 | relational_expression OP_NE shift_expression
4071 $$ = new Binary (Binary.Operator.Inequality,
4072 (Expression) $1, (Expression) $3, lexer.Location);
4074 | relational_expression OP_LT shift_expression
4076 $$ = new Binary (Binary.Operator.LessThan,
4077 (Expression) $1, (Expression) $3, lexer.Location);
4079 | relational_expression OP_GT shift_expression
4081 $$ = new Binary (Binary.Operator.GreaterThan,
4082 (Expression) $1, (Expression) $3, lexer.Location);
4084 | relational_expression OP_LE shift_expression
4086 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4087 (Expression) $1, (Expression) $3, lexer.Location);
4089 | relational_expression OP_GE shift_expression
4091 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4092 (Expression) $1, (Expression) $3, lexer.Location);
4094 | relational_expression IS shift_expression
4096 //FIXME: Should be a different op for reference equality but allows tests to use Is
4097 $$ = new Binary (Binary.Operator.Equality,
4098 (Expression) $1, (Expression) $3, lexer.Location);
4100 | TYPEOF shift_expression IS type
4102 //FIXME: Is this rule correctly defined ?
4103 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4108 : relational_expression
4109 | NOT negation_expression
4111 //FIXME: Is this rule correctly defined ?
4112 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4116 conditional_and_expression
4117 : negation_expression
4118 | conditional_and_expression AND negation_expression
4120 $$ = new Binary (Binary.Operator.LogicalAnd,
4121 (Expression) $1, (Expression) $3, lexer.Location);
4123 | conditional_and_expression ANDALSO negation_expression
4124 { // FIXME: this is likely to be broken
4125 $$ = new Binary (Binary.Operator.LogicalAnd,
4126 (Expression) $1, (Expression) $3, lexer.Location);
4130 conditional_or_expression
4131 : conditional_and_expression
4132 | conditional_or_expression OR conditional_and_expression
4134 $$ = new Binary (Binary.Operator.LogicalOr,
4135 (Expression) $1, (Expression) $3, lexer.Location);
4137 | conditional_or_expression ORELSE conditional_and_expression
4138 { // FIXME: this is likely to be broken
4139 $$ = new Binary (Binary.Operator.LogicalOr,
4140 (Expression) $1, (Expression) $3, lexer.Location);
4144 conditional_xor_expression
4145 : conditional_or_expression
4146 | conditional_xor_expression XOR conditional_or_expression
4148 $$ = new Binary (Binary.Operator.ExclusiveOr,
4149 (Expression) $1, (Expression) $3, lexer.Location);
4153 assignment_expression
4154 : prefixed_unary_expression ASSIGN expression
4156 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4158 | prefixed_unary_expression STAR ASSIGN expression
4160 Location l = lexer.Location;
4162 $$ = new CompoundAssign (
4163 Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
4165 | prefixed_unary_expression DIV ASSIGN expression
4167 Location l = lexer.Location;
4169 $$ = new CompoundAssign (
4170 Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
4172 | prefixed_unary_expression PLUS ASSIGN expression
4174 Location l = lexer.Location;
4176 $$ = new CompoundAssign (
4177 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4179 | prefixed_unary_expression MINUS ASSIGN expression
4181 Location l = lexer.Location;
4183 $$ = new CompoundAssign (
4184 Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
4186 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
4188 Location l = lexer.Location;
4190 $$ = new CompoundAssign (
4191 Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
4193 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
4195 Location l = lexer.Location;
4197 $$ = new CompoundAssign (
4198 Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
4200 | prefixed_unary_expression OP_CONCAT ASSIGN expression
4202 Location l = lexer.Location;
4204 // FIXME should be strings only
4205 $$ = new CompoundAssign (
4206 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4208 | prefixed_unary_expression OP_EXP ASSIGN expression
4210 Location l = lexer.Location;
4212 /* TODO: $$ = new CompoundAssign (
4213 Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
4215 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4217 ArrayList args = new ArrayList();
4218 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4221 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4222 n.isDelegate = true;
4223 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4236 : namespace_or_type_name
4238 $$ = DecomposeQI ((string) $1, lexer.Location);
4247 ArrayList types = new ArrayList ();
4252 | type_list COMMA type
4254 ArrayList types = (ArrayList) $1;
4261 namespace_or_type_name
4262 : qualified_identifier
4266 : OBJECT { $$ = TypeManager.system_object_expr; }
4272 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4273 | DATE { $$ = TypeManager.system_date_expr; }
4274 | CHAR { $$ = TypeManager.system_char_expr; }
4275 | STRING { $$ = TypeManager.system_string_expr; }
4281 | floating_point_type
4282 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4287 | BYTE { $$ = TypeManager.system_byte_expr; }
4288 | SHORT { $$ = TypeManager.system_int16_expr; }
4289 | INTEGER { $$ = TypeManager.system_int32_expr; }
4290 | LONG { $$ = TypeManager.system_int64_expr; }
4294 : SINGLE { $$ = TypeManager.system_single_expr; }
4295 | DOUBLE { $$ = TypeManager.system_double_expr; }
4299 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4301 if(tokenizerController.IsAcceptingTokens)
4303 if(in_external_source)
4304 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4306 in_external_source = true;
4308 lexer.EffectiveSource = (string) $4;
4309 lexer.EffectiveLine = (int) $6;
4313 | HASH IDENTIFIER LITERAL_STRING EOL
4315 if(tokenizerController.IsAcceptingTokens)
4317 string id = ($2 as string);
4319 if(!($2 as string).ToLower().Equals("region"))
4320 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4327 | HASH END IDENTIFIER EOL
4329 if(tokenizerController.IsAcceptingTokens)
4331 if( ($3 as string).ToLower().Equals("externalsource")) {
4332 if(!in_external_source)
4333 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4335 in_external_source = false;
4336 lexer.EffectiveSource = lexer.Source;
4337 lexer.EffectiveLine = lexer.Line;
4340 else if(($3 as string).ToLower().Equals("region")) {
4341 if(in_marked_region > 0)
4344 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4347 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4351 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4353 if(tokenizerController.IsAcceptingTokens)
4360 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4363 ifElseStateMachine.HandleToken(tok);
4365 catch(ApplicationException) {
4366 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4369 boolean_literal opt_then EOL
4371 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4375 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4377 ifElseStateMachine.HandleToken(tok);
4379 catch(ApplicationException) {
4380 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4383 boolean_literal opt_then EOL
4385 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4389 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4391 ifElseStateMachine.HandleToken(tok);
4393 catch(ApplicationException) {
4394 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4399 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4403 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4405 ifElseStateMachine.HandleToken(tok);
4407 catch(ApplicationException) {
4408 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4413 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4417 if(tokenizerController.IsAcceptingTokens)
4418 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4420 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4430 public Tokenizer Lexer {
4436 public static Expression DecomposeQI (string name, Location loc)
4440 if (name.IndexOf ('.') == -1){
4441 return new SimpleName (name, loc);
4443 int pos = name.LastIndexOf (".");
4444 string left = name.Substring (0, pos);
4445 string right = name.Substring (pos + 1);
4447 o = DecomposeQI (left, loc);
4449 return new MemberAccess (o, right, loc);
4453 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4455 Block implicit_block;
4456 ArrayList inits = null;
4459 // We use the `Used' property to check whether statements
4460 // have been added to the current block. If so, we need
4461 // to create another block to contain the new declaration
4462 // otherwise, as an optimization, we use the same block to
4463 // add the declaration.
4465 // FIXME: A further optimization is to check if the statements
4466 // that were added were added as part of the initialization
4467 // below. In which case, no other statements have been executed
4468 // and we might be able to reduce the number of blocks for
4469 // situations like this:
4471 // int j = 1; int k = j + 1;
4474 VariableDeclaration.FixupTypes (variable_declarators);
4476 if (current_block.Used) {
4477 implicit_block = new Block (current_block, true, loc, Location.Null);
4478 implicit_block.AddChildVariableNames (current_block);
4480 implicit_block = current_block;
4482 foreach (VariableDeclaration decl in variable_declarators){
4483 Expression type = decl.type;
4484 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4485 if (decl.expression_or_array_initializer != null){
4487 inits = new ArrayList ();
4494 return implicit_block;
4496 foreach (VariableDeclaration decl in inits){
4499 Expression type = decl.type;
4501 if ((decl.expression_or_array_initializer is Expression) ||
4502 (decl.expression_or_array_initializer is New)) {
4503 expr = (Expression) decl.expression_or_array_initializer;
4505 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4507 expr = new ArrayCreation (type, "", init, decl.Location);
4510 LocalVariableReference var;
4511 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4513 assign = new Assign (var, expr, decl.Location);
4515 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4518 return implicit_block;
4521 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4523 Block implicit_block;
4524 VariableDeclaration.FixupTypes (variable_declarators);
4526 if (current_block.Used)
4527 implicit_block = new Block (current_block, true);
4529 implicit_block = current_block;
4531 foreach (VariableDeclaration decl in variable_declarators){
4532 Expression type = decl.type;
4533 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4534 current_local_parameters, decl.Location);
4537 return implicit_block;
4545 public VarName (object n, object t, object r)
4555 // A class used to pass around variable declarations and constants
4557 public class VariableDeclaration {
4558 public string identifier;
4559 public object expression_or_array_initializer;
4560 public Location Location;
4561 public Attributes OptAttributes;
4562 public Expression type;
4563 public ArrayList dims;
4565 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4567 this.identifier = id;
4568 this.expression_or_array_initializer = eoai;
4570 this.OptAttributes = opt_attrs;
4575 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4579 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4583 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4584 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4588 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4590 // FIXME : This is broken: only the first rank is parsed
4591 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4594 public static void FixupTypes (ArrayList vars)
4596 int varcount = vars.Count;
4597 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4599 if (last_var.type == null)
4600 last_var.type = TypeManager.system_object_expr;
4602 Expression cur_type = last_var.type;
4603 int n = varcount - 1;
4606 VariableDeclaration var = (VariableDeclaration) vars[n--];
4607 if (var.type == null)
4608 var.type = cur_type;
4610 cur_type = var.type;
4614 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4618 if (IndexList != null) {
4619 foreach (Expression e in IndexList)
4620 if (!(e is EmptyExpression)) {
4629 public static bool IndexesSpecified (ArrayList ranks)
4633 if (ranks != null) {
4634 foreach (ArrayList IndexList in ranks) {
4635 if (IndexesSpecifiedInRank (IndexList)) {
4644 public static string StripDims (string varname, ref string d)
4646 string res = varname;
4649 if (varname.IndexOf("[") >= 0) {
4650 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4651 res = varname.Substring(0, varname.IndexOf("["));
4657 public static string StripDims (string varname)
4661 return (StripDims(varname, ref dres));
4664 public static string StripIndexesFromDims (string dims)
4666 StringBuilder sb = new StringBuilder();
4668 foreach (char c in dims)
4669 if (c == ',' || c == ']' || c == '[')
4672 return sb.ToString();
4675 public static string BuildRank (ArrayList rank)
4678 return BuildRank(rank, out allEmpty);
4681 public static string BuildRank (ArrayList rank, out bool allEmpty)
4688 foreach (object e in rank) {
4689 if (!(e is EmptyExpression))
4700 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
4704 bool allEmpty = true;
4705 foreach (ArrayList rank in rank_specifiers) {
4707 res = BuildRank (rank, out tmp) + res;
4711 if (!allEmpty && mustBeEmpty)
4712 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
4717 public static void VBFixIndexList (ref ArrayList IndexList)
4719 if (IndexList != null) {
4720 for (int x = 0; x < IndexList.Count; x++) {
4721 Expression e = (Expression) IndexList[x];
4722 if (!(e is EmptyExpression)) {
4723 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4729 public static bool IsArrayDecl (Parser t)
4731 // return (varname.IndexOf("[") >= 0);
4732 return (t.current_rank_specifiers != null);
4735 public static void VBFixIndexLists (ref ArrayList ranks)
4737 if (ranks != null) {
4738 for (int x = 0; x < ranks.Count; x++) {
4739 ArrayList IndexList = (ArrayList) ranks[x];
4740 VBFixIndexList (ref IndexList);
4745 public static void FixupArrayTypes (ArrayList vars)
4747 int varcount = vars.Count;
4750 foreach (VariableDeclaration var in vars) {
4751 if (var.identifier.EndsWith(",")) {
4752 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4753 var.identifier.LastIndexOf(",")) + "]";
4754 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4755 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4762 public Property BuildSimpleProperty (Expression p_type, string name,
4763 Field p_fld, int mod_flags,
4764 Attributes attrs, Location loc)
4767 Block get_block, set_block;
4768 Accessor acc_set, acc_get;
4769 StatementExpression a_set;
4774 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4775 args = new Parameter [1];
4776 args [0] = implicit_value_parameter;
4778 Parameters set_params = new Parameters (args, null, loc);
4779 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4780 (Expression) new SimpleName("value", loc), loc), loc);
4782 set_block = new Block (current_block, set_params, loc, Location.Null);
4783 set_block.AddStatement ((Statement) a_set);
4784 acc_set = new Accessor (set_block, attrs);
4787 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4788 get_block = new Block (current_block, null, loc, Location.Null);
4789 get_block.AddStatement ((Statement) a_get);
4790 acc_get = new Accessor (get_block, attrs);
4792 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4799 current_block = new Block (current_block, current_local_parameters,
4800 lexer.Location, Location.Null);
4807 while (current_block.Implicit)
4808 current_block = current_block.Parent;
4810 res = current_block;
4812 current_block.SetEndLocation (lexer.Location);
4813 current_block = current_block.Parent;
4818 private void AddHandler (Expression evt_definition, Expression handler_exp)
4820 AddHandler (current_block, evt_definition, handler_exp);
4823 void CheckAttributeTarget (string a)
4827 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4831 Location l = lexer.Location;
4832 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4837 private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
4839 Expression evt_target;
4840 Location loc = lexer.Location;
4842 Statement addhnd = (Statement) new AddHandler (evt_id,
4846 b.AddStatement (addhnd);
4849 private void RaiseEvent (string evt_name, ArrayList args)
4851 Location loc = lexer.Location;
4853 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4854 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4855 current_block.AddStatement (s);
4858 private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
4860 Expression evt_target;
4861 Location loc = lexer.Location;
4863 Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
4866 b.AddStatement (rmhnd);
4870 // This method is used to get at the complete string representation of
4871 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4872 // This is necessary because local_variable_type admits primary_expression
4873 // as the type of the variable. So we do some extra checking
4875 string GetQualifiedIdentifier (Expression expr)
4877 if (expr is SimpleName)
4878 return ((SimpleName)expr).Name;
4879 else if (expr is MemberAccess)
4880 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4882 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4886 private void RemoveHandler (Expression evt_definition, Expression handler_exp)
4888 RemoveHandler (current_block, evt_definition, handler_exp);
4891 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4893 ConstructorInitializer ci = null;
4896 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4897 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4899 if (i.expr is BaseAccess) {
4900 BaseAccess ba = (BaseAccess) i.expr;
4901 if (ba.member == "New" || ba.member == ".ctor") {
4902 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4906 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4907 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4915 void Error_ExpectingTypeName (Location l, Expression expr)
4917 if (expr is Invocation){
4918 Report.Error (1002, l, "; expected");
4920 Report.Error (-1, l, "Invalid Type definition");
4924 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4928 private void ReportError9998()
4930 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4933 protected override int parse ()
4935 RootContext.InitializeImports(ImportsList);
4936 current_namespace = new Namespace (null, RootContext.RootNamespace);
4937 current_container = RootContext.Tree.Types;
4938 current_container.Namespace = current_namespace;
4939 oob_stack = new Stack ();
4940 switch_stack = new Stack ();
4941 expr_stack = new Stack ();
4942 tmp_blocks = new Stack();
4943 with_stack = new Stack();
4944 statement_stack = new Stack();
4946 UseExtendedSyntax = name.EndsWith(".mbs");
4947 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4948 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4949 OptionCompareBinary = InitialOptionCompareBinary;
4951 lexer = new Tokenizer (input, name, defines);
4953 ifElseStateMachine = new IfElseStateMachine();
4954 tokenizerController = new TokenizerController(lexer);
4956 StringBuilder value = new StringBuilder ();
4958 if (yacc_verbose_flag)
4959 yyparse (lexer, new yydebug.yyDebugSimple ());
4965 catch(MBASException e) {
4966 Report.Error(e.code, e.loc, e.Message);
4968 catch (Exception e) {
4969 if (Report.Stacktrace)
4970 Console.WriteLine(e);
4971 Report.Error (29999, lexer.Location, "Parsing error");
4974 RootContext.VerifyImports();
4976 return Report.Errors;
4982 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
4984 catch(ApplicationException) {
4985 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4988 if(in_external_source)
4989 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
4991 if(in_marked_region > 0)
4992 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
4995 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
4998 tokenizerController.PositionTokenizerCursor(tok, expr);
5000 catch(ApplicationException) {
5001 tok = IfElseStateMachine.Token.EOF;
5003 ifElseStateMachine.HandleToken(tok);
5005 catch(ApplicationException) {
5006 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);