//
// Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
//
-// Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+// Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+// Anirban Bhattacharjee (banirban@novell.com)
+// Jambunathan K (kjambunathan@novell.com)
//
// Licensed under the terms of the GNU GPL
//
-// Copyright (C) 2001 A Rafael D Teixeira
+// Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
+// Copyright (C) 2003, 2004 Novell
//
-// TODO:
-// Nearly everything
//
namespace Mono.MonoBASIC
using Mono.Languages;
using Mono.MonoBASIC;
+ public class MBASException : ApplicationException
+ {
+ public int code;
+ public Location loc;
+
+ public MBASException(int code, Location loc, string text) : base(text)
+ {
+ this.code = code;
+ this.loc = loc;
+ }
+ }
+
/// <summary>
/// The MonoBASIC Parser
/// </summary>
{
+
/// <summary>
/// Current block is used to add statements as we find
/// them.
Stack expr_stack;
Stack tmp_blocks;
- Stack statement_stack;
+ Stack statement_stack;
// A stack for With expressions.
//
return list;
}
+ bool in_external_source = false;
+ int in_marked_region = 0;
+
+ TokenizerController tokenizerController;
+ IfElseStateMachine ifElseStateMachine;
+
+
+ public class IfElseStateMachine {
+
+ public enum State {
+ START,
+ IF_SEEN,
+ ELSEIF_SEEN,
+ ELSE_SEEN,
+ ENDIF_SEEN,
+ MAX
+ }
+
+ public enum Token {
+ START,
+ IF,
+ ELSEIF,
+ ELSE,
+ ENDIF,
+ EOF,
+ MAX
+ }
+
+ State state;
+ Stack stateStack;
+
+ public static Hashtable errStrings = new Hashtable();
+
+ int err=0;
+ static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
+
+ static IfElseStateMachine()
+ {
+ // FIXME: Fix both the error nos and the error strings.
+ // Currently the error numbers and the error strings are
+ // just placeholders for getting the state-machine going.
+
+ errStrings.Add(0, "");
+ errStrings.Add(30012, "#If must end with a matching #End If");
+ errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
+ errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
+ errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
+ errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
+
+ errTable[(int)State.START, (int)Token.IF] = 0;
+ errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
+ errTable[(int)State.START, (int)Token.ELSE] = 30028;
+ errTable[(int)State.START, (int)Token.ENDIF] = 30013;
+ errTable[(int)State.START, (int)Token.EOF] = 0;
+
+ errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
+ errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
+ errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
+ errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
+ errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
+
+ errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
+ errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
+ errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
+ errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
+ errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
+
+ errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
+ errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
+ errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
+ errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
+ errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
+
+ errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
+ errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
+ errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
+ errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
+ errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
+ }
+
+ public IfElseStateMachine()
+ {
+ state = State.START;
+
+ stateStack = new Stack();
+ stateStack.Push(state);
+ }
+
+ // The parameter here need not be qualified with IfElseStateMachine
+ // But it hits a bug in mcs. So temporarily scoping it so that builds
+ // are not broken.
+
+ public void HandleToken(IfElseStateMachine.Token tok)
+ {
+ err = (int) errTable[(int)state, (int)tok];
+
+ if(err != 0)
+ throw new ApplicationException("Unexpected pre-processor directive #"+tok);
+
+ if(tok == Token.IF) {
+ stateStack.Push(state);
+ state = (State) tok;
+ }
+ else if(tok == Token.ENDIF) {
+ state = (State)stateStack.Pop();
+ }
+ else
+ state = (State)tok;
+ }
+
+ public int Error {
+ get {
+ return err;
+ }
+ }
+
+ public string ErrString {
+ get {
+ return (string) errStrings[err];
+ }
+ }
+ }
+
+
+ public class TokenizerController {
+
+ struct State
+ {
+ public bool CanAcceptTokens;
+ public bool CanSelectBlock;
+
+ }
+
+ State currentState;
+ Stack stateStack;
+ Tokenizer lexer;
+
+ public TokenizerController(Tokenizer lexer)
+ {
+ this.lexer = lexer;
+ stateStack = new Stack();
+
+ currentState.CanAcceptTokens = true;
+ currentState.CanSelectBlock = true;
+
+ stateStack.Push(currentState);
+ }
+
+ State parentState {
+ get {
+ return (State)stateStack.Peek();
+ }
+ }
+
+ public bool IsAcceptingTokens {
+ get {
+ return currentState.CanAcceptTokens;
+ }
+ }
+
+ public void PositionCursorAtNextPreProcessorDirective()
+ {
+ lexer.PositionCursorAtNextPreProcessorDirective();
+ }
+
+ public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
+ {
+ if(tok == IfElseStateMachine.Token.ENDIF) {
+ currentState = (State)stateStack.Pop();
+
+ if(currentState.CanAcceptTokens)
+ return;
+ else {
+ PositionCursorAtNextPreProcessorDirective();
+ return;
+ }
+ }
+
+ if(tok == IfElseStateMachine.Token.IF) {
+ stateStack.Push(currentState);
+
+ currentState.CanAcceptTokens = parentState.CanAcceptTokens;
+ currentState.CanSelectBlock = true;
+ }
+
+ if(parentState.CanAcceptTokens &&
+ currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
+
+ currentState.CanAcceptTokens = true;
+ currentState.CanSelectBlock = false;
+ return;
+ }
+ else {
+ currentState.CanAcceptTokens = false;
+ PositionCursorAtNextPreProcessorDirective();
+ return;
+ }
+ }
+ }
+
+ bool allow_global_attribs = true;
+
+ bool expecting_global_attribs = false;
+ bool expecting_local_attribs = false;
+
+ bool local_attrib_section_added = false;
%}
%token EOF
%token DEFAULT
%token DELEGATE
%token DIM
+%token DIRECTCAST
%token DO
%token DOUBLE
%token EACH
%token ELSE
%token ELSEIF
-%token END
+%token END
+%token ENDIF
%token ENUM
%token EOL
%token ERASE
%token FRIEND
%token FUNCTION
%token GET
-//%token GETTYPE
+%token GETTYPE
+%token GOSUB
%token GOTO
%token HANDLES
%token IF
%token UNICODE
%token UNTIL
%token VARIANT
+%token WEND
%token WHEN
%token WHILE
%token WITH
%token XOR
%token YIELD // MonoBASIC extension
+%token HASH
+
/* MonoBASIC single character operators/punctuation. */
%token OPEN_BRACKET "["
%token DIV "/"
%token OP_EXP "^"
%token INTERR "?"
-%token OP_IDIV "\\"
+%token OP_IDIV "\\" //FIXME: This should be "\"
%token OP_CONCAT "&"
%token EXCLAMATION "!"
%token OP_NE "<>"
%token OP_XOR "xor"
//%token OP_MODULUS //"mod"
-%token OP_MULT_ASSIGN "*="
-%token OP_DIV_ASSIGN "/="
-%token OP_IDIV_ASSIGN "\\="
-%token OP_ADD_ASSIGN "+="
-%token OP_SUB_ASSIGN "-="
-%token OP_CONCAT_ASSIGN "&="
-%token OP_EXP_ASSIGN "^="
/* VB.NET 2003 new bit-shift operators */
%token OP_SHIFT_LEFT "<<"
%start compilation_unit
%%
+end_of_stmt
+ : logical_end_of_line
+ | COLON
+ ;
+
+logical_end_of_line
+ : EOL
+ | logical_end_of_line pp_directive
+ ;
+
compilation_unit
- : opt_option_directives
+ : logical_end_of_line
+ opt_option_directives
+ opt_imports_directives
+ declarations
+ EOF
+ {
+ $$=$4;
+ }
+ |logical_end_of_line
+ opt_option_directives
opt_imports_directives
opt_attributes
- opt_declarations
EOF
{
- $$ = $4;
+ /* ????? */ ;
}
;
;
option_explicit_directive
- : OPTION EXPLICIT on_off EOL
+ : OPTION EXPLICIT on_off logical_end_of_line
{
if (!UseExtendedSyntax)
OptionExplicit = (bool)$3;
option_strict_directive
- : OPTION STRICT on_off EOL
+ : OPTION STRICT on_off logical_end_of_line
{
if (!UseExtendedSyntax)
OptionStrict = (bool)$3;
;
option_compare_directive
- : OPTION COMPARE text_or_binary EOL
+ : OPTION COMPARE text_or_binary logical_end_of_line
{
OptionCompareBinary = (bool)$3;
}
opt_declarations
: /* empty */
| declarations
- ;
+ ;
declarations
: declaration
;
declaration
- : namespace_declaration
- | type_declaration
+ : declaration_qualifiers
+ {
+ // FIXME: Need to check declaration qualifiers for multi-file compilation
+ // FIXME: Qualifiers cannot be applied to namespaces
+ allow_global_attribs = false;
+ }
+ namespace_declaration
+ |declaration_qualifiers
+ {
+ // FIXME: Need to check declaration qualifiers for multi-file compilation
+ allow_global_attribs = false;
+ }
+ type_spec_declaration
{
string name = "";
int mod_flags;
- if ($1 is Class || $1 is Struct || $1 is Module ){
- TypeContainer c = (TypeContainer) $1;
+ if ($3 is Class || $3 is Struct || $3 is Module ){
+ TypeContainer c = (TypeContainer) $3;
mod_flags = c.ModFlags;
name = c.Name;
} else
break;
- if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+ if ((mod_flags & (Modifiers.PRIVATE)) != 0){
+ Report.Error (
+ 31089, lexer.Location,
+ "Namespace elements cannot be explicitly " +
+ "declared private in '" + name + "'");
+ }
+ else if ((mod_flags & (Modifiers.PROTECTED)) != 0){
Report.Error (
- 1527, lexer.Location,
+ 31047, lexer.Location,
"Namespace elements cannot be explicitly " +
- "declared private or protected in '" + name + "'");
+ "declared protected in '" + name + "'");
}
}
;
qualified_identifier
: identifier
- | qualified_identifier DOT identifier
+ | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
{
$$ = (($1).ToString ()) + "." + ($3.ToString ());
}
;
imports_directive
- : IMPORTS imports_terms EOL
+ : IMPORTS imports_terms logical_end_of_line
;
imports_terms
: imports_term
- | imports_terms COMMA imports_terms
+ | imports_terms COMMA imports_term
;
imports_term
- : qualified_identifier
+ : namespace_or_type_name
{
RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
}
- | qualified_identifier ASSIGN qualified_identifier
+ | identifier ASSIGN namespace_or_type_name
{
RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
}
;
-opt_attributes
- : /* empty */
- | attribute_sections { $$ = $1; }
+opt_params
+ : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
+ | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
+ | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
;
-attribute_sections
- : attribute_section
- {
- AttributeSection sect = (AttributeSection) $1;
+opt_attributes
+ : /* empty */
+ | attribute_sections
+ {
+ $$ = $1;
+ local_attrib_section_added = false;
+ }
+ ;
- if (sect.Target == "assembly")
- RootContext.AddGlobalAttributeSection (current_container, sect);
-
- $$ = new Attributes ((AttributeSection) $1, lexer.Location);
-
- }
- /*
- FIXME: we should check if extended syntax is enabled;
- otherwise an exception should be thrown since VB.NET
- only allows one attribute section
- */
- | attribute_sections attribute_section
- {
- Attributes attrs = null;
- AttributeSection sect = (AttributeSection) $2;
-
- if (sect.Target == "assembly")
- RootContext.AddGlobalAttributeSection (current_container, sect);
-
- if ($1 != null) {
- attrs = (Attributes) $1;
- attrs.AddAttributeSection (sect);
- }
-
- $$ = attrs;
- }
- ;
-
-attribute_section
- : OP_LT attribute_target_specifier attribute_list OP_GT
+attribute_sections
+ : attribute_section
{
- string target = null;
-
- if ($2 != null)
- target = (string) $2;
+ $$ = $1;
+ if ($1 == null) {
+ expecting_local_attribs = false;
+ expecting_global_attribs = false;
+ break;
+ }
- $$ = new AttributeSection (target, (ArrayList) $3);
- }
- | OP_LT attribute_list OP_GT
- {
- $$ = new AttributeSection (null, (ArrayList) $2);
- }
- ;
+ if (expecting_local_attribs) {
+ local_attrib_section_added = true;
+ allow_global_attribs = false;
-attribute_target_specifier
- : attribute_target COLON
+ $$ = new Attributes ((ArrayList) $1);
+ }
+
+ if (expecting_global_attribs) {
+ $$ = null;
+ CodeGen.AddGlobalAttributes ((ArrayList) $1);
+ }
+
+ expecting_local_attribs = false;
+ expecting_global_attribs = false;
+ }
+ | attribute_sections
+ {
+ $$ = lexer.Location;
+ }
+ attribute_section
{
- $$ = $1;
+ $$ = $1;
+ if ($3 != null) {
+ ArrayList attrs = (ArrayList) $3;
+
+ if (expecting_local_attribs) {
+ if (local_attrib_section_added) {
+ expecting_local_attribs = false;
+ expecting_global_attribs = false;
+ Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
+ break;
+ }
+
+ if ($1 == null)
+ $$ = new Attributes (attrs);
+ else
+ ((Attributes) $1).Add (attrs);
+
+ local_attrib_section_added = true;
+ allow_global_attribs = false;
+ }
+
+ if (expecting_global_attribs) {
+ $$ = null;
+ CodeGen.AddGlobalAttributes ((ArrayList) $3);
+ }
+ }
+
+ expecting_local_attribs = false;
+ expecting_global_attribs = false;
}
;
-attribute_target
- : identifier
- {
- CheckAttributeTarget ((string) $1);
- $$ = $1;
- }
- | EVENT { $$ = "event"; }
- | RETURN { $$ = "return"; }
+attribute_section
+ : OP_LT attribute_list OP_GT opt_end_of_stmt
+ {
+ $$ = null;
+ if ($2 != null) {
+ if (expecting_global_attribs && !(bool) $4) {
+ Report.Error (30205, lexer.Location, "End of statement expected");
+ break;
+ }
+
+ if (expecting_local_attribs) {
+ if ((bool) $4) {
+ Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
+ break;
+ }
+ }
+
+ $$ = $2;
+ }
+ }
+ ;
+
+opt_end_of_stmt
+ : /* empty */ { $$ = false; }
+ | end_of_stmt { $$ = true; }
;
-
+
attribute_list
- : attribute
- {
- ArrayList attrs = new ArrayList ();
- attrs.Add ($1);
+ : attribute
+ {
+ ArrayList attrs = null;
+ if ($1 != null) {
+ attrs = new ArrayList ();
+ attrs.Add ($1);
+ }
+ $$ = attrs;
+ }
+ | attribute_list COMMA attribute
+ {
+ ArrayList attrs = null;
+
+ if ($3 != null) {
+ attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
+ attrs.Add ($3);
+ }
- $$ = attrs;
-
- }
- | attribute_list COMMA attribute
- {
- ArrayList attrs = (ArrayList) $1;
- attrs.Add ($3);
+ $$ = attrs;
+ }
+ ;
- $$ = attrs;
- }
- ;
-
attribute
- : attribute_name
- {
- $$ = lexer.Location;
- }
- opt_attribute_arguments
- {
- $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
- }
+ : namespace_or_type_name
+ {
+ $$ = lexer.Location;
+ }
+ opt_attribute_arguments
+ {
+ $$ = null;
+
+ if (expecting_global_attribs)
+ Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
+ else {
+ expecting_local_attribs = true;
+ $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+ }
+ }
+ | attribute_target_specifier
+ {
+ $$ = lexer.Location;
+ }
+ COLON
+ namespace_or_type_name
+ {
+ $$ = lexer.Location;
+ }
+ opt_attribute_arguments
+ {
+ $$ = null;
+
+ string attribute_target = (string) $1;
+ if (attribute_target != "assembly" && attribute_target != "module") {
+ Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
+ break;
+ }
+ if (!allow_global_attribs) {
+ Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
+ break;
+ }
+
+ if (expecting_local_attribs) {
+ Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
+ break;
+ }
+
+ expecting_global_attribs = true;
+ $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
+ }
+ ;
+
+attribute_target_specifier
+ : ASSEMBLY { $$ = "assembly"; }
+ | MODULE { $$ = "module"; }
+ | namespace_or_type_name
;
-attribute_name
- : type_name
- ;
opt_attribute_arguments
: /* empty */ { $$ = null; }
- | OPEN_PARENS attribute_arguments CLOSE_PARENS
+ | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
{
$$ = $2;
}
;
+
+opt_attribute_arguments_list
+ : /* empty */
+ | attribute_arguments_list
+ ;
-attribute_arguments
- : opt_positional_argument_list
+attribute_arguments_list
+ : positional_argument_list
{
- if ($1 == null)
- $$ = null;
- else {
- ArrayList args = new ArrayList ();
- args.Add ($1);
-
- $$ = args;
- }
+ ArrayList args = new ArrayList ();
+ args.Add ($1);
+
+ $$ = args;
}
| positional_argument_list COMMA named_argument_list
{
}
;
-
-opt_positional_argument_list
- : /* empty */ { $$ = null; }
- | positional_argument_list
- ;
-
positional_argument_list
- : expression
+ : constant_expression
{
ArrayList args = new ArrayList ();
args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
$$ = args;
}
- | positional_argument_list COMMA expression
+ | positional_argument_list COMMA constant_expression
{
ArrayList args = (ArrayList) $1;
args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
;
named_argument
- : identifier ATTR_ASSIGN expression
+ : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
{
$$ = new DictionaryEntry (
(string) $1,
;
namespace_declaration
- : opt_attributes NAMESPACE qualified_identifier EOL
+ : NAMESPACE qualified_identifier logical_end_of_line
{
- Attributes attrs = (Attributes) $1;
-
- if (attrs != null) {
- foreach (AttributeSection asec in attrs.AttributeSections)
- if (asec.Target == "assembly")
- RootContext.AddGlobalAttributeSection (current_container, asec);
- }
-
- current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
+ current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2);
}
- opt_imports_directives
opt_declarations
- END NAMESPACE EOL
+ END NAMESPACE logical_end_of_line
{
current_namespace = current_namespace.Parent;
}
;
-type_declaration
+declaration_qualifiers
: opt_attributes
opt_modifiers
{
current_attributes = (Attributes) $1;
current_modifiers = (int) $2;
}
- type_spec_declaration
;
type_spec_declaration
;
class_declaration
- : CLASS identifier EOL opt_inherits opt_implements
+ : CLASS identifier end_of_stmt opt_inherits opt_implements
{
// Module members are static by default, but Class *can't* be declared static
// so we must fix it, if mbas was the one actually responsible for this
RootContext.Tree.RecordDecl (name, new_class);
}
opt_class_member_declarations
- END CLASS EOL
+ END CLASS logical_end_of_line
{
Class new_class = (Class) current_container;
- new_class.Bases = (ArrayList) $4;
+
+ ArrayList bases = (ArrayList) $4;
+
+ ArrayList ifaces = (ArrayList) $5;
+ if (ifaces != null){
+ if (bases != null)
+ bases.AddRange(ifaces);
+ else
+ bases = ifaces;
+ }
+ new_class.Bases = bases;
current_container = current_container.Parent;
CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
opt_inherits
: /* empty */ { $$ = null; }
- | INHERITS type_list EOL { $$ = $2; }
+ | INHERITS type_list end_of_stmt { $$ = $2; }
;
opt_implements
: /* empty */ { $$ = null; }
- | IMPLEMENTS type_list EOL { $$ = $2; }
+ | IMPLEMENTS type_list end_of_stmt { $$ = $2; }
;
opt_modifiers
;
module_declaration
- : MODULE identifier EOL
+ : MODULE identifier logical_end_of_line
{
Module new_module;
string name;
RootContext.Tree.RecordDecl(name, new_module);
}
opt_module_member_declarations
- END MODULE EOL
+ END MODULE logical_end_of_line
{
Module new_module = (Module)current_container;
;
constant_declaration
- : CONST constant_declarators EOL
+ : CONST constant_declarators end_of_stmt
{
// Module members are static by default, but constants *can't* be declared static
// so we must fix it, if mbas was the one actually responsible for this
;
must_override_sub_declaration
- : MUSTOVERRIDE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
+ : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
{
if (current_container is Module)
Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
current_modifiers |= Modifiers.ABSTRACT;
Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
- (Parameters) $5, null, null, lexer.Location);
+ (Parameters) $4, null, (ArrayList) $5, lexer.Location);
if (!(current_container is Class))
Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
- // FIXME ASAP: This will crash the compiler at resolution time
$$ = method;
}
;
must_override_func_declaration
- : MUSTOVERRIDE FUNCTION identifier opt_type_character OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks EOL
+ : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
{
- Expression ftype = ($8 == null) ? (($4 == null) ? TypeManager.
- system_object_expr : (Expression) $4 ) : (Expression) $8;
+ Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.
+ system_object_expr : (Expression) $4 ) : (Expression) $6;
if (current_container is Module)
Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
current_modifiers |= Modifiers.ABSTRACT;
Method method = new Method ((Expression) ftype, (int) current_modifiers,
- (string) $3,(Parameters) $6, null, null,
+ (string) $3,(Parameters) $5, null, (ArrayList) $7,
lexer.Location);
if (!(current_container is Class))
;
sub_declaration
- : SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler opt_implement_clause EOL
+ : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
{
- current_local_parameters = (Parameters) $4;
+ current_local_parameters = (Parameters) $3;
start_block();
// Structure members are Public by default
if ((current_container is Struct) && (current_modifiers == 0))
current_modifiers = Modifiers.PUBLIC;
-
+
member_location = lexer.Location;
}
opt_statement_list
- END SUB EOL
+ END SUB logical_end_of_line
{
Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
(Parameters) current_local_parameters, (Attributes) current_attributes,
- (Expression) $7, member_location);
+ (ArrayList) $5, member_location);
method.Block = (Block) end_block();
$$ = method;
- if ($6 != null) { /* we have an event handler to take care of */
- // This wouldn't work: AddHandler ((Expression)$6, (string) $2);
- string evt_def = ((MemberAccess)$6).ToString();
+ if ($4 != null) {
+ // we have an event handler to take care of
+
+ Expression handles_exp = (Expression) $4;
+ Location loc = lexer.Location;
+
+ if (handles_exp is MemberAccess) {
+ string evt_def = ((MemberAccess)$4).ToString();
int pos = evt_def.LastIndexOf (".");
- string evt_target = ((string) $2).Substring (0, pos);
+ string evt_target = evt_def.Substring (0, pos);
+ bool found = false;
+
+ if (current_container.Properties != null) {
+ foreach (Property p in current_container.Properties) {
+ if (p.Name == evt_target) {
+
- foreach (Property p in current_container.Properties) {
- if (p.Name == evt_target) {
- // FIXME: See below
- // RemoveHandler (p.Set.Block, (Expression)$6, (string) $2);
- AddHandler (p.Set.Block, (Expression)$6, (string) $2);
- break;
- }
- }
+ Statement addhnd = (Statement) new AddHandler ((Expression) $4,
+ DecomposeQI((string) $2, loc),
+ loc);
+
+ current_container.AddEventHandler (addhnd);
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found){
+ Report.Error(30506, lexer.Location,
+ evt_target + " is not declared with WithEvents");
+ }
+ } else if (handles_exp is BaseAccess) {
+ Statement addhnd = (Statement) new AddHandler ((Expression) $4,
+ DecomposeQI((string) $2, loc),
+ loc);
+
+ current_container.AddEventHandler (addhnd);
+ }
+
}
}
;
func_declaration
: FUNCTION identifier opt_type_character
- OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks opt_implement_clause EOL
+ opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
{
- current_local_parameters = (Parameters) $5;
+ current_local_parameters = (Parameters) $4;
member_location = lexer.Location;
start_block();
- Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
+ Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
// Structure members are Public by default
if ((current_container is Struct) && (current_modifiers == 0))
declare_local_variables ((Expression) ftype, retval, lexer.Location);
}
opt_statement_list
- END FUNCTION EOL
+ END FUNCTION logical_end_of_line
{
- Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
+ Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
(Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
- (Expression) $8, member_location);
+ (ArrayList) $6, member_location);
method.Block = end_block();
$$ = method;
}
;
struct_declaration
- : STRUCTURE identifier EOL
+ : STRUCTURE identifier end_of_stmt
opt_implement_clause
{
Struct new_struct;
CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
$$ = new_struct;
}
- END STRUCTURE EOL
+ END STRUCTURE logical_end_of_line
;
opt_struct_member_declarations
;
event_declaration
- : EVENT identifier AS type EOL
+ : EVENT identifier AS type opt_implement_clause logical_end_of_line
{
VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
Event e = new Event ((Expression) $4, var.identifier,
- null, current_modifiers, null, null,
- current_attributes, lexer.Location);
+ null, current_modifiers,
+ current_attributes, (ArrayList) $5,
+ lexer.Location);
CheckDef (current_container.AddEvent (e), e.Name, e.Location);
-
}
- | EVENT identifier opt_event_params EOL
+ | EVENT identifier opt_params opt_implement_clause logical_end_of_line
{
- string delName = (string) $2;
- delName = delName + "EventHandler";
- Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
- (current_container, TypeManager.system_void_expr,
- (int) current_modifiers, MakeName(delName), (Parameters) $3,
- (Attributes) current_attributes, lexer.Location);
-
- del.Namespace = current_namespace;
- CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
-
+ string delName = null;
+
+ if ($4 == null) {
+ delName = (string) $2;
+ delName = delName + "EventHandler";
+ Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
+ (current_container, TypeManager.system_void_expr,
+ (int) current_modifiers, MakeName(delName), (Parameters) $3,
+ (Attributes) current_attributes, lexer.Location);
+
+ del.Namespace = current_namespace;
+ CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
+ } else {
+ ArrayList impls = (ArrayList) $4;
+ if (impls.Count > 1) {
+ string expstr = "Event '" + ((Expression) impls[1]).ToString () +
+ "' can not be implemented with Event '" +
+ (string) $2 + "', since it's delegate type does not match " +
+ "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
+ Report.Error (31407, lexer.Location, expstr);
+ }
+ Expression impl = (Expression) impls[0];
+ delName = impl.ToString();
+ delName = delName.Substring (delName.LastIndexOf(".") + 1);
+ delName = delName + "EventHandler";
+ }
+
Event e = new Event (DecomposeQI (delName, lexer.Location),
(string) $2,
- null, current_modifiers, null, null,
- current_attributes, lexer.Location);
+ null, current_modifiers,
+ current_attributes, (ArrayList) $4,
+ lexer.Location);
CheckDef (current_container.AddEvent (e), e.Name, e.Location);
}
;
-opt_event_params
- : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
- | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
- | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
- ;
-
enum_declaration
- : ENUM identifier opt_type_spec EOL
- opt_enum_member_declarations
+ : ENUM identifier opt_type_spec logical_end_of_line
+ opt_enum_member_declarations
{
Location enum_location = lexer.Location;
string full_name = MakeName ((string) $2);
Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
ArrayList enum_members = (ArrayList) $5;
+ if (enum_members.Count == 0)
+ Report.Error (30280, enum_location,
+ "Enum can not have empty member list");
+
// Module members are static by default, but enums *can't* be declared static
// so we must fix it if mbas was the one actually responsible for this
// instead of triggering an error.
RootContext.Tree.RecordDecl (full_name, e);
}
- END ENUM EOL
+ END ENUM logical_end_of_line
;
opt_enum_member_declarations
;
enum_member_declaration
- : opt_attributes identifier EOL
+ : opt_attributes identifier logical_end_of_line
{
$$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
}
{
$$ = lexer.Location;
}
- ASSIGN expression EOL
+ ASSIGN expression logical_end_of_line
{
$$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
}
;
interface_declaration
- : INTERFACE identifier EOL
+ : INTERFACE identifier logical_end_of_line
{
Interface new_interface;
string full_interface_name = MakeName ((string) $2);
new_interface.Name, new_interface.Location);
}
- END INTERFACE EOL
+ END INTERFACE logical_end_of_line
;
opt_interface_base
: /* empty */ { $$ = null; }
- | interface_base
+ | interface_bases
;
-interface_base
- : INHERITS interface_type_list { $$ = $2; }
- ;
-
-interface_type_list
- : interface_type
- {
- ArrayList interfaces = new ArrayList ();
-
- interfaces.Add ($1);
- $$ = interfaces;
- }
- | interface_type_list COMMA interface_type
+interface_bases
+ : interface_base
+ | interface_bases interface_base
{
- ArrayList interfaces = (ArrayList) $1;
- interfaces.Add ($3);
- $$ = interfaces;
+ ArrayList bases = (ArrayList) $1;
+ bases.AddRange ((ArrayList) $2);
+ $$ = bases;
}
;
+interface_base
+ : INHERITS type_list logical_end_of_line { $$ = $2; }
+ ;
+
interface_body
: opt_interface_member_declarations
;
;
interface_member_declaration
+ : opt_attributes
+ opt_modifiers
+ {
+ current_attributes = (Attributes) $1;
+ current_modifiers = ((int)$2) | Modifiers.ABSTRACT;
+ }
+ interface_member_declarator
+ {
+ $$ = $3;
+ }
+ ;
+
+interface_member_declarator
: interface_method_declaration
{
- InterfaceMethod m = (InterfaceMethod) $1;
-
+ Method m = (Method) $1;
CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
}
| interface_property_declaration
- {
- InterfaceProperty p = (InterfaceProperty) $1;
-
- CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
- }
| interface_event_declaration
- {
- InterfaceEvent e = (InterfaceEvent) $1;
-
- CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
- }
;
-opt_new
- : /* empty */ { $$ = false; }
- | NEW { $$ = true; }
- ;
-
interface_method_declaration
- : SUB identifier
- OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
+ : SUB identifier opt_params logical_end_of_line
{
- $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
- (Parameters) $4, current_attributes, lexer.Location);
- }
- | FUNCTION identifier opt_type_character
- OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
- {
- if ($3 != null && $3 != $8)
- Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
+ Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
+ (Parameters) $3, current_attributes, null, lexer.Location);
- $$ = new InterfaceMethod (
- (Expression) $8, (string) $2, false, (Parameters) $5,
- current_attributes, lexer.Location);
+ $$ = method;
}
- | FUNCTION identifier type_character
- OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+ | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
{
- $$ = new InterfaceMethod (
- (Expression) $3, (string) $2, false, (Parameters) $5,
- current_attributes, lexer.Location);
+ Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.
+ system_object_expr : (Expression) $3 ) : (Expression) $5;
+
+ Method method = new Method ((Expression) ftype, (int) current_modifiers,
+ (string) $2,(Parameters) $4, current_attributes, null,
+ lexer.Location);
+
+ $$ = method;
}
;
interface_property_declaration
- : opt_modifiers PROPERTY identifier
- OPEN_PARENS
- opt_formal_parameter_list
- CLOSE_PARENS opt_type_spec EOL
+ : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
{
- // FIXME we MUST pass property parameters
- $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
- true, true, current_attributes,
- lexer.Location);
+ Expression ftype = ($5 == null) ? (($3 == null) ?
+ TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+
+ current_local_parameters = (Parameters) $4;
+ if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
+ get_parameters = current_local_parameters.Copy (lexer.Location);
+ set_parameters = current_local_parameters.Copy (lexer.Location);
+
+ Parameter implicit_value_parameter = new Parameter (
+ ftype, "Value", Parameter.Modifier.NONE, null);
+
+ set_parameters.AppendParameter (implicit_value_parameter);
+ }
+ else
+ {
+ get_parameters = Parameters.EmptyReadOnlyParameters;
+ set_parameters = new Parameters (null, null ,lexer.Location);
+
+ Parameter implicit_value_parameter = new Parameter (
+ ftype, "Value", Parameter.Modifier.NONE, null);
+
+ set_parameters.AppendParameter (implicit_value_parameter);
+ }
+ lexer.PropertyParsing = true;
+
+ Accessor get_block = new Accessor (null, null);
+ Accessor set_block = new Accessor (null, null);
+
+ Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
+ get_block, set_block, current_attributes, lexer.Location,
+ null, get_parameters, set_parameters, null);
+
+ CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
+
+ get_implicit_value_parameter_type = null;
+ set_implicit_value_parameter_type = null;
+ get_parameters = null;
+ set_parameters = null;
+ current_local_parameters = null;
}
;
interface_event_declaration
- : opt_attributes opt_new EVENT type identifier EOL
+ : EVENT identifier AS type logical_end_of_line
{
- $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
- lexer.Location);
+ VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
+
+ Event e = new Event ((Expression) $4, var.identifier,
+ null, current_modifiers,
+ current_attributes, lexer.Location);
+
+ CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
+
+ }
+ | EVENT identifier opt_params logical_end_of_line
+ {
+ string delName = (string) $2;
+ delName = delName + "EventHandler";
+ int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
+ Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
+ (current_container, TypeManager.system_void_expr,
+ (int) delModifiers, MakeName(delName), (Parameters) $3,
+ (Attributes) current_attributes, lexer.Location);
+
+ del.Namespace = current_namespace;
+ CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
+
+ Event e = new Event (DecomposeQI (delName, lexer.Location),
+ (string) $2,
+ null, current_modifiers,
+ current_attributes, lexer.Location);
+
+ CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
}
;
- property_declaration
- : abstruct_propery_declaration
- | non_abstruct_propery_declaration
+property_declaration
+ : abstract_propery_declaration
+ | non_abstract_propery_declaration
;
-abstruct_propery_declaration
- : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters AS type EOL
+abstract_propery_declaration
+ : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
{
- Expression ftype = ($7 == null) ? (($4 == null) ?
- TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $7;
+ Expression ftype = ($6 == null) ? (($4 == null) ?
+ TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
if (current_container is Module)
Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
get_parameters = current_local_parameters.Copy (lexer.Location);
set_parameters = current_local_parameters.Copy (lexer.Location);
+
+ Parameter implicit_value_parameter = new Parameter (
+ ftype, "Value", Parameter.Modifier.NONE, null);
+
+ set_parameters.AppendParameter (implicit_value_parameter);
}
else
{
;
- non_abstruct_propery_declaration
- : PROPERTY identifier opt_type_character opt_property_parameters AS type opt_implement_clause EOL
- {
+ non_abstract_propery_declaration
+ : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
+ {
+ if ((current_modifiers & Modifiers.DEFAULT) > 0) {
+ if (current_container.DefaultPropName != null
+ && current_container.DefaultPropName != (string) $2)
+ Report.Error (30359,
+ lexer.Location,
+ "Type '" + current_container.Name +
+ "' cannot have more than one 'Default Property' ");
+
+ current_container.DefaultPropName = (string) $2;
+ }
+
get_implicit_value_parameter_type =
- ($6 == null) ? (($3 == null) ?
- TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
+ ($5 == null) ? (($3 == null) ?
+ TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
get_implicit_value_parameter_name = (string) $2;
current_local_parameters = (Parameters) $4;
$$ = lexer.Location;
}
accessor_declarations
- END PROPERTY EOL
+ END PROPERTY logical_end_of_line
{
lexer.PropertyParsing = false;
Property prop;
- Pair pair = (Pair) $10;
+ Pair pair = (Pair) $9;
Accessor get_block = null;
Accessor set_block = null;
if ((current_container is Struct) && (current_modifiers == 0))
current_modifiers = Modifiers.PUBLIC;
- prop = new Property ((Expression) /*$6*/ get_implicit_value_parameter_type,
+ prop = new Property ((Expression) get_implicit_value_parameter_type,
(string) $2, current_modifiers, get_block, set_block,
current_attributes, loc, set_implicit_value_parameter_name,
- get_parameters, set_parameters, (Expression) $7);
+ get_parameters, set_parameters, (ArrayList) $6);
CheckDef (current_container.AddProperty (prop), prop.Name, loc);
get_implicit_value_parameter_type = null;
{
$$ = null;
}
- | IMPLEMENTS qualified_identifier
+ | IMPLEMENTS implement_clause_list
+ {
+ $$ = $2;
+ }
+ ;
+
+implement_clause_list
+ : qualified_identifier
{
- $$ = DecomposeQI ((string)$2, lexer.Location);
+ ArrayList impl_list = new ArrayList ();
+ impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
+ $$ = impl_list;
}
+ | implement_clause_list COMMA qualified_identifier
+ {
+ ArrayList impl_list = (ArrayList) $1;
+ impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
+ $$ = impl_list;
+ }
+
;
accessor_declarations
;
get_accessor_declaration
- : opt_attributes GET EOL
+ : opt_attributes GET logical_end_of_line
{
if ((current_modifiers & Modifiers.WRITEONLY) != 0)
Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
}
opt_statement_list
- END GET EOL
+ END GET logical_end_of_line
{
$$ = new Accessor ((Block) end_block(), (Attributes) $1);
current_local_parameters = null;
;
set_accessor_declaration
- : opt_attributes SET opt_set_parameter EOL
+ : opt_attributes SET opt_set_parameter logical_end_of_line
{
if ((current_modifiers & Modifiers.READONLY) != 0)
Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
lexer.PropertyParsing = false;
}
opt_statement_list
- END SET EOL
+ END SET logical_end_of_line
{
$$ = new Accessor ((Block) end_block(), (Attributes) $1);
current_local_parameters = null;
set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
set_implicit_value_parameter_name = "Value";
}
- | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_spec CLOSE_PARENS
+ | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
{
Parameter.Modifier pm = (Parameter.Modifier)$2;
if ((pm | Parameter.Modifier.VAL) != 0)
set_implicit_value_parameter_type = (Expression) $4;
- if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
+ if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
Report.Error (31064,
lexer.Location,
"Set value parameter type can not be different from property type");
-
+
if ($2 != null)
set_implicit_value_parameter_name = (string) $3;
else
field_declaration
: opt_dim_stmt
- variable_declarators EOL
+ variable_declarators end_of_stmt
{
int mod = (int) current_modifiers;
-
VariableDeclaration.FixupTypes ((ArrayList) $2);
VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
;
withevents_declaration
- : WITHEVENTS variable_declarators EOL
+ : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
{
+ // Module members are static by default, but delegates *can't* be declared static
+ // so we must fix it, if mbas was the one actually responsible for this
+ // instead of triggering an error.
+ if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+ current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
/* WithEvents Fields must be resolved into properties
with a bit of magic behind the scenes */
- VariableDeclaration.FixupTypes ((ArrayList) $2);
+ VariableDeclaration.FixupTypes ((ArrayList) $3);
- foreach (VariableDeclaration var in (ArrayList) $2) {
+ foreach (VariableDeclaration var in (ArrayList) $3) {
// 1 - We create a private field
Location l = var.Location;
Property prop;
Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
var.expression_or_array_initializer,
(Attributes) null, l);
-
+
CheckDef (current_container.AddField (field), field.Name, l);
// 2 - Public property
identifier OPEN_PARENS
opt_formal_parameter_list
CLOSE_PARENS
- EOL
+ logical_end_of_line
{
Location l = lexer.Location;
// Module members are static by default, but delegates *can't* be declared static
| DELEGATE FUNCTION
identifier OPEN_PARENS
opt_formal_parameter_list
- CLOSE_PARENS AS type EOL
+ CLOSE_PARENS opt_type_with_ranks logical_end_of_line
{
Location l = lexer.Location;
if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+ Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
+
Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
current_container,
- (Expression) $8, (int) current_modifiers, MakeName ((string) $3),
+ ftype, (int) current_modifiers, MakeName ((string) $3),
(Parameters) $5, (Attributes) current_attributes, l);
del.Namespace = current_namespace;
;
opt_evt_handler
- : /* empty */
- { $$ = null; }
- | HANDLES qualified_identifier
+ : /* empty */ { $$ = null; }
+ | HANDLES evt_handler { $$ = $2; }
+ ;
+
+evt_handler
+ : qualified_identifier
{
- $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
+ $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);
}
- | HANDLES MYBASE DOT qualified_identifier
+ | base_access
+ {
+ $$ = $1;
+ }
+ | ME DOT qualified_identifier
+ {
+ $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);
+ }
+ /*| MYBASE DOT qualified_identifier
{
// FIXME: this is blatantly wrong and crash-prone
$$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
- }
- ;
-
-opt_empty_parens
- : /* empty */
- | OPEN_PARENS CLOSE_PARENS
- ;
+ }*/
+ ;
constructor_declaration
- : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
+ : SUB NEW opt_params logical_end_of_line
{
- current_local_parameters = (Parameters) $4;
+ current_local_parameters = (Parameters) $3;
start_block();
oob_stack.Push (lexer.Location);
Location l = (Location) oob_stack.Pop ();
- $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
+ $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
$1 = $$;
}
opt_statement_list
CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
current_local_parameters = null;
}
- END SUB EOL
+ END SUB logical_end_of_line
;
opt_formal_parameter_list
;
formal_parameter_list
- : fixed_parameters
+ : parameters
{
ArrayList pars_list = (ArrayList) $1;
-
- Parameter [] pars = new Parameter [pars_list.Count];
- pars_list.CopyTo (pars);
- $$ = new Parameters (pars, null, lexer.Location);
+ Parameter [] pars = null;
+ Parameter array_parameter = null;
+ int non_array_count = pars_list.Count;
+ if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
+ array_parameter = (Parameter) pars_list [pars_list.Count - 1];
+ non_array_count = pars_list.Count - 1;
+ }
+ foreach (Parameter par in pars_list)
+ if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
+ Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
+ non_array_count = 0;
+ array_parameter = null;
+ break;
+ }
+ if (non_array_count > 0) {
+ pars = new Parameter [non_array_count];
+ pars_list.CopyTo (0, pars, 0, non_array_count);
+ }
+ $$ = new Parameters (pars, array_parameter, lexer.Location);
}
- | fixed_parameters COMMA parameter_array
- {
- ArrayList pars_list = (ArrayList) $1;
-
- Parameter [] pars = new Parameter [pars_list.Count];
- pars_list.CopyTo (pars);
-
- $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
- }
- | parameter_array
- {
- $$ = new Parameters (null, (Parameter) $1, lexer.Location);
- }
;
-fixed_parameters
- : fixed_parameter
+parameters
+ : parameter
{
ArrayList pars = new ArrayList ();
pars.Add ($1);
$$ = pars;
}
- | fixed_parameters COMMA fixed_parameter
+ | parameters COMMA parameter
{
ArrayList pars = (ArrayList) $1;
}
;
-fixed_parameter
+parameter
: opt_attributes
opt_parameter_modifier
- identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
+ identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
{
Parameter.Modifier pm = (Parameter.Modifier)$2;
bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
Expression ptype;
if (opt_parm && ($7 == null))
- Report.Error (999, "Optional parameters must have a default value");
+ Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
+
+ if (!opt_parm && ($7 != null))
+ Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
+
+ if ((pm & Parameter.Modifier.PARAMS) != 0) {
+ if ((pm & ~Parameter.Modifier.PARAMS) != 0)
+ Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
+ }
- if (opt_parm) {
- if ((pm & Parameter.Modifier.REF) !=0)
- pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
- else
- pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
- }
+ if ((pm & Parameter.Modifier.REF) !=0)
+ pm |= Parameter.Modifier.ISBYREF;
if ($4 != null && $6 != null && $4 != $6)
- Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
+ Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
if ($5 != null) {
- string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
- ptype = DecomposeQI (t, lexer.Location);
- }
+ string t = ptype.ToString ();
+ if (t.IndexOf('[') >= 0)
+ Report.Error (31087, lexer.Location, "Array types specified in too many places");
+ else
+ ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
+ }
+ if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
+ Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
$$ = new Parameter (ptype, (string) $3, pm,
(Attributes) $1, (Expression) $7, opt_parm);
}
;
-parameter_array
- : PARAM_ARRAY identifier opt_parens AS type
- {
- string s_patype = ((Expression) $5).ToString();
- if ((bool) $3)
- s_patype += "[]";
-
- Expression patype = DecomposeQI (s_patype, Location.Null);
- $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
- // note ("type must be a single-dimension array type");
- }
- ;
-
-opt_parens
- : /* empty */
- { $$ = false; }
- | OPEN_PARENS CLOSE_PARENS
- { $$ = true; }
- ;
-
opt_parameter_modifier
: /* empty */ { $$ = Parameter.Modifier.VAL; }
| parameter_modifiers { $$ = $1; }
: BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
| BYVAL { $$ = Parameter.Modifier.VAL; }
| OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
+ | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
;
opt_statement_list
| statement_list end_of_stmt statement
;
-statement :
- declaration_statement
+statement
+ : declaration_statement
{
- if ($1 != null && (Block) $1 != current_block){
+ if ($1 != null && (Block) $1 != current_block){
current_block.AddStatement ((Statement) $1);
current_block = (Block) $1;
- }
+ }
}
| embedded_statement
{
- Statement s = (Statement) $1;
-
- current_block.AddStatement ((Statement) $1);
+ current_block.AddStatement ((Statement) $1);
}
| labeled_statement
- | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
- {
- AddHandler ((Expression) $2, (string) $5);
- }
+ | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
+ {
+ AddHandler ((Expression) $2, (Expression) $5);
+ }
+ | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
+ {
+ RemoveHandler ((Expression) $2, (Expression) $5);
+ }
| RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
{
- RaiseEvent ((string) $2, (ArrayList) $3);
+ RaiseEvent ((string) $2, (ArrayList) $3);
}
/* | array_handling_statement */
/* | empty_statement */
| with_statement
{
- Statement s = (Statement) $1;
-
- current_block.AddStatement ((Statement) $1);
+ current_block.AddStatement ((Statement) $1);
}
;
}
;
+label_name
+ : identifier
+ | LITERAL_INTEGER
+ {
+ $$ = $1.ToString();
+ }
+ ;
+
labeled_statement
- : identifier COLON end_of_stmt
+ : label_name COLON
+ {
+ LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
+
+ if (!current_block.AddLabel ((string) $1, labeled)){
+ Location l = lexer.Location;
+ Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
+ }
+ current_block.AddStatement (labeled);
+ }
+ | label_name COLON
{
LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
| selection_statement
| iteration_statement
| try_statement
+ | synclock_statement
| jump_statement
| array_handling_statement
;
;
goto_statement
- : GOTO identifier
+ : GOTO label_name
{
$$ = new Goto (current_block, (string) $2, lexer.Location);
}
;
foreach_statement
- : FOR EACH identifier IN
+ : FOR EACH identifier opt_type_spec IN
{
oob_stack.Push (lexer.Location);
}
expression end_of_stmt
{
-
- start_block();
- Block foreach_block = current_block;
Location l = lexer.Location;
LocalVariableReference v = null;
VariableInfo vi;
- vi = foreach_block.GetVariableInfo ((string) $3);
- if (vi != null) {
- // Get a reference to this variable.
- v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
+ if ($4 != null)
+ {
+ start_block();
+ VariableDeclaration decl = new VariableDeclaration ((string) $3,
+ (Expression) $4, null, lexer.Location, null);
+
+ vi = current_block.AddVariable (
+ (Expression) $4, decl.identifier, current_local_parameters, decl.Location);
+
+ Expression expr;
+ if (decl.expression_or_array_initializer is Expression)
+ expr = (Expression) decl.expression_or_array_initializer;
+ else if (decl.expression_or_array_initializer == null)
+ expr = null;
+ else
+ {
+ ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+ expr = new ArrayCreation ((Expression) $4, "", init, decl.Location);
+ }
+
+ v = new LocalVariableReference (current_block, decl.identifier, l);
+
+ if (expr != null)
+ {
+ Assign a = new Assign (v, expr, decl.Location);
+ current_block.AddStatement (new StatementExpression (a, lexer.Location));
+ }
}
else
- Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
-
+ {
+ vi = current_block.GetVariableInfo ((string) $3);
+
+ if (vi != null) {
+ // Get a reference to this variable.
+ v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
+ }
+ else
+ Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
+ }
+
oob_stack.Push (v);
+ start_block();
}
opt_statement_list
NEXT opt_identifier
{
- Block foreach_block = current_block;
LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
- Block prev_block = end_block();
+ Block foreach_block = end_block();
Location l = (Location) oob_stack.Pop ();
Foreach f = null;
- if (v != null) {
- f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
- }
+ if (v != null)
+ f = new Foreach (null, v, (Expression) $7, foreach_block, l);
- $$ = f;
+ if ($4 != null)
+ {
+ current_block.AddStatement (f);
+ $$ = end_block ();
+ }
+ else
+ $$ = f;
}
;
}
;
-
+synclock_statement
+ : SYNCLOCK expression end_of_stmt
+ {
+ start_block();
+ }
+ opt_statement_list
+ END SYNCLOCK
+ {
+ $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
+ }
+ ;
try_statement
: try_catch
| identifier
;
+opt_when
+ : /* empty */ { $$ = null; }
+ | WHEN boolean_expression { $$ = $2; }
+ ;
+
catch_clause
- : CATCH opt_catch_args end_of_stmt
+ : CATCH opt_catch_args opt_when end_of_stmt
{
Expression type = null;
string id = null;
one.Add (new VariableDeclaration (id, type, loc));
-
$1 = current_block;
current_block = new Block (current_block);
Block b = declare_local_variables (type, one, loc);
current_block = b;
}
}
-
}
opt_statement_list {
Expression type = null;
current_block = current_block.Parent;
}
}
-
- $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
+ $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, lexer.Location);
}
- ;
+ ;
opt_catch_args
: /* empty */ { $$ = null; }
}
;
-
for_statement
- : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
+ : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
{
- start_block();
+ if ($3 != null)
+ {
+ start_block();
+ ArrayList VarDeclaration = new ArrayList ();
+ VarDeclaration.Add (new VariableDeclaration ((string) $2,
+ (Expression) $3, null, lexer.Location, null));
+
+ DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
+ Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
+ current_block = b;
+ }
+ oob_stack.Push (lexer.Location);
+ start_block();
}
opt_statement_list
NEXT opt_identifier
{
- Block statement = end_block();
- Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
-
- Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
- Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
- for_var, (Expression) $6, lexer.Location);
- Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
- for_var, (Expression) $7, lexer.Location), lexer.Location);
-
- Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
- Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
-
- $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
- }
+ Block inner_statement = end_block();
+ Location l = (Location) oob_stack.Pop ();
+ Expression for_var = (Expression) DecomposeQI ((string)$2, l);
+
+ Expression assign_expr = new Assign (for_var, (Expression) $5, l);
+ Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
+ for_var, (Expression) $7, l);
+ Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
+ for_var, (Expression) $8, l), l);
+
+ Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
+ Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
+
+ For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
+ if ($3 != null)
+ {
+ current_block.AddStatement (f);
+ $$ = end_block();
+ }
+ else
+ $$ = f;
+ }
;
opt_step
{
$$ = $3;
}
- | if_statement_open THEN pre_embedded_statement
+ | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
{
- Location l = (Location) oob_stack.Pop ();
- tmp_expr = (Expression)expr_stack.Pop();
- $$ = new If ((Expression) tmp_expr, end_block(), l);
+ if ($4 == null)
+ {
+ Location l = (Location) oob_stack.Pop ();
+ tmp_expr = (Expression)expr_stack.Pop();
+ $$ = new If ((Expression) tmp_expr, end_block(), l);
+ }
+ else
+ {
+ Location l = (Location) oob_stack.Pop ();
+ tmp_expr = (Expression)expr_stack.Pop();
+ tmp_block = (Block) tmp_blocks.Pop ();
+ $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
+ }
+ }
+ | if_statement_open THEN else_pre_embedded_statement
+ {
+ Location l = (Location) oob_stack.Pop ();
+ tmp_expr = (Expression)expr_stack.Pop();
+ tmp_block = (Block) tmp_blocks.Pop ();
+ $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
}
;
pre_embedded_statement
: embedded_statement
{
- Statement s = (Statement) $1;
-
current_block.AddStatement ((Statement) $1);
}
;
+
+opt_else_pre_embedded_statement
+ : /* empty */
+ | else_pre_embedded_statement
+ ;
+
+else_pre_embedded_statement
+ : ELSE
+ {
+ Block bl = end_block();
+ tmp_blocks.Push(bl);
+
+ start_block();
+ }
+ | ELSE embedded_statement
+ {
+ Block bl = end_block();
+ tmp_blocks.Push(bl);
+
+ start_block();
+ current_block.AddStatement ((Statement) $2);
+ }
+ ;
if_statement_open
: IF boolean_expression
END IF
{
Location l = (Location) oob_stack.Pop ();
- Expression expr = (Expression)expr_stack.Pop();
+ Expression expr = (Expression)expr_stack.Pop();
$$ = new If ((Expression) expr, (Statement) end_block(), l);
}
| end_of_stmt
ELSE end_of_stmt
{
Block bl = end_block();
- tmp_blocks.Push(bl);
+ tmp_blocks.Push(bl);
start_block();
}
opt_statement_list
topmost.statements.Add (new Break (lexer.Location));
$$ = new SwitchSection ((ArrayList) $2, topmost);
}
- | CASE ELSE ends
+ | CASE ELSE ends
/* FIXME: we should somehow flag an error
(BC30321 'Case' cannot follow a 'Case Else'
in the same 'Select' statement.)
;
array_creation_expression
- : object_creation_expression array_initializer
+ : object_creation_expression opt_rank_specifiers array_initializer
{
New n = (New) $1;
ArrayList dims = new ArrayList();
Expression atype = n.RequestedType;
- ArrayList init = (ArrayList) $2;
+ if ($2 != null)
+ atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
+
+ ArrayList init = (ArrayList) $3;
if (init.Count == 0)
init = null;
else
{
string rank = VariableDeclaration.BuildRank (dims);
- $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
+ $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location);
}
//Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
}
;
-delegate_creation_expression
- : NEW type OPEN_PARENS ADDRESSOF opt_argument_list CLOSE_PARENS
- {
- New n = new New ((Expression) $2, (ArrayList) $5, lexer.Location);
- if (n==null)
- Console.WriteLine("empty");
- $$ = n;
- }
- ;
-
new_expression
: object_creation_expression
| array_creation_expression
- | delegate_creation_expression
;
declaration_statement
string varname = (string) vname.Name;
current_rank_specifiers = (ArrayList) vname.Rank;
object varinit = $3;
- ArrayList a_dims = null;
if (varinit == null)
Report.Error (
Report.Error (30638, "Array bounds cannot appear in type specifiers.");
current_rank_specifiers = new ArrayList ();
- current_rank_specifiers.Add (args);
-
- /*string s_vartype = vartype.ToString();
- s_vartype += "[";
- if (args != null)
- for (int x = 0; x < args.Count; x++)
- s_vartype += ",";
-
- s_vartype += "]";
- vartype = DecomposeQI(s_vartype, Location.Null); */
+ current_rank_specifiers.Add (args);
}
else
vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
VariableDeclaration.VBFixIndexLists (ref a_dims);
varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
}
- vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
+ vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
}
if (vartype is New) {
: opt_type_spec
| AS type rank_specifiers
{
- $$ = TypeManager.system_object_expr;
+ $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
}
;
opt_type_decl
- : opt_type_spec
+ : opt_type_with_ranks
{
$$ = $1;
}
- | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
- {
- $$ = new Pair ($2, $4);
- }
| AS NEW type
{
New n = new New ((Expression)$3, null, lexer.Location);
New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
$$ = (Expression) n;
}
- | AS NEW type OPEN_PARENS ADDRESSOF opt_argument_list CLOSE_PARENS
+ /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
{
- New n = new New ((Expression)$3, (ArrayList) $6, lexer.Location);
+ ArrayList args = new ArrayList();
+ Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
+ args.Add (arg);
+
+ New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
$$ = (Expression) n;
- }
+ }*/
;
opt_array_name_modifier
;
rank_specifier
- : OPEN_PARENS opt_dim_separators CLOSE_PARENS
+ : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
{
$$ = $2;
}
;
-opt_dim_separators
+opt_dim_specifiers
: /* empty */
- {
- ArrayList ds = new ArrayList();
- ds.Add (new EmptyExpression());
- $$ = ds;
- }
- | dim_separators
- {
- ArrayList ds = (ArrayList) $1;
- ds.Add (new EmptyExpression());
- $$ = ds;
- }
- | dim_specifiers
- {
- $$ = $1;
- }
- ;
-
-dim_separators
- : COMMA
{
ArrayList ds = new ArrayList();
ds.Add (new EmptyExpression());
$$ = ds;
- }
- | dim_separators COMMA
- {
- ArrayList ds = (ArrayList) $1;
- ds.Add (new EmptyExpression());
- $$ = ds;
- }
- ;
-
-dim_specifiers
- : expression
+ }
+ | expression
{
ArrayList ds = new ArrayList();
ds.Add ((Expression) $1);
$$ = ds;
}
- | dim_specifiers COMMA expression
+ | opt_dim_specifiers COMMA expression
{
ArrayList ds = (ArrayList) $1;
ds.Add ((Expression) $3);
$$ = ds;
}
+ | opt_dim_specifiers COMMA
+ {
+ ArrayList ds = (ArrayList) $1;
+ ds.Add (new EmptyExpression());
+ $$ = ds;
+ }
;
-/* Expressions */
primary_expression
: literal
{
- // 7.5.1: Literals
+ //TODO
}
-
+ | parenthesized_expression
+ | this_access
+ | base_access
| qualified_identifier
{
string name = (string) $1;
-
$$ = DecomposeQI (name, lexer.Location);
}
- | parenthesized_expression
+ | get_type_expression
| member_access
| invocation_expression
//| element_access
- | this_access
- | base_access
| new_expression
| cast_expression
;
}
}
;
-
+
predefined_type
: builtin_types
;
}
$$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
// Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
- }
+ }
+ | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
+ {
+ if ($2 == null) {
+ Location l = lexer.Location;
+ Report.Error (1, l, "THIS IS CRAZY");
+ }
+ $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
+// Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
+ }
;
base_access
{
$$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
}
+ | ADDRESSOF expression
+ {
+ $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
+ }
;
variable_reference
: expression {/* note ("section 5.4"); */ $$ = $1; }
;
-negation_expression
- : NOT expression
- {
- $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
- }
- ;
expression
- : conditional_expression { $$ = $1; }
- | negation_expression
+ : conditional_xor_expression { $$ = $1; }
/*| assignment_expression*/
;
}
;
-unary_expression
- : primary_expression
- /*| NOT prefixed_unary_expression
- {
- $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
- }
- | cast_expression */
- ;
-
cast_expression
- : cast_operator OPEN_PARENS expression CLOSE_PARENS
+ : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
{
- $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
- }
+ // TODO
+ }
| CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
{
$$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
- }
+ }
+ | cast_operator OPEN_PARENS expression CLOSE_PARENS
+ {
+ $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
+ }
;
cast_operator
| CSNG { $$ = TypeManager.system_single_expr; }
| CSTR { $$ = TypeManager.system_string_expr; }
;
+
+get_type_expression
+ : GETTYPE OPEN_PARENS type CLOSE_PARENS
+ {
+ $$ = new TypeOf ((Expression) $3, lexer.Location);
+ }
+ ;
+
+exponentiation_expression
+ : primary_expression
+ | exponentiation_expression OP_EXP primary_expression
+ {
+ //TODO
+ }
+ ;
- //
- // The idea to split this out is from Rhys' grammar
- // to solve the problem with casts.
- //
prefixed_unary_expression
- : unary_expression
+ : exponentiation_expression
| PLUS prefixed_unary_expression
{
+ //FIXME: Is this rule correctly defined ?
$$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
}
| MINUS prefixed_unary_expression
{
+ //FIXME: Is this rule correctly defined ?
$$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
}
;
$$ = new Binary (Binary.Operator.Division,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | multiplicative_expression OP_IDIV prefixed_unary_expression
- {
+ ;
+
+integer_division_expression
+ : multiplicative_expression
+ | integer_division_expression OP_IDIV multiplicative_expression
+ {
+ //FIXME: Is this right ?
$$ = new Binary (Binary.Operator.Division,
- (Expression) $1, (Expression) $3, lexer.Location);
- }
- | multiplicative_expression MOD prefixed_unary_expression
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
+ ;
+
+mod_expression
+ : integer_division_expression
+ | mod_expression MOD integer_division_expression
{
- $$ = new Binary (Binary.Operator.Modulus,
- (Expression) $1, (Expression) $3, lexer.Location);
+ $$ = new Binary (Binary.Operator.Modulus,
+ (Expression) $1, (Expression) $3, lexer.Location);
}
;
-
+
additive_expression
- : multiplicative_expression
- | additive_expression PLUS multiplicative_expression
+ : mod_expression
+ | additive_expression PLUS mod_expression
{
$$ = new Binary (Binary.Operator.Addition,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | additive_expression MINUS multiplicative_expression
+ | additive_expression MINUS mod_expression
{
$$ = new Binary (Binary.Operator.Subtraction,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | additive_expression OP_CONCAT multiplicative_expression
+ ;
+
+concat_expression
+ : additive_expression
+ | concat_expression OP_CONCAT additive_expression
+ {
+ // FIXME: This should only work for String expressions
+ // We probably need to use something from the runtime
+ $$ = new Binary (Binary.Operator.Addition,
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
+ ;
+
+shift_expression
+ : concat_expression
+ | shift_expression OP_SHIFT_LEFT concat_expression
{
- // FIXME: This should only work for String expressions
- // We probably need to use something from the runtime
- $$ = new Binary (Binary.Operator.Addition,
- (Expression) $1, (Expression) $3, lexer.Location);
- }
+ // TODO
+ }
+ | shift_expression OP_SHIFT_RIGHT concat_expression
+ {
+ //TODO
+ }
;
relational_expression
- : additive_expression
- | relational_expression OP_LT additive_expression
+ : shift_expression
+ | relational_expression ASSIGN shift_expression
+ {
+ $$ = new Binary (Binary.Operator.Equality,
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
+ | relational_expression OP_NE shift_expression
+ {
+ $$ = new Binary (Binary.Operator.Inequality,
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
+ | relational_expression OP_LT shift_expression
{
$$ = new Binary (Binary.Operator.LessThan,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | relational_expression OP_GT additive_expression
+ | relational_expression OP_GT shift_expression
{
$$ = new Binary (Binary.Operator.GreaterThan,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | relational_expression OP_LE additive_expression
+ | relational_expression OP_LE shift_expression
{
$$ = new Binary (Binary.Operator.LessThanOrEqual,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | relational_expression OP_GE additive_expression
+ | relational_expression OP_GE shift_expression
{
$$ = new Binary (Binary.Operator.GreaterThanOrEqual,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | relational_expression IS unary_expression
- {
- $$ = new Binary (Binary.Operator.Equality,
- (Expression) $1, (Expression) $3, lexer.Location);
- }
- | relational_expression AS type_name
- {
- $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
- }
- ;
-
-equality_expression
- : relational_expression
- | equality_expression ASSIGN relational_expression
+ | relational_expression IS shift_expression
{
+ //FIXME: Should be a different op for reference equality but allows tests to use Is
$$ = new Binary (Binary.Operator.Equality,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | equality_expression OP_NE relational_expression
- {
- $$ = new Binary (Binary.Operator.Inequality,
- (Expression) $1, (Expression) $3, lexer.Location);
- }
- ;
-
-and_expression
- : equality_expression
- | and_expression AND equality_expression
+ | TYPEOF shift_expression IS type
{
- $$ = new Binary (Binary.Operator.BitwiseAnd,
- (Expression) $1, (Expression) $3, lexer.Location);
+ //FIXME: Is this rule correctly defined ?
+ $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
}
;
-exclusive_or_expression
- : and_expression
- | exclusive_or_expression OP_XOR and_expression
+negation_expression
+ : relational_expression
+ | NOT negation_expression
{
- $$ = new Binary (Binary.Operator.ExclusiveOr,
- (Expression) $1, (Expression) $3, lexer.Location);
+ //FIXME: Is this rule correctly defined ?
+ $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
}
;
-
+
conditional_and_expression
- : exclusive_or_expression
- | conditional_and_expression AND exclusive_or_expression
+ : negation_expression
+ | conditional_and_expression AND negation_expression
{
$$ = new Binary (Binary.Operator.LogicalAnd,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | conditional_and_expression ANDALSO exclusive_or_expression
+ | conditional_and_expression ANDALSO negation_expression
{ // FIXME: this is likely to be broken
$$ = new Binary (Binary.Operator.LogicalAnd,
(Expression) $1, (Expression) $3, lexer.Location);
}
;
-conditional_expression
+conditional_xor_expression
: conditional_or_expression
+ | conditional_xor_expression XOR conditional_or_expression
+ {
+ $$ = new Binary (Binary.Operator.ExclusiveOr,
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
;
assignment_expression
{
$$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
}
- | prefixed_unary_expression ASSIGN ADDRESSOF expression
- {
- // fixme: this is not working
- // d = AddressOf F
- // type of d has to get resolved somewhere
- //$$ = new New ((Expression) $1, (ArrayList) $4, lexer.Location);
- $$ = new Assign ((Expression) $1, (Expression) $4, lexer.Location);
+ | prefixed_unary_expression STAR ASSIGN expression
+ {
+ Location l = lexer.Location;
+
+ $$ = new CompoundAssign (
+ Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
}
- | prefixed_unary_expression OP_MULT_ASSIGN expression
+ | prefixed_unary_expression DIV ASSIGN expression
{
Location l = lexer.Location;
$$ = new CompoundAssign (
- Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
+ Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
}
- | prefixed_unary_expression OP_DIV_ASSIGN expression
+ | prefixed_unary_expression PLUS ASSIGN expression
{
Location l = lexer.Location;
$$ = new CompoundAssign (
- Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
+ Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
}
- | prefixed_unary_expression OP_IDIV_ASSIGN expression
+ | prefixed_unary_expression MINUS ASSIGN expression
{
Location l = lexer.Location;
$$ = new CompoundAssign (
- Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
- }
- | prefixed_unary_expression OP_ADD_ASSIGN expression
+ Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
+ }
+ | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
{
Location l = lexer.Location;
$$ = new CompoundAssign (
- Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
+ Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
}
- | prefixed_unary_expression OP_SUB_ASSIGN expression
+ | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
{
Location l = lexer.Location;
$$ = new CompoundAssign (
- Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
+ Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
}
- | prefixed_unary_expression OP_CONCAT_ASSIGN expression
+ | prefixed_unary_expression OP_CONCAT ASSIGN expression
{
Location l = lexer.Location;
+ // FIXME should be strings only
$$ = new CompoundAssign (
- Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
- }
+ Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
+ }
+ | prefixed_unary_expression OP_EXP ASSIGN expression
+ {
+ /*Location l = lexer.Location;
+
+ TODO: $$ = new CompoundAssign (
+ Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
+ }
+ | prefixed_unary_expression ASSIGN ADDRESSOF expression
+ {
+ ArrayList args = new ArrayList();
+ Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
+ args.Add (arg);
+
+ New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
+ n.isDelegate = true;
+ $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
+ }
;
-/*constant_expression
+constant_expression
: expression
;
-*/
boolean_expression
: expression
;
type
- : type_name { /* class_type */
- /*
- This does interfaces, delegates, struct_types, class_types,
- parent classes, and more! 4.2
- */
+ : namespace_or_type_name
+ {
$$ = DecomposeQI ((string) $1, lexer.Location);
}
| builtin_types
- /*| array_type
- | pointer_type */
+ //| array_type
;
type_list
}
;
-type_name
- : namespace_or_type_name
- ;
-
namespace_or_type_name
: qualified_identifier
;
-/* Built-in / Integral types */
builtin_types
: OBJECT { $$ = TypeManager.system_object_expr; }
- | STRING { $$ = TypeManager.system_string_expr; }
+ | primitive_type
+ ;
+
+primitive_type
+ : numeric_type
| BOOLEAN { $$ = TypeManager.system_boolean_expr; }
- | DECIMAL { $$ = TypeManager.system_decimal_expr; }
- | SINGLE { $$ = TypeManager.system_single_expr; }
- | DOUBLE { $$ = TypeManager.system_double_expr; }
| DATE { $$ = TypeManager.system_date_expr; }
- | integral_type
+ | CHAR { $$ = TypeManager.system_char_expr; }
+ | STRING { $$ = TypeManager.system_string_expr; }
+ ;
+
+
+numeric_type
+ : integral_type
+ | floating_point_type
+ | DECIMAL { $$ = TypeManager.system_decimal_expr; }
;
integral_type
:
| BYTE { $$ = TypeManager.system_byte_expr; }
| SHORT { $$ = TypeManager.system_int16_expr; }
- | LONG { $$ = TypeManager.system_int64_expr; }
| INTEGER { $$ = TypeManager.system_int32_expr; }
- | CHAR { $$ = TypeManager.system_char_expr; }
- ;
-
-interface_type
- : type_name
+ | LONG { $$ = TypeManager.system_int64_expr; }
;
-end_of_stmt
- : EOL
- | COLON
- ;
+floating_point_type
+ : SINGLE { $$ = TypeManager.system_single_expr; }
+ | DOUBLE { $$ = TypeManager.system_double_expr; }
+ ;
+
+pp_directive
+ : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
+ {
+ if(tokenizerController.IsAcceptingTokens)
+ {
+ if(in_external_source)
+ Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
+ else {
+ in_external_source = true;
+
+ lexer.EffectiveSource = (string) $4;
+ lexer.EffectiveLine = (int) $6;
+ }
+ }
+ }
+ | HASH IDENTIFIER LITERAL_STRING EOL
+ {
+ if(tokenizerController.IsAcceptingTokens)
+ {
+ if(!($2 as string).ToLower().Equals("region"))
+ Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
+ else
+ {
+ ++in_marked_region;
+ }
+ }
+ }
+ | HASH END IDENTIFIER EOL
+ {
+ if(tokenizerController.IsAcceptingTokens)
+ {
+ if( ($3 as string).ToLower().Equals("externalsource")) {
+ if(!in_external_source)
+ Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
+ else {
+ in_external_source = false;
+ lexer.EffectiveSource = lexer.Source;
+ lexer.EffectiveLine = lexer.Line;
+ }
+ }
+ else if(($3 as string).ToLower().Equals("region")) {
+ if(in_marked_region > 0)
+ --in_marked_region;
+ else
+ Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
+ }
+ else {
+ Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
+ }
+ }
+ }
+ | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
+ {
+ if(tokenizerController.IsAcceptingTokens)
+ {
+ //TODO;
+ }
+ }
+ | HASH IF
+ {
+ IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
+
+ try {
+ ifElseStateMachine.HandleToken(tok);
+ }
+ catch(ApplicationException) {
+ throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+ }
+ }
+ boolean_literal opt_then EOL
+ {
+ HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
+ }
+ | HASH ELSEIF
+ {
+ IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
+ try {
+ ifElseStateMachine.HandleToken(tok);
+ }
+ catch(ApplicationException) {
+ throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+ }
+ }
+ boolean_literal opt_then EOL
+ {
+ HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
+ }
+ | HASH ELSE
+ {
+ IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
+ try {
+ ifElseStateMachine.HandleToken(tok);
+ }
+ catch(ApplicationException) {
+ throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+ }
+ }
+ EOL
+ {
+ HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
+ }
+ | HASH END IF
+ {
+ IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
+ try {
+ ifElseStateMachine.HandleToken(tok);
+ }
+ catch(ApplicationException) {
+ throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+ }
+ }
+ EOL
+ {
+ HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
+ }
+ | HASH error EOL
+ {
+ if(tokenizerController.IsAcceptingTokens)
+ Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
+ else
+ Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
+ }
+
+ ;
+
%%
}
public static string BuildRank (ArrayList rank)
+ {
+ bool allEmpty;
+ return BuildRank(rank, out allEmpty);
+ }
+
+ public static string BuildRank (ArrayList rank, out bool allEmpty)
{
string res = "";
res += "[";
- for (int x = 0; x < (rank.Count -1 ); x++)
- res += ",";
+ allEmpty = true;
+ bool first = true;
+ foreach (object e in rank) {
+ if (!(e is EmptyExpression))
+ allEmpty = false;
+ if (!first)
+ res += ",";
+ first = false;
+ }
res += "]";
return res;
}
- public static string BuildRanks (Parser t)
+ public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
{
string res = "";
- foreach (ArrayList rank in t.current_rank_specifiers)
- res += BuildRank (rank);
+ bool allEmpty = true;
+ foreach (ArrayList rank in rank_specifiers) {
+ bool tmp;
+ res = BuildRank (rank, out tmp) + res;
+ if (!tmp)
+ allEmpty = false;
+ }
+ if (!allEmpty && mustBeEmpty)
+ Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
return res;
}
public static void FixupArrayTypes (ArrayList vars)
{
- int varcount = vars.Count;
string dims;
foreach (VariableDeclaration var in vars) {
return (res);
}
-private void AddHandler (Expression evt_definition, string handler_name)
+private void AddHandler (Expression evt_definition, Expression handler_exp)
{
- AddHandler (current_block, evt_definition, handler_name);
+ AddHandler (current_block, evt_definition, handler_exp);
}
void CheckAttributeTarget (string a)
}
}
-private void AddHandler (Block b, Expression evt_id, string handler_name)
+private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
{
- Location loc = lexer.Location;
- string evt_target = evt_id.ToString();
- evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
- Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
- b.AddStatement (s);
+ Location loc = lexer.Location;
+
+ Statement addhnd = (Statement) new AddHandler (evt_id,
+ handles_exp,
+ loc);
+ b.AddStatement (addhnd);
}
private void RaiseEvent (string evt_name, ArrayList args)
current_block.AddStatement (s);
}
-// FIXME: THIS DOES NOT WORK!!!
-private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
+private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
{
- Location loc = lexer.Location;
- ArrayList neh_args = new ArrayList();
- neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
-
- ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
-
- CompoundAssign ca = new CompoundAssign (
- Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
-
- Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc));
- b.AddStatement (s);
+ Location loc = lexer.Location;
+
+ Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
+ handler_exp,
+ loc);
+ b.AddStatement (rmhnd);
}
// <summary>
}
-private void RemoveHandler (Expression evt_definition, string handler_name)
+private void RemoveHandler (Expression evt_definition, Expression handler_exp)
{
- RemoveHandler (current_block, evt_definition, handler_name);
+ RemoveHandler (current_block, evt_definition, handler_exp);
}
private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
with_stack = new Stack();
statement_stack = new Stack();
+ allow_global_attribs = true;
+ expecting_global_attribs = false;
+ expecting_local_attribs = false;
+ local_attrib_section_added = false;
+
UseExtendedSyntax = name.EndsWith(".mbs");
OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
OptionStrict = InitialOptionStrict || UseExtendedSyntax;
OptionCompareBinary = InitialOptionCompareBinary;
lexer = new Tokenizer (input, name, defines);
- StringBuilder value = new StringBuilder ();
+
+ ifElseStateMachine = new IfElseStateMachine();
+ tokenizerController = new TokenizerController(lexer);
+
try {
- if (yacc_verbose_flag)
+ if (yacc_verbose_flag > 0)
yyparse (lexer, new yydebug.yyDebugSimple ());
- else
+ else {
yyparse (lexer);
- } catch (Exception e) {
- Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.ref_name + "\n" + e.ToString());
+ cleanup();
+ }
+ }
+ catch(MBASException e) {
+ Report.Error(e.code, e.loc, e.Message);
+ }
+ catch (Exception e) {
+ if (Report.Stacktrace)
+ Console.WriteLine(e);
+ Report.Error (29999, lexer.Location, "Parsing error");
}
RootContext.VerifyImports();
return Report.Errors;
}
+void cleanup()
+{
+ try {
+ ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
+ }
+ catch(ApplicationException) {
+ throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+ }
+
+ if(in_external_source)
+ Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
+
+ if(in_marked_region > 0)
+ Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
+}
+
+void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
+{
+ try {
+ tokenizerController.PositionTokenizerCursor(tok, expr);
+ }
+ catch(ApplicationException) {
+ tok = IfElseStateMachine.Token.EOF;
+ try {
+ ifElseStateMachine.HandleToken(tok);
+ }
+ catch(ApplicationException) {
+ throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+ }
+ }
+}
/* end end end */
}