3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
5 // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
7 // Licensed under the terms of the GNU GPL
9 // Copyright (C) 2001 A Rafael D Teixeira
15 namespace Mono.MonoBASIC
19 using System.Reflection;
20 using System.Collections;
24 public class MBASException : ApplicationException
29 public MBASException(int code, Location loc, string text) : base(text)
37 /// The MonoBASIC Parser
40 public class Parser : GenericParser
45 /// Current block is used to add statements as we find
51 /// Tmp block is used to store block endings in if/select's
56 /// Tmp block is used to store tmp copies of expressions
61 /// Tmp catch is used to store catch clauses in try..catch..finally
63 ArrayList tmp_catch_clauses;
66 /// Current interface is used by the various declaration
67 /// productions in the interface declaration to "add"
68 /// the interfaces as we find them.
70 Interface current_interface;
73 /// This is used by the unary_expression code to resolve
74 /// a name against a parameter.
76 Parameters current_local_parameters;
79 /// This are used when parsing parameters in property
82 Parameters set_parameters;
83 Parameters get_parameters;
86 /// This is used by the sub_header parser to store modifiers
87 /// to be passed to sub/constructor
89 int current_modifiers;
92 /// This is used by the sub_header parser to store attributes
93 /// to be passed to sub/constructor
95 Attributes current_attributes;
98 /// Using during property parsing to describe the implicit
99 /// value parameter that is passed to the "set" accessor
102 string get_implicit_value_parameter_name;
105 // Using during property parsing to describe the implicit
106 // value parameter that is passed to the "set" and "get"accesor
107 // methods (properties and indexers).
109 Expression get_implicit_value_parameter_type;
112 /// Using during property parsing to describe the implicit
113 /// value parameter that is passed to the "set" accessor
116 string set_implicit_value_parameter_name;
119 // Using during property parsing to describe the implicit
120 // value parameter that is passed to the "set" and "get"accesor
121 // methods (properties and indexers).
123 Expression set_implicit_value_parameter_type;
125 Location member_location;
127 // An out-of-band stack.
131 ArrayList current_rank_specifiers;
139 // Expression stack for nested ifs
143 Stack statement_stack;
145 // A stack for With expressions.
150 static public bool InitialOptionExplicit = false;
151 static public bool InitialOptionStrict = false;
152 static public bool InitialOptionCompareBinary = true;
153 static public ArrayList ImportsList = null;
157 bool OptionCompareBinary;
159 static public bool UseExtendedSyntax; // for ".mbs" files
161 bool implicit_modifiers;
163 public override string[] extensions()
165 string [] list = { ".vb", ".mbs" };
169 bool in_external_source = false;
170 int in_marked_region = 0;
172 TokenizerController tokenizerController;
173 IfElseStateMachine ifElseStateMachine;
176 public class IfElseStateMachine {
200 public static Hashtable errStrings = new Hashtable();
203 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
205 static IfElseStateMachine()
207 // FIXME: Fix both the error nos and the error strings.
208 // Currently the error numbers and the error strings are
209 // just placeholders for getting the state-machine going.
211 errStrings.Add(0, "");
212 errStrings.Add(30012, "#If must end with a matching #End If");
213 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
214 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
215 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
216 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
218 errTable[(int)State.START, (int)Token.IF] = 0;
219 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
220 errTable[(int)State.START, (int)Token.ELSE] = 30028;
221 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
222 errTable[(int)State.START, (int)Token.EOF] = 0;
224 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
225 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
226 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
227 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
228 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
230 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
231 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
232 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
233 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
234 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
236 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
237 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
238 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
239 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
240 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
242 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
243 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
244 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
245 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
246 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
249 public IfElseStateMachine()
253 stateStack = new Stack();
254 stateStack.Push(state);
257 // The parameter here need not be qualified with IfElseStateMachine
258 // But it hits a bug in mcs. So temporarily scoping it so that builds
261 public void HandleToken(IfElseStateMachine.Token tok)
263 err = (int) errTable[(int)state, (int)tok];
266 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
268 if(tok == Token.IF) {
269 stateStack.Push(state);
272 else if(tok == Token.ENDIF) {
273 state = (State)stateStack.Pop();
285 public string ErrString {
287 return (string) errStrings[err];
293 public class TokenizerController {
297 public bool CanAcceptTokens;
298 public bool CanSelectBlock;
306 public TokenizerController(Tokenizer lexer)
309 stateStack = new Stack();
311 currentState.CanAcceptTokens = true;
312 currentState.CanSelectBlock = true;
314 stateStack.Push(currentState);
319 return (State)stateStack.Peek();
323 public bool IsAcceptingTokens {
325 return currentState.CanAcceptTokens;
329 public void PositionCursorAtNextPreProcessorDirective()
331 lexer.PositionCursorAtNextPreProcessorDirective();
334 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
336 if(tok == IfElseStateMachine.Token.ENDIF) {
337 currentState = (State)stateStack.Pop();
339 if(currentState.CanAcceptTokens)
342 PositionCursorAtNextPreProcessorDirective();
347 if(tok == IfElseStateMachine.Token.IF) {
348 stateStack.Push(currentState);
350 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
351 currentState.CanSelectBlock = true;
354 if(parentState.CanAcceptTokens &&
355 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
357 currentState.CanAcceptTokens = true;
358 currentState.CanSelectBlock = false;
362 currentState.CanAcceptTokens = false;
363 PositionCursorAtNextPreProcessorDirective();
371 %token NONE /* This token is never returned by our lexer */
372 %token ERROR // This is used not by the parser, but by the tokenizer.
376 *These are the MonoBASIC keywords
465 %token NOTINHERITABLE
466 %token NOTOVERRIDABLE
521 %token YIELD // MonoBASIC extension
525 /* MonoBASIC single character operators/punctuation. */
527 %token OPEN_BRACKET "["
528 %token CLOSE_BRACKET "]"
529 %token OPEN_PARENS "("
530 %token OPEN_BRACE "{"
531 %token CLOSE_BRACE "}"
532 %token CLOSE_PARENS ")"
548 %token EXCLAMATION "!"
551 %token LONGTYPECHAR "&"
553 %token SINGLETYPECHAR "!"
554 %token NUMBER_SIGN "#"
555 %token DOLAR_SIGN "$"
557 %token ATTR_ASSIGN ":="
559 /* MonoBASIC multi-character operators. */
564 //%token OP_MODULUS //"mod"
565 %token OP_MULT_ASSIGN "*="
566 %token OP_DIV_ASSIGN "/="
567 %token OP_IDIV_ASSIGN "\\="
568 %token OP_ADD_ASSIGN "+="
569 %token OP_SUB_ASSIGN "-="
570 %token OP_CONCAT_ASSIGN "&="
571 %token OP_EXP_ASSIGN "^="
573 /* VB.NET 2003 new bit-shift operators */
574 %token OP_SHIFT_LEFT "<<"
575 %token OP_SHIFT_RIGHT ">>"
578 %token LITERAL_INTEGER "int literal"
579 %token LITERAL_SINGLE "float literal"
580 %token LITERAL_DOUBLE "double literal"
581 %token LITERAL_DECIMAL "decimal literal"
582 %token LITERAL_CHARACTER "character literal"
583 %token LITERAL_STRING "string literal"
584 %token LITERAL_DATE "datetime literal"
588 /* Add precedence rules to solve dangling else s/r conflict */
597 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
599 %left STAR DIV PERCENT
600 %right BITWISE_NOT CARRET UMINUS
601 %nonassoc OP_INC OP_DEC
603 %left OPEN_BRACKET OPEN_BRACE
608 %start compilation_unit
612 : logical_end_of_line
618 | logical_end_of_line pp_directive
621 opt_logical_end_of_line
623 | logical_end_of_line
627 : logical_end_of_line
628 opt_option_directives
629 opt_imports_directives
639 opt_option_directives
646 | option_directives option_directive
650 : option_explicit_directive
651 | option_strict_directive
652 | option_compare_directive
681 option_explicit_directive
682 : OPTION EXPLICIT on_off logical_end_of_line
684 if (!UseExtendedSyntax)
685 OptionExplicit = (bool)$3;
688 9999, lexer.Location,
689 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
694 option_strict_directive
695 : OPTION STRICT on_off logical_end_of_line
697 if (!UseExtendedSyntax)
698 OptionStrict = (bool)$3;
701 9999, lexer.Location,
702 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
706 option_compare_directive
707 : OPTION COMPARE text_or_binary logical_end_of_line
709 OptionCompareBinary = (bool)$3;
720 | declarations declaration
724 : namespace_declaration
730 if ($1 is Class || $1 is Struct || $1 is Module ){
731 TypeContainer c = (TypeContainer) $1;
732 mod_flags = c.ModFlags;
737 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
739 1527, lexer.Location,
740 "Namespace elements cannot be explicitly " +
741 "declared private or protected in '" + name + "'");
756 : PERCENT { $$ = TypeManager.system_int32_expr; }
757 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
758 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
759 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
760 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
761 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
765 : /* empty */ { $$ = null; }
766 | type_character { $$ = $1; }
772 | qualified_identifier DOT identifier
774 $$ = (($1).ToString ()) + "." + ($3.ToString ());
778 opt_imports_directives
785 | imports_directives imports_directive
789 : IMPORTS imports_terms logical_end_of_line
794 | imports_terms COMMA imports_terms
798 : qualified_identifier
800 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
802 | qualified_identifier ASSIGN qualified_identifier
804 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
809 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
810 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
811 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
816 | attribute_sections { $$ = $1; }
822 AttributeSection sect = (AttributeSection) $1;
824 if (sect.Target == "assembly")
825 RootContext.AddGlobalAttributeSection (current_container, sect);
827 $$ = new Attributes ((AttributeSection) $1, lexer.Location);
831 FIXME: we should check if extended syntax is enabled;
832 otherwise an exception should be thrown since VB.NET
833 only allows one attribute section
835 | attribute_sections attribute_section
837 Attributes attrs = null;
838 AttributeSection sect = (AttributeSection) $2;
840 if (sect.Target == "assembly")
841 RootContext.AddGlobalAttributeSection (current_container, sect);
844 attrs = (Attributes) $1;
845 attrs.AddAttributeSection (sect);
853 : OP_LT attribute_target_specifier attribute_list OP_GT
855 string target = null;
858 target = (string) $2;
860 $$ = new AttributeSection (target, (ArrayList) $3);
862 | OP_LT attribute_list OP_GT
864 $$ = new AttributeSection (null, (ArrayList) $2);
868 attribute_target_specifier
869 : attribute_target COLON
878 CheckAttributeTarget ((string) $1);
881 | EVENT { $$ = "event"; }
882 | RETURN { $$ = "return"; }
888 ArrayList attrs = new ArrayList ();
894 | attribute_list COMMA attribute
896 ArrayList attrs = (ArrayList) $1;
908 opt_attribute_arguments
910 $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
918 opt_attribute_arguments
919 : /* empty */ { $$ = null; }
920 | OPEN_PARENS attribute_arguments CLOSE_PARENS
927 : opt_positional_argument_list
932 ArrayList args = new ArrayList ();
938 | positional_argument_list COMMA named_argument_list
940 ArrayList args = new ArrayList ();
946 | named_argument_list
948 ArrayList args = new ArrayList ();
957 opt_positional_argument_list
958 : /* empty */ { $$ = null; }
959 | positional_argument_list
962 positional_argument_list
965 ArrayList args = new ArrayList ();
966 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
970 | positional_argument_list COMMA expression
972 ArrayList args = (ArrayList) $1;
973 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
982 ArrayList args = new ArrayList ();
987 | named_argument_list COMMA named_argument
989 ArrayList args = (ArrayList) $1;
997 : identifier ATTR_ASSIGN expression
999 $$ = new DictionaryEntry (
1001 new Argument ((Expression) $3, Argument.AType.Expression));
1005 namespace_declaration
1006 : opt_attributes NAMESPACE qualified_identifier logical_end_of_line
1008 Attributes attrs = (Attributes) $1;
1010 if (attrs != null) {
1011 foreach (AttributeSection asec in attrs.AttributeSections)
1012 if (asec.Target == "assembly")
1013 RootContext.AddGlobalAttributeSection (current_container, asec);
1016 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
1018 opt_imports_directives
1020 END NAMESPACE logical_end_of_line
1022 current_namespace = current_namespace.Parent;
1030 current_attributes = (Attributes) $1;
1031 current_modifiers = (int) $2;
1033 type_spec_declaration
1036 type_spec_declaration
1038 | module_declaration
1039 | interface_declaration
1040 | delegate_declaration
1041 | struct_declaration
1046 : CLASS identifier logical_end_of_line opt_inherits opt_implements
1048 // Module members are static by default, but Class *can't* be declared static
1049 // so we must fix it, if mbas was the one actually responsible for this
1050 // instead of triggering an error.
1051 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1052 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1057 name = MakeName ((string) $2);
1058 new_class = new Class (current_container, name, current_modifiers,
1059 (Attributes) current_attributes, lexer.Location);
1061 current_container = new_class;
1062 current_container.Namespace = current_namespace;
1063 RootContext.Tree.RecordDecl (name, new_class);
1065 opt_class_member_declarations
1066 END CLASS logical_end_of_line
1068 Class new_class = (Class) current_container;
1069 new_class.Bases = (ArrayList) $4;
1071 current_container = current_container.Parent;
1072 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
1079 : /* empty */ { $$ = null; }
1080 | INHERITS type_list logical_end_of_line { $$ = $2; }
1084 : /* empty */ { $$ = null; }
1085 | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
1089 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
1090 | modifiers { $$ = $1; current_modifiers = (int) $1; }
1095 | modifiers modifier
1100 if ((m1 & m2) != 0) {
1101 Location l = lexer.Location;
1102 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1104 $$ = (int) (m1 | m2);
1109 : PUBLIC { $$ = Modifiers.PUBLIC; }
1110 | PROTECTED { $$ = Modifiers.PROTECTED; }
1111 | PRIVATE { $$ = Modifiers.PRIVATE; }
1112 | SHARED { $$ = Modifiers.STATIC; }
1113 | FRIEND { $$ = Modifiers.INTERNAL; }
1114 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1115 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1116 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1117 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1118 | OVERLOADS { $$ = Modifiers.NEW; }
1119 | SHADOWS { $$ = Modifiers.SHADOWS; }
1120 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1121 | READONLY { $$ = Modifiers.READONLY; }
1122 | DEFAULT { $$ = Modifiers.DEFAULT; }
1123 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1127 : MODULE identifier logical_end_of_line
1131 name = MakeName((string) $2);
1132 new_module = new Module(current_container,
1134 current_modifiers, // already checks then
1135 (Attributes) current_attributes,
1137 current_container = new_module;
1138 current_container.Namespace = current_namespace;
1139 RootContext.Tree.RecordDecl(name, new_module);
1141 opt_module_member_declarations
1142 END MODULE logical_end_of_line
1144 Module new_module = (Module)current_container;
1146 current_container = current_container.Parent;
1147 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
1149 TypeManager.AddStandardModule(new_module);
1155 opt_module_member_declarations
1157 | module_member_declarations
1160 module_member_declarations
1161 : module_member_declaration
1162 | module_member_declarations module_member_declaration
1165 module_member_declaration
1169 current_attributes = (Attributes) $1;
1170 current_modifiers = ((int)$2) | Modifiers.STATIC;
1171 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1172 implicit_modifiers = (!explicit_static);
1174 module_member_declarator
1176 implicit_modifiers = false;
1181 module_member_declarator
1182 : constructor_declaration
1183 | method_declaration
1185 Method method = (Method) $1;
1186 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1189 | withevents_declaration /* This is a field but must be treated specially, see below */
1190 | constant_declaration
1191 | property_declaration
1193 | type_spec_declaration
1196 constant_declaration
1197 : CONST constant_declarators logical_end_of_line
1199 // Module members are static by default, but constants *can't* be declared static
1200 // so we must fix it, if mbas was the one actually responsible for this
1201 // instead of triggering an error.
1202 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1203 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1205 int mod = (int) current_modifiers;
1207 // Structure members are Public by default
1208 if ((current_container is Struct) && (mod == 0))
1209 mod = Modifiers.PUBLIC;
1211 ArrayList consts = (ArrayList) $2;
1212 if(consts.Count > 0)
1214 VariableDeclaration.FixupTypes ((ArrayList) $2);
1215 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1217 foreach (VariableDeclaration var in (ArrayList) $2){
1218 Location l = var.Location;
1219 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
1220 (Expression)var.expression_or_array_initializer,
1221 mod, (Attributes) null, l);
1223 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
1229 opt_class_member_declarations
1231 | class_member_declarations
1234 class_member_declarations
1235 : class_member_declaration
1236 | class_member_declarations class_member_declaration
1239 class_member_declaration
1243 current_attributes = (Attributes) $1;
1244 current_modifiers = (int) $2;
1246 class_member_declarator
1252 class_member_declarator
1253 : constructor_declaration
1254 | method_declaration
1256 Method method = (Method) $1;
1257 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1260 | constant_declaration
1261 | property_declaration
1263 | withevents_declaration /* This is a field but must be treated specially, see below */
1264 | type_spec_declaration
1271 | must_override_declaration
1274 must_override_declaration
1275 : must_override_sub_declaration
1276 | must_override_func_declaration
1279 must_override_sub_declaration
1280 : MUSTOVERRIDE SUB identifier opt_params logical_end_of_line
1282 if (current_container is Module)
1283 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1285 if (current_container is Struct)
1286 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1288 current_modifiers |= Modifiers.ABSTRACT;
1290 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1291 (Parameters) $4, null, null, lexer.Location);
1293 if (!(current_container is Class))
1294 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1301 must_override_func_declaration
1302 : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
1304 Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.
1305 system_object_expr : (Expression) $4 ) : (Expression) $6;
1307 if (current_container is Module)
1308 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1310 if (current_container is Struct)
1311 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1313 current_modifiers |= Modifiers.ABSTRACT;
1315 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1316 (string) $3,(Parameters) $5, null, null,
1319 if (!(current_container is Class))
1320 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1327 : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
1329 current_local_parameters = (Parameters) $3;
1332 // Structure members are Public by default
1333 if ((current_container is Struct) && (current_modifiers == 0))
1334 current_modifiers = Modifiers.PUBLIC;
1336 member_location = lexer.Location;
1339 END SUB logical_end_of_line
1341 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1342 (Parameters) current_local_parameters, (Attributes) current_attributes,
1343 (Expression) $5, member_location);
1345 method.Block = (Block) end_block();
1349 // we have an event handler to take care of
1351 string evt_def = ((MemberAccess)$6).ToString();
1352 int pos = evt_def.LastIndexOf (".");
1353 string evt_target = evt_def.Substring (0, pos);
1356 if (current_container.Properties != null) {
1357 foreach (Property p in current_container.Properties) {
1358 if (p.Name == evt_target) {
1359 Location loc = lexer.Location;
1361 Statement addhnd = (Statement) new AddHandler ((Expression) $4,
1362 DecomposeQI((string) $2, loc),
1363 DecomposeQI(evt_target, loc), loc);
1365 current_container.AddEventHandler (addhnd);
1373 Report.Error(30506, lexer.Location,
1374 evt_target + " is not declared with WithEvents");
1381 : FUNCTION identifier opt_type_character
1382 opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1384 current_local_parameters = (Parameters) $4;
1385 member_location = lexer.Location;
1388 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1390 // Structure members are Public by default
1391 if ((current_container is Struct) && (current_modifiers == 0))
1392 current_modifiers = Modifiers.PUBLIC;
1393 // Add local var declaration
1395 ArrayList retval = new ArrayList ();
1396 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1397 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1400 END FUNCTION logical_end_of_line
1402 Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1404 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1405 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1406 (Expression) $6, member_location);
1407 method.Block = end_block();
1413 : STRUCTURE identifier logical_end_of_line
1414 opt_implement_clause
1417 string full_struct_name = MakeName ((string) $2);
1419 // Module members are static by default, but structures *can't* be declared static
1420 // so we must fix it, if mbas was the one actually responsible for this
1421 // instead of triggering an error.
1422 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1423 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1425 new_struct = new Struct (current_container, full_struct_name,
1426 (int) current_modifiers,
1427 (Attributes) current_attributes, lexer.Location);
1428 current_container = new_struct;
1429 current_container.Namespace = current_namespace;
1430 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1432 opt_struct_member_declarations
1434 Struct new_struct = (Struct) current_container;
1437 new_struct.Bases = (ArrayList) $4;
1439 current_container = current_container.Parent;
1440 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1443 END STRUCTURE logical_end_of_line
1446 opt_struct_member_declarations
1448 | struct_member_declarations
1451 struct_member_declarations
1452 : struct_member_declaration
1453 | struct_member_declarations struct_member_declaration
1456 struct_member_declaration
1458 struct_member_declarator
1461 struct_member_declarator
1463 | constant_declaration
1464 | constructor_declaration
1465 | method_declaration
1467 Method method = (Method) $1;
1468 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1470 | property_declaration
1472 | type_spec_declaration
1475 * This is only included so we can flag error 575:
1476 * destructors only allowed on class types
1478 //| destructor_declaration
1482 : EVENT identifier AS type logical_end_of_line
1484 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1486 Event e = new Event ((Expression) $4, var.identifier,
1487 null, current_modifiers, null, null,
1488 current_attributes, lexer.Location);
1490 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1493 | EVENT identifier opt_params logical_end_of_line
1495 string delName = (string) $2;
1496 delName = delName + "EventHandler";
1497 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1498 (current_container, TypeManager.system_void_expr,
1499 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1500 (Attributes) current_attributes, lexer.Location);
1502 del.Namespace = current_namespace;
1503 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1505 Event e = new Event (DecomposeQI (delName, lexer.Location),
1507 null, current_modifiers, null, null,
1508 current_attributes, lexer.Location);
1510 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1515 : ENUM identifier opt_type_spec logical_end_of_line
1516 opt_enum_member_declarations
1518 Location enum_location = lexer.Location;
1519 string full_name = MakeName ((string) $2);
1520 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1521 ArrayList enum_members = (ArrayList) $5;
1523 // Module members are static by default, but enums *can't* be declared static
1524 // so we must fix it if mbas was the one actually responsible for this
1525 // instead of triggering an error.
1526 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1527 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1529 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1530 (int) current_modifiers, full_name,
1531 (Attributes) current_attributes, enum_location);
1533 foreach (VariableDeclaration ev in enum_members) {
1534 Location loc = (Location) ev.Location;
1536 CheckDef (e.AddEnumMember (ev.identifier,
1537 (Expression) ev.expression_or_array_initializer,
1538 loc, ev.OptAttributes), ev.identifier, loc);
1541 e.Namespace = current_namespace;
1543 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1544 RootContext.Tree.RecordDecl (full_name, e);
1547 END ENUM logical_end_of_line
1550 opt_enum_member_declarations
1551 : /* empty */ { $$ = new ArrayList (); }
1552 | enum_member_declarations { $$ = $1; }
1555 enum_member_declarations
1556 : enum_member_declaration
1558 ArrayList l = new ArrayList ();
1563 | enum_member_declarations enum_member_declaration
1565 ArrayList l = (ArrayList) $1;
1573 enum_member_declaration
1574 : opt_attributes identifier logical_end_of_line
1576 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1578 | opt_attributes identifier
1580 $$ = lexer.Location;
1582 ASSIGN expression logical_end_of_line
1584 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1588 interface_declaration
1589 : INTERFACE identifier logical_end_of_line
1591 Interface new_interface;
1592 string full_interface_name = MakeName ((string) $2);
1594 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1595 (Attributes) current_attributes, lexer.Location);
1596 if (current_interface != null) {
1597 Location l = lexer.Location;
1598 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1600 current_interface = new_interface;
1601 new_interface.Namespace = current_namespace;
1602 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1607 Interface new_interface = (Interface) current_interface;
1610 new_interface.Bases = (ArrayList) $5;
1612 current_interface = null;
1613 CheckDef (current_container.AddInterface (new_interface),
1614 new_interface.Name, new_interface.Location);
1617 END INTERFACE logical_end_of_line
1621 : /* empty */ { $$ = null; }
1626 : INHERITS interface_type_list { $$ = $2; }
1632 ArrayList interfaces = new ArrayList ();
1634 interfaces.Add ($1);
1637 | interface_type_list COMMA interface_type
1639 ArrayList interfaces = (ArrayList) $1;
1640 interfaces.Add ($3);
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
1660 : interface_method_declaration
1662 InterfaceMethod m = (InterfaceMethod) $1;
1664 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1666 | interface_property_declaration
1668 InterfaceProperty p = (InterfaceProperty) $1;
1670 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1672 | interface_event_declaration
1674 InterfaceEvent e = (InterfaceEvent) $1;
1676 CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1681 : /* empty */ { $$ = false; }
1682 | NEW { $$ = true; }
1685 interface_method_declaration
1687 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS logical_end_of_line
1689 $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
1690 (Parameters) $4, current_attributes, lexer.Location);
1692 | FUNCTION identifier opt_type_character
1693 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
1695 if ($3 != null && $3 != $8)
1696 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
1698 $$ = new InterfaceMethod (
1699 (Expression) $8, (string) $2, false, (Parameters) $5,
1700 current_attributes, lexer.Location);
1702 | FUNCTION identifier type_character
1703 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1705 $$ = new InterfaceMethod (
1706 (Expression) $3, (string) $2, false, (Parameters) $5,
1707 current_attributes, lexer.Location);
1711 interface_property_declaration
1712 : opt_modifiers PROPERTY identifier
1714 opt_formal_parameter_list
1715 CLOSE_PARENS opt_type_spec logical_end_of_line
1717 // FIXME we MUST pass property parameters
1718 $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
1719 true, true, current_attributes,
1724 interface_event_declaration
1725 : opt_attributes opt_new EVENT type identifier logical_end_of_line
1727 $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
1732 property_declaration
1733 : abstruct_propery_declaration
1734 | non_abstruct_propery_declaration
1737 abstruct_propery_declaration
1738 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters AS type logical_end_of_line
1740 Expression ftype = ($7 == null) ? (($4 == null) ?
1741 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $7;
1743 if (current_container is Module)
1744 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1746 if (current_container is Struct)
1747 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1749 current_modifiers |= Modifiers.ABSTRACT;
1751 current_local_parameters = (Parameters) $5;
1752 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1753 get_parameters = current_local_parameters.Copy (lexer.Location);
1754 set_parameters = current_local_parameters.Copy (lexer.Location);
1758 get_parameters = Parameters.EmptyReadOnlyParameters;
1759 set_parameters = new Parameters (null, null ,lexer.Location);
1761 Parameter implicit_value_parameter = new Parameter (
1762 ftype, "Value", Parameter.Modifier.NONE, null);
1764 set_parameters.AppendParameter (implicit_value_parameter);
1766 lexer.PropertyParsing = true;
1768 Accessor get_block = new Accessor (null, null);
1769 Accessor set_block = new Accessor (null, null);
1771 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1772 get_block, set_block, current_attributes, lexer.Location,
1773 null, get_parameters, set_parameters, null);
1775 if (!(current_container is Class))
1776 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1778 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1780 get_implicit_value_parameter_type = null;
1781 set_implicit_value_parameter_type = null;
1782 get_parameters = null;
1783 set_parameters = null;
1784 current_local_parameters = null;
1789 non_abstruct_propery_declaration
1790 : PROPERTY identifier opt_type_character opt_property_parameters AS type opt_implement_clause logical_end_of_line
1792 get_implicit_value_parameter_type =
1793 ($6 == null) ? (($3 == null) ?
1794 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
1795 get_implicit_value_parameter_name = (string) $2;
1797 current_local_parameters = (Parameters) $4;
1798 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1799 get_parameters = current_local_parameters.Copy (lexer.Location);
1800 set_parameters = current_local_parameters.Copy (lexer.Location);
1804 get_parameters = Parameters.EmptyReadOnlyParameters;
1805 set_parameters = new Parameters (null, null ,lexer.Location);
1807 lexer.PropertyParsing = true;
1809 $$ = lexer.Location;
1811 accessor_declarations
1812 END PROPERTY logical_end_of_line
1814 lexer.PropertyParsing = false;
1817 Pair pair = (Pair) $10;
1819 Accessor get_block = null;
1820 Accessor set_block = null;
1822 if (pair.First != null){
1823 get_block = (Accessor) pair.First;
1826 if (pair.Second != null) {
1827 set_block = (Accessor) pair.Second;
1830 Location loc = lexer.Location;
1832 // Structure members are Public by default
1833 if ((current_container is Struct) && (current_modifiers == 0))
1834 current_modifiers = Modifiers.PUBLIC;
1836 prop = new Property ((Expression) /*$6*/ get_implicit_value_parameter_type,
1837 (string) $2, current_modifiers, get_block, set_block,
1838 current_attributes, loc, set_implicit_value_parameter_name,
1839 get_parameters, set_parameters, (Expression) $7);
1841 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1842 get_implicit_value_parameter_type = null;
1843 set_implicit_value_parameter_type = null;
1844 get_parameters = null;
1845 set_parameters = null;
1846 current_local_parameters = null;
1850 opt_property_parameters
1853 $$ = Parameters.EmptyReadOnlyParameters;
1855 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1861 opt_implement_clause
1866 | IMPLEMENTS qualified_identifier
1868 $$ = DecomposeQI ((string)$2, lexer.Location);
1872 accessor_declarations
1873 : get_accessor_declaration opt_set_accessor_declaration
1875 $$ = new Pair ($1, $2);
1877 | set_accessor_declaration opt_get_accessor_declaration
1879 $$ = new Pair ($2, $1);
1883 opt_get_accessor_declaration
1884 : /* empty */ { $$ = null; }
1885 | get_accessor_declaration
1888 opt_set_accessor_declaration
1889 : /* empty */ { $$ = null; }
1890 | set_accessor_declaration
1893 get_accessor_declaration
1894 : opt_attributes GET logical_end_of_line
1896 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
1897 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
1899 current_local_parameters = get_parameters;
1901 lexer.PropertyParsing = false;
1904 // Add local var declaration
1906 ArrayList retval = new ArrayList ();
1907 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1908 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1911 END GET logical_end_of_line
1913 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1914 current_local_parameters = null;
1915 lexer.PropertyParsing = true;
1919 set_accessor_declaration
1920 : opt_attributes SET opt_set_parameter logical_end_of_line
1922 if ((current_modifiers & Modifiers.READONLY) != 0)
1923 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
1925 Parameter implicit_value_parameter = new Parameter (
1926 set_implicit_value_parameter_type,
1927 set_implicit_value_parameter_name,
1928 Parameter.Modifier.NONE, null);
1930 current_local_parameters = set_parameters;
1931 current_local_parameters.AppendParameter (implicit_value_parameter);
1934 lexer.PropertyParsing = false;
1937 END SET logical_end_of_line
1939 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1940 current_local_parameters = null;
1941 lexer.PropertyParsing = true;
1948 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
1949 set_implicit_value_parameter_name = "Value";
1951 |OPEN_PARENS CLOSE_PARENS
1953 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
1954 set_implicit_value_parameter_name = "Value";
1956 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_spec CLOSE_PARENS
1958 Parameter.Modifier pm = (Parameter.Modifier)$2;
1959 if ((pm | Parameter.Modifier.VAL) != 0)
1960 Report.Error (31065,
1962 "Set cannot have a paremeter modifier other than 'ByVal'");
1964 set_implicit_value_parameter_type = (Expression) $4;
1966 if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
1967 Report.Error (31064,
1969 "Set value parameter type can not be different from property type");
1972 set_implicit_value_parameter_name = (string) $3;
1974 set_implicit_value_parameter_name = "Value";
1980 variable_declarators logical_end_of_line
1982 int mod = (int) current_modifiers;
1985 VariableDeclaration.FixupTypes ((ArrayList) $2);
1986 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1988 if (current_container is Module)
1989 mod = mod | Modifiers.STATIC;
1991 // Structure members are Public by default
1992 if ((current_container is Struct) && (mod == 0))
1993 mod = Modifiers.PUBLIC;
1995 if ((mod & Modifiers.Accessibility) == 0)
1996 mod |= Modifiers.PRIVATE;
1998 foreach (VariableDeclaration var in (ArrayList) $2){
1999 Location l = var.Location;
2000 Field field = new Field (var.type, mod, var.identifier,
2001 var.expression_or_array_initializer,
2002 (Attributes) null, l);
2004 CheckDef (current_container.AddField (field), field.Name, l);
2009 withevents_declaration
2010 : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2012 // Module members are static by default, but delegates *can't* be declared static
2013 // so we must fix it, if mbas was the one actually responsible for this
2014 // instead of triggering an error.
2015 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2016 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2018 /* WithEvents Fields must be resolved into properties
2019 with a bit of magic behind the scenes */
2021 VariableDeclaration.FixupTypes ((ArrayList) $3);
2023 foreach (VariableDeclaration var in (ArrayList) $3) {
2024 // 1 - We create a private field
2025 Location l = var.Location;
2027 if ((current_modifiers & Modifiers.STATIC) > 0)
2028 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2030 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2031 var.expression_or_array_initializer,
2032 (Attributes) null, l);
2034 CheckDef (current_container.AddField (field), field.Name, l);
2036 // 2 - Public property
2038 prop = BuildSimpleProperty (var.type, (string) var.identifier,
2039 field, (int) current_modifiers,
2040 (Attributes) current_attributes, l);
2042 CheckDef (current_container.AddProperty (prop), prop.Name, l);
2052 delegate_declaration
2054 identifier OPEN_PARENS
2055 opt_formal_parameter_list
2059 Location l = lexer.Location;
2060 // Module members are static by default, but delegates *can't* be declared static
2061 // so we must fix it, if mbas was the one actually responsible for this
2062 // instead of triggering an error.
2063 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2064 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2066 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
2067 TypeManager.system_void_expr,
2068 (int) current_modifiers,
2069 MakeName ((string) $3), (Parameters) $5,
2070 (Attributes) current_attributes, l);
2072 del.Namespace = current_namespace;
2073 CheckDef (current_container.AddDelegate (del), del.Name, l);
2076 identifier OPEN_PARENS
2077 opt_formal_parameter_list
2078 CLOSE_PARENS opt_type_spec logical_end_of_line
2080 Location l = lexer.Location;
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 Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2090 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
2092 ftype, (int) current_modifiers, MakeName ((string) $3),
2093 (Parameters) $5, (Attributes) current_attributes, l);
2095 del.Namespace = current_namespace;
2096 CheckDef (current_container.AddDelegate (del), del.Name, l);
2103 | HANDLES qualified_identifier
2105 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
2107 | HANDLES MYBASE DOT qualified_identifier
2109 // FIXME: this is blatantly wrong and crash-prone
2110 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2116 | OPEN_PARENS CLOSE_PARENS
2119 constructor_declaration
2120 : SUB NEW opt_params logical_end_of_line
2122 current_local_parameters = (Parameters) $3;
2124 oob_stack.Push (lexer.Location);
2126 Location l = (Location) oob_stack.Pop ();
2127 $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
2132 Constructor c = (Constructor) $1;
2133 c.Block = (Block) end_block();
2134 c.ModFlags = (int) current_modifiers;
2135 c.OptAttributes = current_attributes;
2137 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2139 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
2140 current_local_parameters = null;
2142 END SUB logical_end_of_line
2145 opt_formal_parameter_list
2148 $$ = Parameters.EmptyReadOnlyParameters;
2150 | formal_parameter_list
2153 //Parameter p = ((Parameters) $1).FixedParameters[0];
2157 formal_parameter_list
2160 ArrayList pars_list = (ArrayList) $1;
2162 Parameter [] pars = new Parameter [pars_list.Count];
2163 pars_list.CopyTo (pars);
2164 $$ = new Parameters (pars, null, lexer.Location);
2166 | fixed_parameters COMMA parameter_array
2168 ArrayList pars_list = (ArrayList) $1;
2170 Parameter [] pars = new Parameter [pars_list.Count];
2171 pars_list.CopyTo (pars);
2173 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
2177 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
2184 ArrayList pars = new ArrayList ();
2189 | fixed_parameters COMMA fixed_parameter
2191 ArrayList pars = (ArrayList) $1;
2200 opt_parameter_modifier
2201 identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
2203 Parameter.Modifier pm = (Parameter.Modifier)$2;
2204 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2207 if (opt_parm && ($7 == null))
2208 Report.Error (30812, "Optional parameters must have a default value");
2211 if ((pm & Parameter.Modifier.REF) !=0)
2212 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
2214 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
2217 if ($4 != null && $6 != null && $4 != $6)
2218 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2220 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2222 string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
2223 ptype = DecomposeQI (t, lexer.Location);
2225 $$ = new Parameter (ptype, (string) $3, pm,
2226 (Attributes) $1, (Expression) $7, opt_parm);
2231 : PARAM_ARRAY identifier opt_parens AS type
2233 string s_patype = ((Expression) $5).ToString();
2237 Expression patype = DecomposeQI (s_patype, Location.Null);
2238 $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
2239 // note ("type must be a single-dimension array type");
2246 | OPEN_PARENS CLOSE_PARENS
2250 opt_parameter_modifier
2251 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2252 | parameter_modifiers { $$ = $1; }
2256 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2257 | parameter_modifier { $$ = $1; }
2261 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2262 | BYVAL { $$ = Parameter.Modifier.VAL; }
2263 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2268 | statement_list end_of_stmt
2273 | statement_list end_of_stmt statement
2277 declaration_statement
2279 if ($1 != null && (Block) $1 != current_block){
2280 current_block.AddStatement ((Statement) $1);
2281 current_block = (Block) $1;
2284 | embedded_statement
2286 Statement s = (Statement) $1;
2288 current_block.AddStatement ((Statement) $1);
2291 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2293 AddHandler ((Expression) $2, (string) $5);
2295 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2297 RemoveHandler ((Expression) $2, (string) $5);
2299 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2301 RaiseEvent ((string) $2, (ArrayList) $3);
2303 /* | array_handling_statement */
2304 /* | empty_statement */
2307 Statement s = (Statement) $1;
2309 current_block.AddStatement ((Statement) $1);
2313 opt_raise_event_args
2314 : /* empty */ { $$ = null; }
2315 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2329 : label_name COLON opt_logical_end_of_line
2331 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2333 if (!current_block.AddLabel ((string) $1, labeled)){
2334 Location l = lexer.Location;
2335 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2337 current_block.AddStatement (labeled);
2343 : expression_statement
2344 | selection_statement
2345 | iteration_statement
2347 | synclock_statement
2349 | array_handling_statement
2355 $$ = new EmptyStatement ();
2361 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2363 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2364 Expression e = (Expression) $2;
2371 Block b = end_block();
2378 array_handling_statement
2384 : REDIM opt_preserve redim_clauses
2386 ArrayList list = (ArrayList) $3;
2387 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2394 : /* empty */ { $$ = false; }
2395 | PRESERVE { $$ = true; }
2401 ArrayList clauses = new ArrayList ();
2406 | redim_clauses COMMA redim_clause
2408 ArrayList clauses = (ArrayList) ($1);
2416 : invocation_expression
2418 Invocation i = (Invocation) $1;
2419 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2425 : ERASE erase_clauses
2427 ArrayList list = (ArrayList) $2;
2428 foreach(Expression e in list)
2430 Erase r = new Erase (e, lexer.Location);
2439 ArrayList clauses = new ArrayList ();
2444 | erase_clauses COMMA erase_clause
2446 ArrayList clauses = (ArrayList) ($1);
2454 : primary_expression
2459 | continue_statement
2460 | */return_statement
2470 $$ = new Goto (current_block, (string) $2, lexer.Location);
2475 : THROW opt_expression
2477 $$ = new Throw ((Expression) $2, lexer.Location);
2484 $$ = new Exit ((ExitType)$2, lexer.Location);
2489 : DO { $$ = ExitType.DO; }
2490 | FOR { $$ = ExitType.FOR; }
2491 | WHILE { $$ = ExitType.WHILE; }
2492 | SELECT { $$ = ExitType.SELECT; }
2493 | SUB { $$ = ExitType.SUB; }
2494 | FUNCTION { $$ = ExitType.FUNCTION; }
2495 | PROPERTY { $$ = ExitType.PROPERTY; }
2496 | TRY { $$ = ExitType.TRY; }
2499 : RETURN opt_expression
2501 $$ = new Return ((Expression) $2, lexer.Location);
2513 : FOR EACH identifier IN
2515 oob_stack.Push (lexer.Location);
2517 expression end_of_stmt
2521 Block foreach_block = current_block;
2522 Location l = lexer.Location;
2523 LocalVariableReference v = null;
2526 vi = foreach_block.GetVariableInfo ((string) $3);
2528 // Get a reference to this variable.
2529 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2532 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2539 Block foreach_block = current_block;
2540 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2541 Block prev_block = end_block();
2542 Location l = (Location) oob_stack.Pop ();
2546 f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
2556 if (!UseExtendedSyntax)
2562 if (iterator_container == null){
2563 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2566 iterator_container.SetYields ();
2567 $$ = new Yield ((Expression) $2, lexer.Location);
2572 if (!UseExtendedSyntax)
2578 if (iterator_container == null){
2579 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2582 iterator_container.SetYields ();
2583 $$ = new YieldBreak (lexer.Location);
2589 : SYNCLOCK expression end_of_stmt
2596 $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
2613 tmp_catch_clauses = (ArrayList) $5;
2622 ArrayList s = new ArrayList ();
2624 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2631 // Now s contains the list of specific catch clauses
2632 // and g contains the general one.
2633 Block b = end_block();
2635 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2642 tmp_block = end_block();
2652 ArrayList s = new ArrayList ();
2653 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2655 if (catch_list != null){
2656 foreach (Catch cc in catch_list) {
2664 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2670 : /* empty */ { $$ = null; }
2677 ArrayList l = new ArrayList ();
2682 | catch_clauses catch_clause
2684 ArrayList l = (ArrayList) $1;
2692 : /* empty */ { $$ = null; }
2697 : CATCH opt_catch_args end_of_stmt
2699 Expression type = null;
2703 DictionaryEntry cc = (DictionaryEntry) $2;
2704 type = (Expression) cc.Key;
2705 id = (string) cc.Value;
2708 ArrayList one = new ArrayList ();
2709 Location loc = lexer.Location;
2711 one.Add (new VariableDeclaration (id, type, loc));
2715 current_block = new Block (current_block);
2716 Block b = declare_local_variables (type, one, loc);
2722 opt_statement_list {
2723 Expression type = null;
2725 Block b_catch = current_block;
2728 DictionaryEntry cc = (DictionaryEntry) $2;
2729 type = (Expression) cc.Key;
2730 id = (string) cc.Value;
2734 // FIXME: I can change this for an assignment.
2736 while (current_block != (Block) $1)
2737 current_block = current_block.Parent;
2741 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2746 : /* empty */ { $$ = null; }
2751 : identifier AS type
2753 $$ = new DictionaryEntry ($3, $1);
2759 : DO opt_do_construct end_of_stmt
2762 oob_stack.Push (lexer.Location);
2765 LOOP opt_do_construct
2767 Expression t_before = (Expression) $2;
2768 Expression t_after = (Expression) $7;
2771 if ((t_before != null) && (t_after != null))
2772 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2774 if ((t_before == null) && (t_after == null))
2775 t = new BoolLiteral (true);
2777 t = (t_before != null) ? t_before : t_after;
2779 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2781 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2782 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2783 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2785 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2790 : /* empty */ { $$ = null; }
2791 | while_or_until boolean_expression
2793 do_type = (DoOptions)$1;
2794 $$ = (Expression) $2;
2799 : WHILE { $$ = DoOptions.WHILE; }
2800 | UNTIL { $$ = DoOptions.UNTIL; }
2807 oob_stack.Push (lexer.Location);
2809 boolean_expression end_of_stmt
2813 Location l = (Location) oob_stack.Pop ();
2814 Block b = end_block();
2815 Expression e = (Expression) $3;
2816 $$ = new While ((Expression) e, (Statement) b, l);
2822 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2829 Block statement = end_block();
2830 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2832 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2833 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2834 for_var, (Expression) $6, lexer.Location);
2835 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2836 for_var, (Expression) $7, lexer.Location), lexer.Location);
2838 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2839 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2841 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2846 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2847 | STEP expression { $$ = $2; }
2856 : if_statement_open opt_then if_statement_rest
2860 | if_statement_open THEN pre_embedded_statement
2862 Location l = (Location) oob_stack.Pop ();
2863 tmp_expr = (Expression)expr_stack.Pop();
2864 $$ = new If ((Expression) tmp_expr, end_block(), l);
2868 pre_embedded_statement
2869 : embedded_statement
2871 Statement s = (Statement) $1;
2873 current_block.AddStatement ((Statement) $1);
2878 : IF boolean_expression
2880 oob_stack.Push (lexer.Location);
2882 tmp_expr = (Expression) $2;
2883 expr_stack.Push(tmp_expr);
2897 Location l = (Location) oob_stack.Pop ();
2898 Expression expr = (Expression)expr_stack.Pop();
2899 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2905 Block bl = end_block();
2906 tmp_blocks.Push(bl);
2912 Location l = (Location) oob_stack.Pop ();
2913 tmp_expr = (Expression)expr_stack.Pop();
2914 tmp_block = (Block) tmp_blocks.Pop();
2915 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2919 ELSEIF boolean_expression opt_then
2921 tmp_expr = (Expression) $4;
2922 expr_stack.Push(tmp_expr);
2923 tmp_block = end_block();
2924 tmp_blocks.Push(tmp_block);
2927 else_if_statement_rest
2929 Statement stmt = (Statement) statement_stack.Pop();
2930 Block bl = (Block) tmp_blocks.Pop();
2931 Expression expr = (Expression)expr_stack.Pop();
2932 Location l = (Location) oob_stack.Pop ();
2933 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
2938 else_if_statement_rest
2943 Location l = (Location) oob_stack.Pop ();
2945 Expression expr = (Expression)expr_stack.Pop();
2946 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
2947 statement_stack.Push(stmt);
2953 Block bl = end_block();
2954 tmp_blocks.Push(bl);
2960 Location l = (Location) oob_stack.Pop ();
2962 Expression expr = (Expression)expr_stack.Pop();
2963 Block bl = (Block)tmp_blocks.Pop();
2964 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
2965 statement_stack.Push(stmt);
2969 ELSEIF boolean_expression opt_then
2971 expr_stack.Push((Expression) $4);
2972 Block bl = end_block();
2973 tmp_blocks.Push(bl);
2976 else_if_statement_rest
2978 Location l = (Location) oob_stack.Pop ();
2980 Statement tmp_stmt = (Statement)statement_stack.Pop();
2981 Block bl = (Block) tmp_blocks.Pop();
2982 Expression expr = (Expression)expr_stack.Pop();
2983 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
2984 statement_stack.Push(stmt);
2989 : SELECT opt_case expression end_of_stmt
2991 oob_stack.Push (lexer.Location);
2992 switch_stack.Push (current_block);
2997 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2998 current_block = (Block) switch_stack.Pop ();
3003 : /* empty */ { $$ = null; }
3004 | case_sections { $$ = $1; }
3008 : case_sections case_section
3010 ArrayList sections = (ArrayList) $1;
3017 ArrayList sections = new ArrayList ();
3031 : CASE case_clauses ends
3037 //Block topmost = current_block;
3038 Block topmost = end_block();
3040 while (topmost.Implicit)
3041 topmost = topmost.Parent;
3043 // FIXME: This is a horrible hack which MUST go
3044 topmost.statements.Add (new Break (lexer.Location));
3045 $$ = new SwitchSection ((ArrayList) $2, topmost);
3048 /* FIXME: we should somehow flag an error
3049 (BC30321 'Case' cannot follow a 'Case Else'
3050 in the same 'Select' statement.)
3051 if Case Else is not the last of the Case clauses
3058 //Block topmost = current_block;
3059 Block topmost = end_block();
3061 while (topmost.Implicit)
3062 topmost = topmost.Parent;
3064 // FIXME: This is a horrible hack which MUST go
3065 topmost.statements.Add (new Break (lexer.Location));
3067 ArrayList a = new ArrayList();
3068 a.Add (new SwitchLabel (null, lexer.Location));
3069 $$ = new SwitchSection ((ArrayList) a, topmost);
3076 ArrayList labels = new ArrayList ();
3081 | case_clauses COMMA case_clause
3083 ArrayList labels = (ArrayList) ($1);
3091 : opt_is comparison_operator expression
3094 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3116 expression_statement
3117 : statement_expression
3124 statement_expression
3125 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3126 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3127 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3130 object_creation_expression
3131 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3133 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3137 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3141 array_creation_expression
3142 : object_creation_expression array_initializer
3145 ArrayList dims = new ArrayList();
3147 if (n.Arguments != null) {
3148 foreach (Argument a in n.Arguments) {
3153 Expression atype = n.RequestedType;
3155 ArrayList init = (ArrayList) $2;
3156 if (init.Count == 0)
3159 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3160 VariableDeclaration.VBFixIndexList (ref dims);
3161 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3165 string rank = VariableDeclaration.BuildRank (dims);
3166 $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
3168 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3172 /*delegate_creation_expression
3173 : NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3175 ArrayList args = new ArrayList();
3176 Argument arg = new Argument ((Expression) $5, Argument.AType.Expression);
3179 New n = new New ((Expression) $2, (ArrayList) args, lexer.Location);
3185 : object_creation_expression
3186 | array_creation_expression
3187 //| delegate_creation_expression
3190 declaration_statement
3191 : local_variable_declaration
3194 DictionaryEntry de = (DictionaryEntry) $1;
3196 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3199 | local_constant_declaration
3202 DictionaryEntry de = (DictionaryEntry) $1;
3204 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3209 local_variable_declaration
3210 : DIM variable_declarators
3212 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3217 local_constant_declaration
3218 : CONST constant_declarators
3221 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3227 constant_declarators
3228 : constant_declarator
3230 ArrayList decl = new ArrayList ();
3236 | constant_declarators COMMA constant_declarator
3238 ArrayList decls = (ArrayList) $1;
3247 : variable_name opt_type_decl opt_variable_initializer
3249 VarName vname = (VarName) $1;
3250 string varname = (string) vname.Name;
3251 current_rank_specifiers = (ArrayList) vname.Rank;
3252 object varinit = $3;
3253 ArrayList a_dims = null;
3255 if (varinit == null)
3257 30438, lexer.Location, "Constant should have a value"
3260 if (vname.Type != null && $2 != null)
3262 30302, lexer.Location,
3263 "Type character cannot be used with explicit type declaration" );
3265 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3267 if (current_rank_specifiers != null)
3269 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3273 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3277 variable_declarators
3278 : variable_declarator
3280 ArrayList decl = new ArrayList ();
3281 decl.AddRange ((ArrayList) $1);
3284 | variable_declarators COMMA variable_declarator
3286 ArrayList decls = (ArrayList) $1;
3287 decls.AddRange ((ArrayList) $3);
3293 : variable_names opt_type_decl opt_variable_initializer
3295 ArrayList names = (ArrayList) $1;
3296 object varinit = $3;
3297 ArrayList VarDeclarations = new ArrayList();
3299 ArrayList a_dims = null;
3301 if ((names.Count > 1) && (varinit != null))
3303 30671, lexer.Location,
3304 "Multiple variables with single type can not have " +
3305 "a explicit initialization" );
3308 foreach (VarName vname in names)
3310 string varname = (string) vname.Name;
3311 current_rank_specifiers = (ArrayList) vname.Rank;
3315 if(vname.Type != null && $2 != null)
3317 30302, lexer.Location,
3318 "Type character cannot be used with explicit type declaration" );
3320 // Some checking is required for particularly weird declarations
3321 // like Dim a As Integer(,)
3323 vartype = (Expression) ((Pair) $2).First;
3325 /*if ($3 != null && $3 is ArrayList)
3326 Report.Error (205, "End of statement expected.");*/
3328 ArrayList args = (ArrayList) ((Pair) $2).Second;
3329 if (current_rank_specifiers != null)
3330 Report.Error (31087, lexer.Location,
3331 "Array types specified in too many places");
3333 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3334 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3336 current_rank_specifiers = new ArrayList ();
3337 current_rank_specifiers.Add (args);
3339 /*string s_vartype = vartype.ToString();
3342 for (int x = 0; x < args.Count; x++)
3346 vartype = DecomposeQI(s_vartype, Location.Null); */
3349 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3351 // if the variable is an array with explicit bound
3352 // and having explicit initialization throw exception
3353 if (current_rank_specifiers != null && varinit != null)
3355 bool broken = false;
3356 foreach (ArrayList exprs in current_rank_specifiers)
3358 foreach (Expression expr in exprs)
3360 if (!((Expression)expr is EmptyExpression ))
3363 30672, lexer.Location,
3364 "Array declared with explicit bound " +
3365 " can not have explicit initialization");
3376 Check for a declaration like Dim a(2) or Dim a(2,3)
3377 If this is the case, we must generate an ArrayCreationExpression
3378 and, in case, add the initializer after the array has been created.
3380 if (VariableDeclaration.IsArrayDecl (this)) {
3381 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3382 a_dims = (ArrayList) current_rank_specifiers;
3383 VariableDeclaration.VBFixIndexLists (ref a_dims);
3384 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3386 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
3389 if (vartype is New) {
3390 if (varinit != null) {
3391 Report.Error (30205, lexer.Location, "End of statement expected");
3397 vartype = ((New)vartype).RequestedType;
3400 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3402 $$ = VarDeclarations;
3409 ArrayList list = new ArrayList ();
3413 | variable_names COMMA variable_name
3415 ArrayList list = (ArrayList) $1;
3422 : identifier opt_type_character opt_array_name_modifier
3424 $$ = new VarName ($1, $2, $3);
3435 $$ = (Expression) $2;
3441 | AS type rank_specifiers
3443 $$ = TypeManager.system_object_expr;
3452 | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
3454 $$ = new Pair ($2, $4);
3458 New n = new New ((Expression)$3, null, lexer.Location);
3459 $$ = (Expression) n;
3461 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3463 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3464 $$ = (Expression) n;
3466 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3468 ArrayList args = new ArrayList();
3469 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3472 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3473 $$ = (Expression) n;
3477 opt_array_name_modifier
3478 : /* empty */ { $$ = null; }
3479 | array_type_modifier { $$ = $1; }
3483 : rank_specifiers { $$ = $1; }
3486 opt_variable_initializer
3487 : /* empty */ { $$ = null; }
3488 | ASSIGN variable_initializer { $$ = $2; }
3491 variable_initializer
3504 : OPEN_BRACE CLOSE_BRACE
3506 ArrayList list = new ArrayList ();
3509 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3511 $$ = (ArrayList) $2;
3515 variable_initializer_list
3516 : variable_initializer
3518 ArrayList list = new ArrayList ();
3522 | variable_initializer_list COMMA variable_initializer
3524 ArrayList list = (ArrayList) $1;
3545 ArrayList rs = new ArrayList();
3549 | rank_specifiers rank_specifier
3551 ArrayList rs = (ArrayList) $1;
3558 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
3567 ArrayList ds = new ArrayList();
3568 ds.Add (new EmptyExpression());
3573 ArrayList ds = (ArrayList) $1;
3574 ds.Add (new EmptyExpression());
3586 ArrayList ds = new ArrayList();
3587 ds.Add (new EmptyExpression());
3590 | dim_separators COMMA
3592 ArrayList ds = (ArrayList) $1;
3593 ds.Add (new EmptyExpression());
3601 ArrayList ds = new ArrayList();
3602 ds.Add ((Expression) $1);
3605 | dim_specifiers COMMA expression
3607 ArrayList ds = (ArrayList) $1;
3608 ds.Add ((Expression) $3);
3620 | qualified_identifier
3622 string name = (string) $1;
3623 $$ = DecomposeQI (name, lexer.Location);
3625 | parenthesized_expression
3627 | invocation_expression
3639 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3640 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3641 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3642 | NOTHING { $$ = NullLiteral.Null; }
3646 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3647 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3648 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3653 object v = lexer.Value;
3656 $$ = new IntLiteral ((Int32)v);
3657 else if (v is short)
3658 $$ = new ShortLiteral ((Int16)v);
3660 $$ = new LongLiteral ((Int64)v);
3662 Console.WriteLine ("OOPS. Unexpected result from scanner");
3668 : TRUE { $$ = new BoolLiteral (true); }
3669 | FALSE { $$ = new BoolLiteral (false); }
3672 parenthesized_expression
3673 : OPEN_PARENS expression CLOSE_PARENS
3678 : primary_expression DOT identifier
3681 string id_name = (string)$3;
3682 if (id_name.ToUpper() == "NEW")
3684 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3688 if (with_stack.Count > 0) {
3689 Expression e = (Expression) with_stack.Peek();
3690 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3698 /* | primary_expression DOT NEW
3700 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3702 | predefined_type DOT identifier
3705 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3708 if (with_stack.Count > 0) {
3709 Expression e = (Expression) with_stack.Peek();
3710 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3724 invocation_expression
3725 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3728 Location l = lexer.Location;
3729 Report.Error (1, l, "THIS IS CRAZY");
3731 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3732 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3737 : MYBASE DOT IDENTIFIER
3739 string id_name = (string) $3;
3740 if (id_name.ToUpper() == "NEW")
3742 $$ = new BaseAccess (id_name, lexer.Location);
3746 $$ = new BaseAccess ("New", lexer.Location);
3754 The 'argument' rule returns an 'empty' argument
3755 of type NoArg (used for default arguments in invocations)
3756 if no arguments are actually passed.
3758 If there is only one argument and it is o type NoArg,
3759 we return a null (empty) list
3761 ArrayList args = (ArrayList) $1;
3762 if (args.Count == 1 &&
3763 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3773 ArrayList list = new ArrayList ();
3777 | argument_list COMMA argument
3779 ArrayList list = (ArrayList) $1;
3788 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3790 | BYREF variable_reference
3792 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3796 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3798 | ADDRESSOF expression
3800 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
3805 : expression {/* note ("section 5.4"); */ $$ = $1; }
3811 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3816 : conditional_expression { $$ = $1; }
3817 | negation_expression
3818 /*| assignment_expression*/
3829 $$ = new This (current_block, lexer.Location);
3833 // FIXME: This is actually somewhat different from Me
3834 // because it is for accessing static (classifier) methods/properties/fields
3835 $$ = new This (current_block, lexer.Location);
3840 : primary_expression
3841 /*| NOT prefixed_unary_expression
3843 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3845 | cast_expression */
3849 : cast_operator OPEN_PARENS expression CLOSE_PARENS
3851 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3853 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3855 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3860 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3861 | CBYTE { $$ = TypeManager.system_byte_expr; }
3862 | CCHAR { $$ = TypeManager.system_char_expr; }
3863 | CDATE { $$ = TypeManager.system_date_expr; }
3864 | CDBL { $$ = TypeManager.system_double_expr; }
3865 | CDEC { $$ = TypeManager.system_decimal_expr; }
3866 | CINT { $$ = TypeManager.system_int32_expr; }
3867 | CLNG { $$ = TypeManager.system_int64_expr; }
3868 | COBJ { $$ = TypeManager.system_object_expr; }
3869 | CSHORT { $$ = TypeManager.system_int16_expr; }
3870 | CSNG { $$ = TypeManager.system_single_expr; }
3871 | CSTR { $$ = TypeManager.system_string_expr; }
3875 // The idea to split this out is from Rhys' grammar
3876 // to solve the problem with casts.
3878 prefixed_unary_expression
3880 | PLUS prefixed_unary_expression
3882 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3884 | MINUS prefixed_unary_expression
3886 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3890 multiplicative_expression
3891 : prefixed_unary_expression
3892 | multiplicative_expression STAR prefixed_unary_expression
3894 $$ = new Binary (Binary.Operator.Multiply,
3895 (Expression) $1, (Expression) $3, lexer.Location);
3897 | multiplicative_expression DIV prefixed_unary_expression
3899 $$ = new Binary (Binary.Operator.Division,
3900 (Expression) $1, (Expression) $3, lexer.Location);
3902 | multiplicative_expression OP_IDIV prefixed_unary_expression
3904 $$ = new Binary (Binary.Operator.Division,
3905 (Expression) $1, (Expression) $3, lexer.Location);
3907 | multiplicative_expression MOD prefixed_unary_expression
3909 $$ = new Binary (Binary.Operator.Modulus,
3910 (Expression) $1, (Expression) $3, lexer.Location);
3915 : multiplicative_expression
3916 | additive_expression PLUS multiplicative_expression
3918 $$ = new Binary (Binary.Operator.Addition,
3919 (Expression) $1, (Expression) $3, lexer.Location);
3921 | additive_expression MINUS multiplicative_expression
3923 $$ = new Binary (Binary.Operator.Subtraction,
3924 (Expression) $1, (Expression) $3, lexer.Location);
3926 | additive_expression OP_CONCAT multiplicative_expression
3928 // FIXME: This should only work for String expressions
3929 // We probably need to use something from the runtime
3930 $$ = new Binary (Binary.Operator.Addition,
3931 (Expression) $1, (Expression) $3, lexer.Location);
3935 relational_expression
3936 : additive_expression
3937 | relational_expression OP_LT additive_expression
3939 $$ = new Binary (Binary.Operator.LessThan,
3940 (Expression) $1, (Expression) $3, lexer.Location);
3942 | relational_expression OP_GT additive_expression
3944 $$ = new Binary (Binary.Operator.GreaterThan,
3945 (Expression) $1, (Expression) $3, lexer.Location);
3947 | relational_expression OP_LE additive_expression
3949 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3950 (Expression) $1, (Expression) $3, lexer.Location);
3952 | relational_expression OP_GE additive_expression
3954 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3955 (Expression) $1, (Expression) $3, lexer.Location);
3957 | relational_expression IS unary_expression
3959 $$ = new Binary (Binary.Operator.Equality,
3960 (Expression) $1, (Expression) $3, lexer.Location);
3962 | relational_expression AS type_name
3964 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3969 : relational_expression
3970 | equality_expression ASSIGN relational_expression
3972 $$ = new Binary (Binary.Operator.Equality,
3973 (Expression) $1, (Expression) $3, lexer.Location);
3975 | equality_expression OP_NE relational_expression
3977 $$ = new Binary (Binary.Operator.Inequality,
3978 (Expression) $1, (Expression) $3, lexer.Location);
3983 : equality_expression
3984 | and_expression AND equality_expression
3986 $$ = new Binary (Binary.Operator.BitwiseAnd,
3987 (Expression) $1, (Expression) $3, lexer.Location);
3991 exclusive_or_expression
3993 | exclusive_or_expression OP_XOR and_expression
3995 $$ = new Binary (Binary.Operator.ExclusiveOr,
3996 (Expression) $1, (Expression) $3, lexer.Location);
4000 conditional_and_expression
4001 : exclusive_or_expression
4002 | conditional_and_expression AND exclusive_or_expression
4004 $$ = new Binary (Binary.Operator.LogicalAnd,
4005 (Expression) $1, (Expression) $3, lexer.Location);
4007 | conditional_and_expression ANDALSO exclusive_or_expression
4008 { // FIXME: this is likely to be broken
4009 $$ = new Binary (Binary.Operator.LogicalAnd,
4010 (Expression) $1, (Expression) $3, lexer.Location);
4014 conditional_or_expression
4015 : conditional_and_expression
4016 | conditional_or_expression OR conditional_and_expression
4018 $$ = new Binary (Binary.Operator.LogicalOr,
4019 (Expression) $1, (Expression) $3, lexer.Location);
4021 | conditional_or_expression ORELSE conditional_and_expression
4022 { // FIXME: this is likely to be broken
4023 $$ = new Binary (Binary.Operator.LogicalOr,
4024 (Expression) $1, (Expression) $3, lexer.Location);
4028 conditional_expression
4029 : conditional_or_expression
4032 assignment_expression
4033 : prefixed_unary_expression ASSIGN expression
4035 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4037 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4039 ArrayList args = new ArrayList();
4040 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4043 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4044 n.isDelegate = true;
4045 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
4047 | prefixed_unary_expression OP_MULT_ASSIGN expression
4049 Location l = lexer.Location;
4051 $$ = new CompoundAssign (
4052 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
4054 | prefixed_unary_expression OP_DIV_ASSIGN expression
4056 Location l = lexer.Location;
4058 $$ = new CompoundAssign (
4059 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
4061 | prefixed_unary_expression OP_IDIV_ASSIGN expression
4063 Location l = lexer.Location;
4065 $$ = new CompoundAssign (
4066 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
4068 | prefixed_unary_expression OP_ADD_ASSIGN expression
4070 Location l = lexer.Location;
4072 $$ = new CompoundAssign (
4073 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
4075 | prefixed_unary_expression OP_SUB_ASSIGN expression
4077 Location l = lexer.Location;
4079 $$ = new CompoundAssign (
4080 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
4082 | prefixed_unary_expression OP_CONCAT_ASSIGN expression
4084 Location l = lexer.Location;
4086 $$ = new CompoundAssign (
4087 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
4091 /*constant_expression
4101 : type_name { /* class_type */
4103 This does interfaces, delegates, struct_types, class_types,
4104 parent classes, and more! 4.2
4106 $$ = DecomposeQI ((string) $1, lexer.Location);
4116 ArrayList types = new ArrayList ();
4121 | type_list COMMA type
4123 ArrayList types = (ArrayList) $1;
4131 : namespace_or_type_name
4134 namespace_or_type_name
4135 : qualified_identifier
4138 /* Built-in / Integral types */
4140 : OBJECT { $$ = TypeManager.system_object_expr; }
4141 | STRING { $$ = TypeManager.system_string_expr; }
4142 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4143 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4144 | SINGLE { $$ = TypeManager.system_single_expr; }
4145 | DOUBLE { $$ = TypeManager.system_double_expr; }
4146 | DATE { $$ = TypeManager.system_date_expr; }
4152 | BYTE { $$ = TypeManager.system_byte_expr; }
4153 | SHORT { $$ = TypeManager.system_int16_expr; }
4154 | LONG { $$ = TypeManager.system_int64_expr; }
4155 | INTEGER { $$ = TypeManager.system_int32_expr; }
4156 | CHAR { $$ = TypeManager.system_char_expr; }
4164 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4166 if(tokenizerController.IsAcceptingTokens)
4168 if(in_external_source)
4169 Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4171 in_external_source = true;
4173 lexer.EffectiveSource = (string) $4;
4174 lexer.EffectiveLine = (int) $6;
4178 | HASH IDENTIFIER LITERAL_STRING EOL
4180 if(tokenizerController.IsAcceptingTokens)
4182 string id = ($2 as string);
4184 if(!($2 as string).ToLower().Equals("region"))
4185 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4192 | HASH END IDENTIFIER EOL
4194 if(tokenizerController.IsAcceptingTokens)
4196 if( ($3 as string).ToLower().Equals("externalsource")) {
4197 if(!in_external_source)
4198 Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4200 in_external_source = false;
4201 lexer.EffectiveSource = lexer.Source;
4202 lexer.EffectiveLine = lexer.Line;
4205 else if(($3 as string).ToLower().Equals("region")) {
4206 if(in_marked_region > 0)
4209 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4212 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4216 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4218 if(tokenizerController.IsAcceptingTokens)
4225 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4228 ifElseStateMachine.HandleToken(tok);
4230 catch(ApplicationException) {
4231 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4234 boolean_literal opt_then EOL
4236 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4240 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4242 ifElseStateMachine.HandleToken(tok);
4244 catch(ApplicationException) {
4245 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4248 boolean_literal opt_then EOL
4250 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4254 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4256 ifElseStateMachine.HandleToken(tok);
4258 catch(ApplicationException) {
4259 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4264 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4268 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4270 ifElseStateMachine.HandleToken(tok);
4272 catch(ApplicationException) {
4273 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4278 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4282 if(tokenizerController.IsAcceptingTokens)
4283 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4285 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4295 public Tokenizer Lexer {
4301 public static Expression DecomposeQI (string name, Location loc)
4305 if (name.IndexOf ('.') == -1){
4306 return new SimpleName (name, loc);
4308 int pos = name.LastIndexOf (".");
4309 string left = name.Substring (0, pos);
4310 string right = name.Substring (pos + 1);
4312 o = DecomposeQI (left, loc);
4314 return new MemberAccess (o, right, loc);
4318 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4320 Block implicit_block;
4321 ArrayList inits = null;
4324 // We use the `Used' property to check whether statements
4325 // have been added to the current block. If so, we need
4326 // to create another block to contain the new declaration
4327 // otherwise, as an optimization, we use the same block to
4328 // add the declaration.
4330 // FIXME: A further optimization is to check if the statements
4331 // that were added were added as part of the initialization
4332 // below. In which case, no other statements have been executed
4333 // and we might be able to reduce the number of blocks for
4334 // situations like this:
4336 // int j = 1; int k = j + 1;
4339 VariableDeclaration.FixupTypes (variable_declarators);
4341 if (current_block.Used) {
4342 implicit_block = new Block (current_block, true, loc, Location.Null);
4343 implicit_block.AddChildVariableNames (current_block);
4345 implicit_block = current_block;
4347 foreach (VariableDeclaration decl in variable_declarators){
4348 Expression type = decl.type;
4349 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4350 if (decl.expression_or_array_initializer != null){
4352 inits = new ArrayList ();
4359 return implicit_block;
4361 foreach (VariableDeclaration decl in inits){
4364 Expression type = decl.type;
4366 if ((decl.expression_or_array_initializer is Expression) ||
4367 (decl.expression_or_array_initializer is New)) {
4368 expr = (Expression) decl.expression_or_array_initializer;
4370 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4372 expr = new ArrayCreation (type, "", init, decl.Location);
4375 LocalVariableReference var;
4376 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4378 assign = new Assign (var, expr, decl.Location);
4380 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4383 return implicit_block;
4386 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4388 Block implicit_block;
4389 VariableDeclaration.FixupTypes (variable_declarators);
4391 if (current_block.Used)
4392 implicit_block = new Block (current_block, true);
4394 implicit_block = current_block;
4396 foreach (VariableDeclaration decl in variable_declarators){
4397 Expression type = decl.type;
4398 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4399 current_local_parameters, decl.Location);
4402 return implicit_block;
4410 public VarName (object n, object t, object r)
4420 // A class used to pass around variable declarations and constants
4422 public class VariableDeclaration {
4423 public string identifier;
4424 public object expression_or_array_initializer;
4425 public Location Location;
4426 public Attributes OptAttributes;
4427 public Expression type;
4428 public ArrayList dims;
4430 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4432 this.identifier = id;
4433 this.expression_or_array_initializer = eoai;
4435 this.OptAttributes = opt_attrs;
4440 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4444 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4448 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4449 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4453 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4455 // FIXME : This is broken: only the first rank is parsed
4456 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4459 public static void FixupTypes (ArrayList vars)
4461 int varcount = vars.Count;
4462 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4464 if (last_var.type == null)
4465 last_var.type = TypeManager.system_object_expr;
4467 Expression cur_type = last_var.type;
4468 int n = varcount - 1;
4471 VariableDeclaration var = (VariableDeclaration) vars[n--];
4472 if (var.type == null)
4473 var.type = cur_type;
4475 cur_type = var.type;
4479 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4483 if (IndexList != null) {
4484 foreach (Expression e in IndexList)
4485 if (!(e is EmptyExpression)) {
4494 public static bool IndexesSpecified (ArrayList ranks)
4498 if (ranks != null) {
4499 foreach (ArrayList IndexList in ranks) {
4500 if (IndexesSpecifiedInRank (IndexList)) {
4509 public static string StripDims (string varname, ref string d)
4511 string res = varname;
4514 if (varname.IndexOf("[") >= 0) {
4515 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4516 res = varname.Substring(0, varname.IndexOf("["));
4522 public static string StripDims (string varname)
4526 return (StripDims(varname, ref dres));
4529 public static string StripIndexesFromDims (string dims)
4531 StringBuilder sb = new StringBuilder();
4533 foreach (char c in dims)
4534 if (c == ',' || c == ']' || c == '[')
4537 return sb.ToString();
4540 public static string BuildRank (ArrayList rank)
4545 for (int x = 0; x < (rank.Count -1 ); x++)
4552 public static string BuildRanks (Parser t)
4556 foreach (ArrayList rank in t.current_rank_specifiers)
4557 res += BuildRank (rank);
4562 public static void VBFixIndexList (ref ArrayList IndexList)
4564 if (IndexList != null) {
4565 for (int x = 0; x < IndexList.Count; x++) {
4566 Expression e = (Expression) IndexList[x];
4567 if (!(e is EmptyExpression)) {
4568 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4574 public static bool IsArrayDecl (Parser t)
4576 // return (varname.IndexOf("[") >= 0);
4577 return (t.current_rank_specifiers != null);
4580 public static void VBFixIndexLists (ref ArrayList ranks)
4582 if (ranks != null) {
4583 for (int x = 0; x < ranks.Count; x++) {
4584 ArrayList IndexList = (ArrayList) ranks[x];
4585 VBFixIndexList (ref IndexList);
4590 public static void FixupArrayTypes (ArrayList vars)
4592 int varcount = vars.Count;
4595 foreach (VariableDeclaration var in vars) {
4596 if (var.identifier.EndsWith(",")) {
4597 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4598 var.identifier.LastIndexOf(",")) + "]";
4599 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4600 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4607 public Property BuildSimpleProperty (Expression p_type, string name,
4608 Field p_fld, int mod_flags,
4609 Attributes attrs, Location loc)
4612 Block get_block, set_block;
4613 Accessor acc_set, acc_get;
4614 StatementExpression a_set;
4619 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4620 args = new Parameter [1];
4621 args [0] = implicit_value_parameter;
4623 Parameters set_params = new Parameters (args, null, loc);
4624 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4625 (Expression) new SimpleName("value", loc), loc), loc);
4627 set_block = new Block (current_block, set_params, loc, Location.Null);
4628 set_block.AddStatement ((Statement) a_set);
4629 acc_set = new Accessor (set_block, attrs);
4632 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4633 get_block = new Block (current_block, null, loc, Location.Null);
4634 get_block.AddStatement ((Statement) a_get);
4635 acc_get = new Accessor (get_block, attrs);
4637 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4644 current_block = new Block (current_block, current_local_parameters,
4645 lexer.Location, Location.Null);
4652 while (current_block.Implicit)
4653 current_block = current_block.Parent;
4655 res = current_block;
4657 current_block.SetEndLocation (lexer.Location);
4658 current_block = current_block.Parent;
4663 private void AddHandler (Expression evt_definition, string handler_name)
4665 AddHandler (current_block, evt_definition, handler_name);
4668 void CheckAttributeTarget (string a)
4672 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4676 Location l = lexer.Location;
4677 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4682 private void AddHandler (Block b, Expression evt_id, string handler_name)
4684 Location loc = lexer.Location;
4685 string evt_target = evt_id.ToString();
4686 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4687 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4691 private void RaiseEvent (string evt_name, ArrayList args)
4693 Location loc = lexer.Location;
4695 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4696 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4697 current_block.AddStatement (s);
4700 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4702 Location loc = lexer.Location;
4703 string evt_target = evt_definition.ToString();
4704 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4705 Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4710 // This method is used to get at the complete string representation of
4711 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4712 // This is necessary because local_variable_type admits primary_expression
4713 // as the type of the variable. So we do some extra checking
4715 string GetQualifiedIdentifier (Expression expr)
4717 if (expr is SimpleName)
4718 return ((SimpleName)expr).Name;
4719 else if (expr is MemberAccess)
4720 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4722 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4726 private void RemoveHandler (Expression evt_definition, string handler_name)
4728 RemoveHandler (current_block, evt_definition, handler_name);
4731 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4733 ConstructorInitializer ci = null;
4736 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4737 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4739 if (i.expr is BaseAccess) {
4740 BaseAccess ba = (BaseAccess) i.expr;
4741 if (ba.member == "New" || ba.member == ".ctor") {
4742 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4746 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4747 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4755 void Error_ExpectingTypeName (Location l, Expression expr)
4757 if (expr is Invocation){
4758 Report.Error (1002, l, "; expected");
4760 Report.Error (-1, l, "Invalid Type definition");
4764 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4768 private void ReportError9998()
4770 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4773 protected override int parse ()
4775 RootContext.InitializeImports(ImportsList);
4776 current_namespace = new Namespace (null, RootContext.RootNamespace);
4777 current_container = RootContext.Tree.Types;
4778 current_container.Namespace = current_namespace;
4779 oob_stack = new Stack ();
4780 switch_stack = new Stack ();
4781 expr_stack = new Stack ();
4782 tmp_blocks = new Stack();
4783 with_stack = new Stack();
4784 statement_stack = new Stack();
4786 UseExtendedSyntax = name.EndsWith(".mbs");
4787 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4788 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4789 OptionCompareBinary = InitialOptionCompareBinary;
4791 lexer = new Tokenizer (input, name, defines);
4793 ifElseStateMachine = new IfElseStateMachine();
4794 tokenizerController = new TokenizerController(lexer);
4796 StringBuilder value = new StringBuilder ();
4798 if (yacc_verbose_flag)
4799 yyparse (lexer, new yydebug.yyDebugSimple ());
4805 catch(MBASException e) {
4806 Report.Error(e.code, e.loc, e.Message);
4808 catch (Exception e) {
4809 Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.EffectiveSource + "\n" + e.ToString());
4812 RootContext.VerifyImports();
4814 return Report.Errors;
4820 ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
4822 catch(ApplicationException) {
4823 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4826 if(in_external_source)
4827 Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
4829 if(in_marked_region > 0)
4830 Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
4833 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
4836 tokenizerController.PositionTokenizerCursor(tok, expr);
4838 catch(ApplicationException) {
4839 tok = IfElseStateMachine.Token.EOF;
4841 ifElseStateMachine.HandleToken(tok);
4843 catch(ApplicationException) {
4844 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);