// Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
//
// Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+// Anirban Bhattacharjee (banirban@novell.com)
//
// Licensed under the terms of the GNU GPL
//
// Copyright (C) 2001 A Rafael D Teixeira
//
-// TODO:
-// Nearly everything
//
namespace Mono.MonoBASIC
using System.Reflection;
using System.Collections;
using Mono.Languages;
- using Mono.CSharp;
+ 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>
- public class Parser : GenericParser
+ [DefaultParser]
+ public class Parser : GenericParser
{
/// to be passed to sub/constructor
/// </summary>
int current_modifiers;
-
+
/// <summary>
/// This is used by the sub_header parser to store attributes
/// to be passed to sub/constructor
// </summary>
Expression set_implicit_value_parameter_type;
+ Location member_location;
+
// An out-of-band stack.
//
Stack oob_stack;
+
+ ArrayList current_rank_specifiers;
DoOptions do_type;
//
// Switch stack.
//
Stack switch_stack;
+
+ // Expression stack for nested ifs
+ Stack expr_stack;
+
+ Stack tmp_blocks;
+ Stack statement_stack;
+
+ // A stack for With expressions.
+ //
+ Stack with_stack;
+
+
+ static public bool InitialOptionExplicit = false;
+ static public bool InitialOptionStrict = false;
+ static public bool InitialOptionCompareBinary = true;
+ static public ArrayList ImportsList = null;
- bool UseExtendedSyntax; // for ".mbs" files
+ bool OptionExplicit;
+ bool OptionStrict;
+ bool OptionCompareBinary;
+ static public bool UseExtendedSyntax; // for ".mbs" files
+
+ bool implicit_modifiers;
+
public override string[] extensions()
{
string [] list = { ".vb", ".mbs" };
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;
+ }
+ }
+ }
%}
%token EOF
%token AS
%token ASSEMBLY
%token AUTO
+%token BINARY
%token BOOLEAN
%token BYREF
%token BYTE
%token CLASS
%token CLNG
%token COBJ
-//%token COMPARE
+%token COMPARE
%token CONST
%token CSHORT
%token CSNG
%token DECLARE
%token DEFAULT
%token DELEGATE
-%token DESCRIPTION // MonoBASIC extension
%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 ERROR
%token EVENT
%token EXIT
-//%token EXPLICIT
+%token EXPLICIT
%token FALSE
%token FINALLY
%token FOR
%token FUNCTION
%token GET
%token GETTYPE
+%token GOSUB
%token GOTO
%token HANDLES
%token IF
%token NOTINHERITABLE
%token NOTOVERRIDABLE
%token OBJECT
+%token OFF
%token ON
%token OPTION
%token OPTIONAL
%token OVERLOADS
%token OVERRIDABLE
%token OVERRIDES
-%token PARAMETER // MonoBASIC extension
%token PARAM_ARRAY
%token PRESERVE
%token PRIVATE
%token STATIC
%token STEP
%token STOP
-%token STRING
-%token STRUCTURE
+%token STRICT
+%token STRING
+%token STRUCTURE
%token SUB
-%token SUMMARY // MonoBASIC extension
%token SYNCLOCK
+%token TEXT
%token THEN
%token THROW
%token TO
%token UNICODE
%token UNTIL
%token VARIANT
+%token WEND
%token WHEN
%token WHILE
%token WITH
%token WITHEVENTS
%token WRITEONLY
%token XOR
+%token YIELD // MonoBASIC extension
+
+%token HASH
/* MonoBASIC single character operators/punctuation. */
+
%token OPEN_BRACKET "["
%token CLOSE_BRACKET "]"
%token OPEN_PARENS "("
+%token OPEN_BRACE "{"
+%token CLOSE_BRACE "}"
%token CLOSE_PARENS ")"
%token DOT "."
%token COMMA ","
%token OP_LT "<"
%token OP_GT ">"
%token STAR "*"
-%token PERCENT "%"
%token DIV "/"
%token OP_EXP "^"
%token INTERR "?"
-%token OP_IDIV "\\"
+%token OP_IDIV "\\" //FIXME: This should be "\"
%token OP_CONCAT "&"
+%token EXCLAMATION "!"
+
+%token PERCENT "%"
+%token LONGTYPECHAR "&"
+%token AT_SIGN "@"
+%token SINGLETYPECHAR "!"
+%token NUMBER_SIGN "#"
+%token DOLAR_SIGN "$"
+
+%token ATTR_ASSIGN ":="
/* MonoBASIC multi-character operators. */
%token OP_LE "<="
%token OP_GE ">="
-%token OP_EQ "=="
%token OP_NE "<>"
-%token OP_AND //"and"
-%token OP_OR //"or"
-%token OP_XOR //"xor"
-%token OP_MODULUS //"mod"
+%token OP_XOR "xor"
+//%token OP_MODULUS //"mod"
%token OP_MULT_ASSIGN "*="
%token OP_DIV_ASSIGN "/="
%token OP_IDIV_ASSIGN "\\="
%token OP_CONCAT_ASSIGN "&="
%token OP_EXP_ASSIGN "^="
+/* VB.NET 2003 new bit-shift operators */
+%token OP_SHIFT_LEFT "<<"
+%token OP_SHIFT_RIGHT ">>"
+
/* Numbers */
%token LITERAL_INTEGER "int literal"
%token LITERAL_SINGLE "float literal"
%token LITERAL_DECIMAL "decimal literal"
%token LITERAL_CHARACTER "character literal"
%token LITERAL_STRING "string literal"
+%token LITERAL_DATE "datetime literal"
%token IDENTIFIER
%left OPEN_PARENS
%left OPEN_BRACKET OPEN_BRACE
%left DOT
+%right NOT
%nonassoc HIGHPREC
%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_imports_directives
+ : logical_end_of_line
+ opt_option_directives
+ opt_imports_directives
opt_attributes
opt_declarations
EOF
{
- $$ = $3;
+ $$=$5;
}
+
+ ;
+
+opt_option_directives
+ : /* empty */
+ | option_directives
+ ;
+
+option_directives
+ : option_directive
+ | option_directives option_directive
+ ;
+
+option_directive
+ : option_explicit_directive
+ | option_strict_directive
+ | option_compare_directive
;
+on_off
+ : /* empty */
+ {
+ $$ = (object)true;
+ }
+ | ON
+ {
+ $$ = (object)true;
+ }
+ | OFF
+ {
+ $$ = (object)false;
+ }
+ ;
+
+text_or_binary
+ : BINARY
+ {
+ $$ = (object)true;
+ }
+ | TEXT
+ {
+ $$ = (object)false;
+ }
+ ;
+
+option_explicit_directive
+ : OPTION EXPLICIT on_off logical_end_of_line
+ {
+ if (!UseExtendedSyntax)
+ OptionExplicit = (bool)$3;
+ else
+ Report.Warning (
+ 9999, lexer.Location,
+ "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
+ }
+ ;
+
+
+option_strict_directive
+ : OPTION STRICT on_off logical_end_of_line
+ {
+ if (!UseExtendedSyntax)
+ OptionStrict = (bool)$3;
+ else
+ Report.Warning (
+ 9999, lexer.Location,
+ "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
+ }
+ ;
+
+option_compare_directive
+ : OPTION COMPARE text_or_binary logical_end_of_line
+ {
+ OptionCompareBinary = (bool)$3;
+ }
+ ;
+
opt_declarations
: /* empty */
| declarations
string name = "";
int mod_flags;
- if ($1 is Class){
- Class c = (Class) $1;
+ if ($1 is Class || $1 is Struct || $1 is Module ){
+ TypeContainer c = (TypeContainer) $1;
mod_flags = c.ModFlags;
name = c.Name;
- } else if ($1 is Struct){
- Struct s = (Struct) $1;
- mod_flags = s.ModFlags;
- name = s.Name;
- } else if ($1 is Module){
- Module m = (Module) $1;
- mod_flags = m.ModFlags;
- name = m.Name;
} else
break;
}
;
-qualified_identifier
+identifier
: IDENTIFIER
- | qualified_identifier DOT IDENTIFIER
+ | BINARY
+ | TEXT
+ | COMPARE
+ | EXPLICIT
+ | OFF
+ ;
+
+type_character
+ : PERCENT { $$ = TypeManager.system_int32_expr; }
+ | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
+ | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
+ | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
+ | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
+ | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
+ ;
+
+opt_type_character
+ : /* empty */ { $$ = null; }
+ | type_character { $$ = $1; }
+ ;
+
+
+qualified_identifier
+ : identifier
+ | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
{
$$ = (($1).ToString ()) + "." + ($3.ToString ());
}
;
+
opt_imports_directives
: /* empty */
| imports_directives
;
imports_directive
- : /* imports_alias_directive
- | */ imports_namespace_directive
+ : IMPORTS imports_terms logical_end_of_line
;
-imports_namespace_directive
- : IMPORTS qualified_identifier EOL
+imports_terms
+ : imports_term
+ | imports_terms COMMA imports_term
+ ;
+
+imports_term
+ : namespace_or_type_name
+ {
+ RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
+ }
+ | identifier ASSIGN namespace_or_type_name
{
- current_namespace.Using ((string) $2, lexer.Location);
+ RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
}
;
+opt_params
+ : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
+ | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
+ | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
+ ;
+
+global_attribute_list
+ : global_attribute
+ | global_attribute_list COMMA global_attribute
+ ;
+
+global_attribute
+ : attribute_modifier COLON attribute
+
+attribute_modifier
+ : ASSEMBLY
+ | MODULE
+ | identifier
+ {
+ Report.Error (658, lexer.Location, "`" + (string)$1 + "' is an invalid attribute target");
+ }
+ ;
+
opt_attributes
- : /* empty */
- | OP_LT attribute_list OP_GT
- ;
+ : /* empty */
+ | attributes { $$ = $1; }
+ ;
-attribute_list
- : attribute
- | attribute_list COMMA attribute
+attr_begin
+ : OP_LT
;
-
+
+attr_end
+ : OP_GT
+ ;
+
+attributes
+ : attr_begin attribute_list attr_end
+ {
+ AttributeSection sect = new AttributeSection (null, (ArrayList) $2);
+ $$ = new Attributes (sect, lexer.Location);
+ }
+ | attr_begin global_attribute_list attr_end logical_end_of_line
+ ;
+
+attribute_list
+ : attribute
+ {
+ ArrayList attrs = new ArrayList ();
+ attrs.Add ($1);
+
+ $$ = attrs;
+
+ }
+ | attribute_list COMMA attribute
+ {
+ ArrayList attrs = (ArrayList) $1;
+ attrs.Add ($3);
+
+ $$ = attrs;
+ }
+ ;
+
attribute
- : IDENTIFIER
+ : attribute_name
+ {
+ $$ = lexer.Location;
+ }
+ opt_attribute_arguments
+ {
+ $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+ }
+ ;
+
+attribute_name
+ : namespace_or_type_name
+ ;
+
+opt_attribute_arguments
+ : /* empty */ { $$ = null; }
+ | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
+ {
+ $$ = $2;
+ }
;
+
+opt_attribute_arguments_list
+ : /* empty */
+ | attribute_arguments_list
+ ;
+
+attribute_arguments_list
+ : positional_argument_list
+ {
+ ArrayList args = new ArrayList ();
+ args.Add ($1);
+
+ $$ = args;
+ }
+ | positional_argument_list COMMA named_argument_list
+ {
+ ArrayList args = new ArrayList ();
+ args.Add ($1);
+ args.Add ($3);
+
+ $$ = args;
+ }
+ | named_argument_list
+ {
+ ArrayList args = new ArrayList ();
+ args.Add (null);
+ args.Add ($1);
+ $$ = args;
+ }
+ ;
+
+positional_argument_list
+ : constant_expression
+ {
+ ArrayList args = new ArrayList ();
+ args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
+
+ $$ = args;
+ }
+ | positional_argument_list COMMA constant_expression
+ {
+ ArrayList args = (ArrayList) $1;
+ args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
+
+ $$ = args;
+ }
+ ;
+
+named_argument_list
+ : named_argument
+ {
+ ArrayList args = new ArrayList ();
+ args.Add ($1);
+
+ $$ = args;
+ }
+ | named_argument_list COMMA named_argument
+ {
+ ArrayList args = (ArrayList) $1;
+ args.Add ($3);
+
+ $$ = args;
+ }
+ ;
+
+named_argument
+ : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
+ {
+ $$ = new DictionaryEntry (
+ (string) $1,
+ new Argument ((Expression) $3, Argument.AType.Expression));
+ }
+ ;
+
namespace_declaration
- : NAMESPACE qualified_identifier EOL
+ : NAMESPACE qualified_identifier logical_end_of_line
{
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
- : opt_attributes
- opt_modifiers
- {
- current_attributes = (Attributes) $1;
- current_modifiers = (int) $2;
- }
+ : opt_attributes
+ opt_modifiers
+ {
+ current_attributes = (Attributes) $1;
+ current_modifiers = (int) $2;
+ }
type_spec_declaration
;
| module_declaration
| interface_declaration
| delegate_declaration
-// | struct_declaration
-// | enum_declaration
+ | struct_declaration
+ | enum_declaration
;
-
+
class_declaration
- : CLASS IDENTIFIER EOL opt_class_base
+ : CLASS identifier logical_end_of_line 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
+ // instead of triggering an error.
+ if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+ current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
Class new_class;
string name;
name = MakeName ((string) $2);
-
new_class = new Class (current_container, name, current_modifiers,
(Attributes) current_attributes, lexer.Location);
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_class_base
- : /* empty */ { $$ = null; }
- | class_base { $$ = $1; }
+opt_inherits
+ : /* empty */ { $$ = null; }
+ | INHERITS type_list logical_end_of_line { $$ = $2; }
;
-class_base
- : inherits_or_implements type_list EOL { $$ = $2; }
+opt_implements
+ : /* empty */ { $$ = null; }
+ | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
;
-inherits_or_implements
- : INHERITS
- | IMPLEMENTS
- ;
-
opt_modifiers
: /* empty */ { $$ = (int) 0; current_modifiers = 0; }
| modifiers { $$ = $1; current_modifiers = (int) $1; }
;
-
+
modifiers
: modifier
| modifiers modifier
;
modifier
- : PUBLIC { $$ = Modifiers.PUBLIC; }
- | PROTECTED { $$ = Modifiers.PROTECTED; }
- | PRIVATE { $$ = Modifiers.PRIVATE; }
- | STATIC { $$ = Modifiers.STATIC; }
- /* FIXME: FRIEND and PROTECTED FRIEND are missing */
+ : PUBLIC { $$ = Modifiers.PUBLIC; }
+ | PROTECTED { $$ = Modifiers.PROTECTED; }
+ | PRIVATE { $$ = Modifiers.PRIVATE; }
+ | SHARED { $$ = Modifiers.STATIC; }
+ | FRIEND { $$ = Modifiers.INTERNAL; }
+ | NOTINHERITABLE { $$ = Modifiers.SEALED; }
+ | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
+ | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
+ | OVERRIDES { $$ = Modifiers.OVERRIDE; }
+ | OVERLOADS { $$ = Modifiers.NEW; }
+ | SHADOWS { $$ = Modifiers.SHADOWS; }
+ | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
+ | READONLY { $$ = Modifiers.READONLY; }
+ | DEFAULT { $$ = Modifiers.DEFAULT; }
+ | WRITEONLY { $$ = Modifiers.WRITEONLY; }
;
module_declaration
- : MODULE IDENTIFIER EOL
+ : MODULE identifier logical_end_of_line
{
Module new_module;
string name;
- // FIXME : Check for valid module modifiers
name = MakeName((string) $2);
new_module = new Module(current_container,
- name,
- current_modifiers,
- (Attributes) current_attributes,
- lexer.Location);
+ name,
+ current_modifiers, // already checks then
+ (Attributes) current_attributes,
+ lexer.Location);
current_container = new_module;
current_container.Namespace = current_namespace;
RootContext.Tree.RecordDecl(name, new_module);
}
- opt_class_member_declarations
- END MODULE EOL
+ opt_module_member_declarations
+ END MODULE logical_end_of_line
{
Module new_module = (Module)current_container;
current_container = current_container.Parent;
CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
+
+ TypeManager.AddStandardModule(new_module);
$$ = new_module;
}
;
-opt_class_member_declarations
+opt_module_member_declarations
: /* empty */
- | class_member_declarations
+ | module_member_declarations
;
-class_member_declarations
- : class_member_declaration
- | class_member_declarations class_member_declaration
+module_member_declarations
+ : module_member_declaration
+ | module_member_declarations module_member_declaration
;
-class_member_declaration
+module_member_declaration
: opt_attributes
opt_modifiers
{
current_attributes = (Attributes) $1;
- current_modifiers = (int) $2;
+ current_modifiers = ((int)$2) | Modifiers.STATIC;
+ bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
+ implicit_modifiers = (!explicit_static);
}
- class_member_declarator
+ module_member_declarator
{
+ implicit_modifiers = false;
$$ = $3;
}
;
-class_member_declarator
+module_member_declarator
: constructor_declaration
| method_declaration
{
CheckDef (current_container.AddMethod (method), method.Name, method.Location);
}
| field_declaration
- | property_declaration
-// | event_declaration
| withevents_declaration /* This is a field but must be treated specially, see below */
- | type_declaration
+ | constant_declaration
+ | property_declaration
+ | event_declaration
+ | type_spec_declaration
;
-
-method_declaration
- : sub_declaration
- | func_declaration
+constant_declaration
+ : CONST constant_declarators logical_end_of_line
+ {
+ // 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
+ // instead of triggering an error.
+ if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+ current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+ int mod = (int) current_modifiers;
+
+ // Structure members are Public by default
+ if ((current_container is Struct) && (mod == 0))
+ mod = Modifiers.PUBLIC;
+
+ ArrayList consts = (ArrayList) $2;
+ if(consts.Count > 0)
+ {
+ VariableDeclaration.FixupTypes ((ArrayList) $2);
+ VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
+
+ foreach (VariableDeclaration var in (ArrayList) $2){
+ Location l = var.Location;
+ Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
+ (Expression)var.expression_or_array_initializer,
+ mod, (Attributes) null, l);
+
+ CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
+ }
+ }
+ }
;
-
-sub_declaration
- : SUB IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler EOL
- {
-
- current_local_parameters = (Parameters) $4;
- start_block();
- }
- opt_local_declarations
- {
- /* This is WEIRD: declaring a method (sub) in a module as static will
- trigger a syntax error, but the same methods MUST be static in order
- to be properly called
- */
- if (current_container is Module) {
- if (current_modifiers == Modifiers.STATIC) {
- Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
- }
- else
- {
- current_modifiers = Modifiers.STATIC;
- }
- }
+
+opt_class_member_declarations
+ : /* empty */
+ | class_member_declarations
+ ;
+
+class_member_declarations
+ : class_member_declaration
+ | class_member_declarations class_member_declaration
+ ;
+
+class_member_declaration
+ : opt_attributes
+ opt_modifiers
+ {
+ current_attributes = (Attributes) $1;
+ current_modifiers = (int) $2;
+ }
+ class_member_declarator
+ {
+ $$ = $3;
+ }
+ ;
+
+class_member_declarator
+ : constructor_declaration
+ | method_declaration
+ {
+ Method method = (Method) $1;
+ CheckDef (current_container.AddMethod (method), method.Name, method.Location);
+ }
+ | field_declaration
+ | constant_declaration
+ | property_declaration
+ | event_declaration
+ | withevents_declaration /* This is a field but must be treated specially, see below */
+ | type_spec_declaration
+ ;
+
+
+method_declaration
+ : sub_declaration
+ | func_declaration
+ | must_override_declaration
+ ;
+
+must_override_declaration
+ : must_override_sub_declaration
+ | must_override_func_declaration
+ ;
+
+must_override_sub_declaration
+ : MUSTOVERRIDE SUB identifier opt_params logical_end_of_line
+ {
+ if (current_container is Module)
+ Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
+
+ if (current_container is Struct)
+ Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+
+ current_modifiers |= Modifiers.ABSTRACT;
+
+ Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
+ (Parameters) $4, null, null, lexer.Location);
+
+ if (!(current_container is Class))
+ Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
+
+ $$ = method;
+ }
+ ;
+
+
+must_override_func_declaration
+ : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
+ {
+ 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'.");
+
+ if (current_container is Struct)
+ Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+
+ current_modifiers |= Modifiers.ABSTRACT;
+
+ Method method = new Method ((Expression) ftype, (int) current_modifiers,
+ (string) $3,(Parameters) $5, null, null,
+ lexer.Location);
+
+ if (!(current_container is Class))
+ Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
+
+ $$ = method;
+ }
+ ;
+
+sub_declaration
+ : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
+ {
+ 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, null, lexer.Location);
+ (Parameters) current_local_parameters, (Attributes) current_attributes,
+ (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);
+ if ($4 != null) {
+ // we have an event handler to take care of
+
string evt_def = ((MemberAccess)$6).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) {
+ Location loc = lexer.Location;
+
+ Statement addhnd = (Statement) new AddHandler ((Expression) $4,
+ DecomposeQI((string) $2, loc),
+ DecomposeQI(evt_target, loc), loc);
+
+ current_container.AddEventHandler (addhnd);
+ found = true;
+ break;
+ }
+ }
+ }
- 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;
- }
+ if (!found){
+ Report.Error(30506, lexer.Location,
+ evt_target + " is not declared with WithEvents");
}
-
-
}
}
;
func_declaration
- : FUNCTION IDENTIFIER
- OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type EOL
+ : FUNCTION identifier opt_type_character
+ opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
{
-
current_local_parameters = (Parameters) $4;
+ member_location = lexer.Location;
start_block();
- }
- opt_local_declarations
- {
- /* This is WEIRD: declaring a method (sub) in a module as static will
- trigger a syntax error, but the same methods MUST be static in order
- to be properly called
- */
- if (current_container is Module) {
- if (current_modifiers == Modifiers.STATIC) {
- Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
- }
- else
- {
- current_modifiers = Modifiers.STATIC;
- }
- }
+
+ 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))
+ current_modifiers = Modifiers.PUBLIC;
// Add local var declaration
// for return value
ArrayList retval = new ArrayList ();
- retval.Add (new VariableDeclaration ((string) $2, null, lexer.Location));
- declare_local_variables ((Expression) $7, retval, lexer.Location);
+ retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
+ declare_local_variables ((Expression) ftype, retval, lexer.Location);
}
opt_statement_list
- END FUNCTION EOL
+ END FUNCTION logical_end_of_line
{
- Method method = new Method ((Expression) $7, (int) current_modifiers, (string) $2,
- (Parameters) current_local_parameters, null, 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) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
+ (ArrayList) $6, member_location);
method.Block = end_block();
$$ = method;
-
}
;
+struct_declaration
+ : STRUCTURE identifier logical_end_of_line
+ opt_implement_clause
+ {
+ Struct new_struct;
+ string full_struct_name = MakeName ((string) $2);
+
+ // Module members are static by default, but structures *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);
+
+ new_struct = new Struct (current_container, full_struct_name,
+ (int) current_modifiers,
+ (Attributes) current_attributes, lexer.Location);
+ current_container = new_struct;
+ current_container.Namespace = current_namespace;
+ RootContext.Tree.RecordDecl (full_struct_name, new_struct);
+ }
+ opt_struct_member_declarations
+ {
+ Struct new_struct = (Struct) current_container;
+
+ if ($4 != null)
+ new_struct.Bases = (ArrayList) $4;
+
+ current_container = current_container.Parent;
+ CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
+ $$ = new_struct;
+ }
+ END STRUCTURE logical_end_of_line
+ ;
+
+opt_struct_member_declarations
+ : /* empty */
+ | struct_member_declarations
+ ;
+
+struct_member_declarations
+ : struct_member_declaration
+ | struct_member_declarations struct_member_declaration
+ ;
+
+struct_member_declaration
+ : opt_modifiers
+ struct_member_declarator
+ ;
+
+struct_member_declarator
+ : field_declaration
+ | constant_declaration
+ | constructor_declaration
+ | method_declaration
+ {
+ Method method = (Method) $1;
+ CheckDef (current_container.AddMethod (method), method.Name, method.Location);
+ }
+ | property_declaration
+ | event_declaration
+ | type_spec_declaration
+
+ /*
+ * This is only included so we can flag error 575:
+ * destructors only allowed on class types
+ */
+ //| destructor_declaration
+ ;
+
+event_declaration
+ : 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, (ArrayList) $5,
+ lexer.Location);
+
+ CheckDef (current_container.AddEvent (e), e.Name, e.Location);
+ }
+ | EVENT identifier opt_params opt_implement_clause logical_end_of_line
+ {
+ 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, (ArrayList) $4,
+ lexer.Location);
+
+ CheckDef (current_container.AddEvent (e), e.Name, e.Location);
+ }
+ ;
+
+enum_declaration
+ : ENUM identifier opt_type_spec logical_end_of_line
+ opt_enum_member_declarations // FIXME: BC30280: Enum must contain atleast one member
+ {
+ 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;
+
+ // 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.
+ if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+ current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+ Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
+ (int) current_modifiers, full_name,
+ (Attributes) current_attributes, enum_location);
+
+ foreach (VariableDeclaration ev in enum_members) {
+ Location loc = (Location) ev.Location;
+
+ CheckDef (e.AddEnumMember (ev.identifier,
+ (Expression) ev.expression_or_array_initializer,
+ loc, ev.OptAttributes), ev.identifier, loc);
+ }
+
+ e.Namespace = current_namespace;
+
+ CheckDef (current_container.AddEnum (e), full_name, enum_location);
+ RootContext.Tree.RecordDecl (full_name, e);
+
+ }
+ END ENUM logical_end_of_line
+ ;
+
+opt_enum_member_declarations
+ : /* empty */ { $$ = new ArrayList (); }
+ | enum_member_declarations { $$ = $1; }
+ ;
+
+enum_member_declarations
+ : enum_member_declaration
+ {
+ ArrayList l = new ArrayList ();
+
+ l.Add ($1);
+ $$ = l;
+ }
+ | enum_member_declarations enum_member_declaration
+ {
+ ArrayList l = (ArrayList) $1;
+
+ l.Add ($2);
+
+ $$ = l;
+ }
+ ;
+
+enum_member_declaration
+ : opt_attributes identifier logical_end_of_line
+ {
+ $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
+ }
+ | opt_attributes identifier
+ {
+ $$ = lexer.Location;
+ }
+ 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
;
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);
+ Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
+ (Parameters) $3, current_attributes, null, lexer.Location);
+
+ $$ = method;
}
- | FUNCTION IDENTIFIER
- OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
+ | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
{
- $$ = new InterfaceMethod (
- (Expression) $7, (string) $2, false, (Parameters) $4,
- 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
- : PROPERTY IDENTIFIER
- OPEN_PARENS
- opt_formal_parameter_list
- CLOSE_PARENS opt_type_spec EOL
+ : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line
{
- // FIXME we MUST pass property parameters
- $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
- false, false, 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, null, null,
+ 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, null, null,
+ current_attributes, lexer.Location);
+
+ CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
}
;
property_declaration
- : PROPERTY IDENTIFIER opt_property_parameters AS type EOL
+ : abstract_propery_declaration
+ | non_abstract_propery_declaration
+ ;
+
+abstract_propery_declaration
+ : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line
+ {
+ 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_container is Struct)
+ Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+
+ current_modifiers |= Modifiers.ABSTRACT;
+
+ current_local_parameters = (Parameters) $5;
+ 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) $3, current_modifiers,
+ get_block, set_block, current_attributes, lexer.Location,
+ null, get_parameters, set_parameters, null);
+
+ if (!(current_container is Class))
+ Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
+
+ CheckDef (current_container.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;
+ }
+ ;
+
+
+ non_abstract_propery_declaration
+ : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec opt_implement_clause logical_end_of_line
{
- get_implicit_value_parameter_type = (Expression) $5;
+ get_implicit_value_parameter_type =
+ ($5 == null) ? (($3 == null) ?
+ TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
get_implicit_value_parameter_name = (string) $2;
- current_local_parameters = (Parameters) $3;
+ 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);
$$ = lexer.Location;
}
accessor_declarations
- END PROPERTY EOL
+ END PROPERTY logical_end_of_line
{
lexer.PropertyParsing = false;
Property prop;
- Pair pair = (Pair) $8;
- Accessor get_block = (Accessor) pair.First;
- Accessor set_block = (Accessor) pair.Second;
+ Pair pair = (Pair) $9;
+
+ Accessor get_block = null;
+ Accessor set_block = null;
+
+ if (pair.First != null){
+ get_block = (Accessor) pair.First;
+ }
+
+ if (pair.Second != null) {
+ set_block = (Accessor) pair.Second;
+ }
+
Location loc = lexer.Location;
- prop = new Property ((Expression) $5, (string) $2, current_modifiers, get_block, set_block,
+ // Structure members are Public by default
+ if ((current_container is Struct) && (current_modifiers == 0))
+ current_modifiers = Modifiers.PUBLIC;
+
+ 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);
+ get_parameters, set_parameters, (ArrayList) $6);
CheckDef (current_container.AddProperty (prop), prop.Name, loc);
get_implicit_value_parameter_type = null;
opt_property_parameters
: /* empty */
{
- $$ = Parameters.EmptyReadOnlyParameters; ;
+ $$ = Parameters.EmptyReadOnlyParameters;
}
| OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
}
;
+opt_implement_clause
+ : /* empty */
+ {
+ $$ = null;
+ }
+ | IMPLEMENTS implement_clause_list
+ {
+ $$ = $2;
+ }
+ ;
+
+implement_clause_list
+ : qualified_identifier
+ {
+ 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_set_accessor_declaration
{
;
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");
+
current_local_parameters = get_parameters;
lexer.PropertyParsing = false;
// Add local var declaration
// for return value
ArrayList retval = new ArrayList ();
- retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, null, lexer.Location));
+ retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
-
}
- opt_statement_list
- END GET EOL
+ opt_statement_list
+ 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");
+
Parameter implicit_value_parameter = new Parameter (
set_implicit_value_parameter_type,
set_implicit_value_parameter_name,
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;
opt_set_parameter
: /* empty */
{
- set_implicit_value_parameter_type = (Expression) TypeManager.system_object_expr;
+ set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
set_implicit_value_parameter_name = "Value";
}
- | OPEN_PARENS opt_identifier opt_type_spec CLOSE_PARENS
+ |OPEN_PARENS CLOSE_PARENS
{
- /* FIXME: possible syntax error which must be caught
- Set ( As <type>) is currently (and wrongly so) legal
- */
- set_implicit_value_parameter_type = (Expression) $3;
+ 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
+ {
+ Parameter.Modifier pm = (Parameter.Modifier)$2;
+ if ((pm | Parameter.Modifier.VAL) != 0)
+ Report.Error (31065,
+ lexer.Location,
+ "Set cannot have a paremeter modifier other than 'ByVal'");
+
+ set_implicit_value_parameter_type = (Expression) $4;
+
+ if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
+ 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) $2;
+ set_implicit_value_parameter_name = (string) $3;
else
set_implicit_value_parameter_name = "Value";
}
field_declaration
: opt_dim_stmt
- variable_declarators EOL
+ variable_declarators logical_end_of_line
{
int mod = (int) current_modifiers;
-
VariableDeclaration.FixupTypes ((ArrayList) $2);
VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
if (current_container is Module)
mod = mod | Modifiers.STATIC;
+
+ // Structure members are Public by default
+ if ((current_container is Struct) && (mod == 0))
+ mod = Modifiers.PUBLIC;
+
+ if ((mod & Modifiers.Accessibility) == 0)
+ mod |= Modifiers.PRIVATE;
foreach (VariableDeclaration var in (ArrayList) $2){
Location l = var.Location;
-
Field field = new Field (var.type, mod, var.identifier,
var.expression_or_array_initializer,
(Attributes) null, l);
;
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
delegate_declaration
: DELEGATE SUB
- IDENTIFIER OPEN_PARENS
+ identifier OPEN_PARENS
opt_formal_parameter_list
CLOSE_PARENS
- EOL
+ logical_end_of_line
{
Location l = lexer.Location;
- Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (current_container, TypeManager.system_void_expr,
+ // 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);
+
+ Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
+ TypeManager.system_void_expr,
(int) current_modifiers,
- MakeName ((string) $3), (Parameters) $5,
+ MakeName ((string) $3), (Parameters) $5,
(Attributes) current_attributes, l);
del.Namespace = current_namespace;
CheckDef (current_container.AddDelegate (del), del.Name, l);
}
| DELEGATE FUNCTION
- IDENTIFIER OPEN_PARENS
+ identifier OPEN_PARENS
opt_formal_parameter_list
- CLOSE_PARENS AS type
+ CLOSE_PARENS opt_type_spec logical_end_of_line
{
Location l = lexer.Location;
- Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (
+
+ // 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);
+
+ 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; }
+ { $$ = null; }
| HANDLES qualified_identifier
- {
+ {
$$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
- }
+ }
+ | HANDLES MYBASE DOT qualified_identifier
+ {
+ // FIXME: this is blatantly wrong and crash-prone
+ $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
+ }
;
-
+
constructor_declaration
- : constructor_declarator
- opt_local_declarations
+ : SUB NEW opt_params logical_end_of_line
+ {
+ current_local_parameters = (Parameters) $3;
+ start_block();
+ oob_stack.Push (lexer.Location);
+
+ Location l = (Location) oob_stack.Pop ();
+ $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
+ $1 = $$;
+ }
opt_statement_list
{
Constructor c = (Constructor) $1;
c.Block = (Block) end_block();
c.ModFlags = (int) current_modifiers;
- c.OptAttributes = (Attributes) null;
+ c.OptAttributes = current_attributes;
- CheckDef (current_container.AddConstructor (c), c.Name, c.Location);
- current_local_parameters = null;
- }
- END SUB EOL
- ;
+ c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
-constructor_declarator
- : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
- {
- current_local_parameters = (Parameters) $4;
- start_block();
- oob_stack.Push (lexer.Location);
-
- Location l = (Location) oob_stack.Pop ();
- $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
+ CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
+ current_local_parameters = null;
}
+ END SUB logical_end_of_line
;
-
opt_formal_parameter_list
: /* empty */
{
fixed_parameter
: opt_attributes
opt_parameter_modifier
- IDENTIFIER opt_type_spec opt_variable_initializer
+ identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
{
Parameter.Modifier pm = (Parameter.Modifier)$2;
bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
+ Expression ptype;
- if (opt_parm && ($5 == null))
- Report.Error (999, "Optional parameters must have a default value");
+ if (opt_parm && ($7 == null))
+ Report.Error (30812, "Optional parameters must have a default value");
- if (opt_parm)
- pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
-
- $$ = new Parameter ((Expression) $4, (string) $3,
- pm, (Attributes) $1, (Expression) $5, opt_parm);
+ 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 ($4 != null && $6 != null && $4 != $6)
+ Report.Error (-1, 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);
+ }
+ $$ = new Parameter (ptype, (string) $3, pm,
+ (Attributes) $1, (Expression) $7, opt_parm);
}
;
parameter_array
- : PARAM_ARRAY IDENTIFIER opt_parens AS type
+ : PARAM_ARRAY identifier opt_parens AS type
{
- $$ = new Parameter ((Expression) $5, (string) $2, Parameter.Modifier.PARAMS, null);
+ 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
- ;
-
-opt_type_spec
- : /* empty */ { $$ = (Expression) TypeManager.system_object_expr; }
- | AS type { $$ = (Expression) $2; };
+ { $$ = true; }
;
opt_parameter_modifier
| OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
;
-opt_actual_parameters
+opt_statement_list
: /* empty */
- | qualified_identifier
- | LITERAL_STRING
+ | statement_list end_of_stmt
;
-opt_statement_list
- : /* empty */
- | statement_list EOL
+statement_list
+ : statement
+ | statement_list end_of_stmt statement
+ ;
+
+statement :
+ declaration_statement
+ {
+ 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);
+ }
+ | labeled_statement
+ | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
+ {
+ AddHandler ((Expression) $2, (string) $5);
+ }
+ | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
+ {
+ RemoveHandler ((Expression) $2, (string) $5);
+ }
+ | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
+ {
+ RaiseEvent ((string) $2, (ArrayList) $3);
+ }
+ /* | array_handling_statement */
+ /* | empty_statement */
+ | with_statement
+ {
+ Statement s = (Statement) $1;
+
+ current_block.AddStatement ((Statement) $1);
+ }
+ ;
+
+opt_raise_event_args
+ : /* empty */ { $$ = null; }
+ | OPEN_PARENS opt_argument_list CLOSE_PARENS
+ {
+ $$ = $2;
+ }
+ ;
+
+label_name
+ : identifier
+ | LITERAL_INTEGER
+ {
+ $$ = $1.ToString();
+ }
+ ;
+
+labeled_statement
+ : 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);
+
+ 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);
+ }
+ statement
+ ;
+
+embedded_statement
+ : expression_statement
+ | selection_statement
+ | iteration_statement
+ | try_statement
+ | synclock_statement
+ | jump_statement
+ | array_handling_statement
+ ;
+/*
+empty_statement
+ : end_of_stmt
+ {
+ $$ = new EmptyStatement ();
+ }
+ ;
+*/
+
+with_statement
+ : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
+ {
+ // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
+ Expression e = (Expression) $2;
+ with_stack.Push(e);
+ start_block();
+ }
+ opt_statement_list
+ END WITH
+ {
+ Block b = end_block();
+ with_stack.Pop();
+ $$ = b;
+ }
+ ;
+
+
+array_handling_statement
+ : redim_statement
+ | erase_statement
+ ;
+
+redim_statement
+ : REDIM opt_preserve redim_clauses
+ {
+ ArrayList list = (ArrayList) $3;
+ ReDim r = new ReDim (list, (bool) $2, lexer.Location);
+ $$ = r;
+
+ }
+ ;
+
+opt_preserve
+ : /* empty */ { $$ = false; }
+ | PRESERVE { $$ = true; }
+ ;
+
+redim_clauses
+ : redim_clause
+ {
+ ArrayList clauses = new ArrayList ();
+
+ clauses.Add ($1);
+ $$ = clauses;
+ }
+ | redim_clauses COMMA redim_clause
+ {
+ ArrayList clauses = (ArrayList) ($1);
+ clauses.Add ($2);
+
+ $$ = clauses;
+ }
+ ;
+
+redim_clause
+ : invocation_expression
+ {
+ Invocation i = (Invocation) $1;
+ RedimClause rc = new RedimClause (i.expr, i.Arguments);
+ $$ = rc;
+ }
+ ;
+
+erase_statement
+ : ERASE erase_clauses
+ {
+ ArrayList list = (ArrayList) $2;
+ foreach(Expression e in list)
+ {
+ Erase r = new Erase (e, lexer.Location);
+ $$ = r;
+ }
+ }
;
-statement_list
- : statement
- | statement_list EOL statement
- ;
-
-statement : embedded_statement
+erase_clauses
+ : erase_clause
{
- Statement s = (Statement) $1;
-
- current_block.AddStatement ((Statement) $1);
- }
- | labeled_statement EOL
- | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
- {
- AddHandler ((Expression) $2, (string) $5);
- }
- ;
-
+ ArrayList clauses = new ArrayList ();
-labeled_statement
- : IDENTIFIER COLON
+ clauses.Add ($1);
+ $$ = clauses;
+ }
+ | erase_clauses COMMA erase_clause
{
- LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
+ ArrayList clauses = (ArrayList) ($1);
+ clauses.Add ($2);
- 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);
+ $$ = clauses;
}
- statement
;
-embedded_statement
- : expression_statement
- | selection_statement
- | iteration_statement
- | try_statement
- | jump_statement
- ;
-
+erase_clause
+ : primary_expression
+ ;
+
jump_statement
: /*break_statement
| continue_statement
- | goto_statement
- | throw_statement
| */return_statement
+ | goto_statement
+ | throw_statement
| exit_statement
+ | yield_statement
;
+goto_statement
+ : GOTO label_name
+ {
+ $$ = new Goto (current_block, (string) $2, lexer.Location);
+ }
+ ;
+
+throw_statement
+ : THROW opt_expression
+ {
+ $$ = new Throw ((Expression) $2, lexer.Location);
+ }
+ ;
+
exit_statement
: EXIT exit_type
{
: while_statement
| do_statement
| for_statement
- /*| foreach_statement*/
+ | foreach_statement
+ ;
+
+foreach_statement
+ : FOR EACH identifier 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);
+ }
+ else
+ Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
+
+ oob_stack.Push (v);
+ }
+ opt_statement_list
+ NEXT opt_identifier
+ {
+ Block foreach_block = current_block;
+ LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
+ Block prev_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);
+ }
+
+ $$ = f;
+ }
+ ;
+
+yield_statement
+ : YIELD expression
+ {
+ if (!UseExtendedSyntax)
+ {
+ ReportError9998();
+ $$ = null;
+ }
+/* else
+ if (iterator_container == null){
+ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+ $$ = null;
+ } else {
+ iterator_container.SetYields ();
+ $$ = new Yield ((Expression) $2, lexer.Location);
+ } */
+ }
+ | YIELD STOP
+ {
+ if (!UseExtendedSyntax)
+ {
+ ReportError9998();
+ $$ = null;
+ }
+/* else
+ if (iterator_container == null){
+ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+ $$ = null;
+ } else {
+ iterator_container.SetYields ();
+ $$ = new YieldBreak (lexer.Location);
+ } */
+ }
+ ;
+
+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_finally
;
+try_header
+ : TRY end_of_stmt
+ {
+ start_block();
+ }
+ opt_statement_list
+ opt_catch_clauses
+ {
+ tmp_catch_clauses = (ArrayList) $5;
+ }
+ ;
+
try_catch
: try_header
END TRY
{
tmp_block = end_block();
}
- FINALLY EOL
+ FINALLY end_of_stmt
{
start_block();
}
$$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
}
- ;
-
-try_header
- : TRY EOL
- { Console.WriteLine ("try_header");
- start_block();
- }
- opt_statement_list
- opt_catch_clauses
- {
- tmp_catch_clauses = (ArrayList) $5;
- }
- ;
+ ;
opt_catch_clauses
: /* empty */ { $$ = null; }
opt_identifier
: /* empty */ { $$ = null; }
- | IDENTIFIER
+ | identifier
;
catch_clause
- : CATCH opt_catch_args EOL
+ : CATCH opt_catch_args end_of_stmt
{
Expression type = null;
string id = null;
ArrayList one = new ArrayList ();
Location loc = lexer.Location;
- one.Add (new VariableDeclaration (id, null, loc));
+ one.Add (new VariableDeclaration (id, type, loc));
$1 = current_block;
;
catch_args
- : IDENTIFIER AS type
+ : identifier AS type
{
$$ = new DictionaryEntry ($3, $1);
}
do_statement
- : DO opt_do_construct EOL
+ : DO opt_do_construct end_of_stmt
{
start_block();
oob_stack.Push (lexer.Location);
start_block();
oob_stack.Push (lexer.Location);
}
- boolean_expression EOL
+ boolean_expression end_of_stmt
opt_statement_list
END WHILE
{
for_statement
- : FOR qualified_identifier ASSIGN expression TO expression opt_step EOL
+ : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
{
start_block();
}
opt_statement_list
- NEXT opt_next_identifier
+ NEXT opt_identifier
{
Block statement = end_block();
Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
| STEP expression { $$ = $2; }
;
-opt_next_identifier
- : /* empty */
- | qualified_identifier
- ;
-
selection_statement
: if_statement
| select_statement
;
if_statement
- : if_statement_open if_statement_rest
+ : if_statement_open opt_then if_statement_rest
{
- $$ = $2;
+ $$ = $3;
+ }
+ | if_statement_open THEN pre_embedded_statement
+ {
+ Location l = (Location) oob_stack.Pop ();
+ tmp_expr = (Expression)expr_stack.Pop();
+ $$ = new If ((Expression) tmp_expr, end_block(), l);
}
;
+
+pre_embedded_statement
+ : embedded_statement
+ {
+ Statement s = (Statement) $1;
+
+ current_block.AddStatement ((Statement) $1);
+ }
+ ;
if_statement_open
- : IF boolean_expression THEN EOL
+ : IF boolean_expression
{
oob_stack.Push (lexer.Location);
start_block();
tmp_expr = (Expression) $2;
+ expr_stack.Push(tmp_expr);
}
;
+opt_then
+ : /* empty */
+ | THEN
+ ;
+
if_statement_rest
- :
+ : end_of_stmt
opt_statement_list
END IF
{
Location l = (Location) oob_stack.Pop ();
-
- $$ = new If ((Expression) tmp_expr, (Statement) end_block(), l);
-
+ Expression expr = (Expression)expr_stack.Pop();
+ $$ = new If ((Expression) expr, (Statement) end_block(), l);
}
- |
+ | end_of_stmt
opt_statement_list
- ELSE EOL
+ ELSE end_of_stmt
{
- tmp_block = end_block();
+ Block bl = end_block();
+ tmp_blocks.Push(bl);
start_block();
}
opt_statement_list
END IF
{
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, (Statement) end_block(), l);
- }
+ }
+ | end_of_stmt
+ opt_statement_list
+ ELSEIF boolean_expression opt_then
+ {
+ tmp_expr = (Expression) $4;
+ expr_stack.Push(tmp_expr);
+ tmp_block = end_block();
+ tmp_blocks.Push(tmp_block);
+ start_block();
+ }
+ else_if_statement_rest
+ {
+ Statement stmt = (Statement) statement_stack.Pop();
+ Block bl = (Block) tmp_blocks.Pop();
+ Expression expr = (Expression)expr_stack.Pop();
+ Location l = (Location) oob_stack.Pop ();
+ $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
+ }
+ ;
+
+
+else_if_statement_rest
+ : end_of_stmt
+ opt_statement_list
+ END IF
+ {
+ Location l = (Location) oob_stack.Pop ();
+ oob_stack.Push (l);
+ Expression expr = (Expression)expr_stack.Pop();
+ Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
+ statement_stack.Push(stmt);
+ }
+ | end_of_stmt
+ opt_statement_list
+ ELSE end_of_stmt
+ {
+ Block bl = end_block();
+ tmp_blocks.Push(bl);
+ start_block();
+ }
+ opt_statement_list
+ END IF
+ {
+ Location l = (Location) oob_stack.Pop ();
+ oob_stack.Push (l);
+ Expression expr = (Expression)expr_stack.Pop();
+ Block bl = (Block)tmp_blocks.Pop();
+ Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
+ statement_stack.Push(stmt);
+ }
+ | end_of_stmt
+ opt_statement_list
+ ELSEIF boolean_expression opt_then
+ {
+ expr_stack.Push((Expression) $4);
+ Block bl = end_block();
+ tmp_blocks.Push(bl);
+ start_block();
+ }
+ else_if_statement_rest
+ {
+ Location l = (Location) oob_stack.Pop ();
+ oob_stack.Push (l);
+ Statement tmp_stmt = (Statement)statement_stack.Pop();
+ Block bl = (Block) tmp_blocks.Pop();
+ Expression expr = (Expression)expr_stack.Pop();
+ Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
+ statement_stack.Push(stmt);
+ }
;
select_statement
- : SELECT opt_case expression EOL
+ : SELECT opt_case expression end_of_stmt
{
oob_stack.Push (lexer.Location);
switch_stack.Push (current_block);
}
;
+ends
+ : end_of_stmt
+ | ends end_of_stmt
+ ;
+
+
case_section
- : CASE case_clauses EOL
+ : CASE case_clauses ends
{
start_block();
}
opt_statement_list
{
- Block topmost = current_block;
-
+ //Block topmost = current_block;
+ Block topmost = end_block();
+
while (topmost.Implicit)
topmost = topmost.Parent;
topmost.statements.Add (new Break (lexer.Location));
$$ = new SwitchSection ((ArrayList) $2, topmost);
}
- | CASE ELSE EOL
+ | CASE ELSE ends
/* FIXME: we should somehow flag an error
(BC30321 'Case' cannot follow a 'Case Else'
in the same 'Select' statement.)
}
opt_statement_list
{
- Block topmost = current_block;
+ //Block topmost = current_block;
+ Block topmost = end_block();
while (topmost.Implicit)
topmost = topmost.Parent;
comparison_operator
: OP_LT
| OP_GT
- | OP_LT
| OP_LE
| OP_NE
- | OP_EQ
+ /*| OP_EQ */
;
opt_case
}
;
+
statement_expression
: invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
| object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
object_creation_expression
: NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
{
- $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
+ $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
+ }
+ | NEW type
+ {
+ $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
}
;
+
+array_creation_expression
+ : object_creation_expression array_initializer
+ {
+ New n = (New) $1;
+ ArrayList dims = new ArrayList();
+
+ if (n.Arguments != null) {
+ foreach (Argument a in n.Arguments) {
+ dims.Add (a.Expr);
+ }
+ }
+
+ Expression atype = n.RequestedType;
+
+ ArrayList init = (ArrayList) $2;
+ if (init.Count == 0)
+ init = null;
+
+ if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
+ VariableDeclaration.VBFixIndexList (ref dims);
+ $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
+ }
+ else
+ {
+ string rank = VariableDeclaration.BuildRank (dims);
+ $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
+ }
+ //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
+ }
+ ;
new_expression
: object_creation_expression
- /* | array_creation_expression */
- ;
-
-assignment_expression
- : prefixed_unary_expression ASSIGN expression
- {
- $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
- }
+ | array_creation_expression
;
-opt_local_declarations
- : /* empty */
- | local_declarations
- { if ($1 != null && (Block) $1 != current_block){
- current_block.AddStatement ((Statement) $1);
- current_block = (Block) $1;
- }
- }
- ;
-
-local_declarations
- : local_declaration EOL
- | local_declaration EOL local_declarations
- ;
-
-local_declaration
+declaration_statement
: local_variable_declaration
{
if ($1 != null){
$$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
}
}
-
| local_constant_declaration
{
if ($1 != null){
DictionaryEntry de = (DictionaryEntry) $1;
- $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
+ $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
}
}
;
{
$$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
}
- | DIM variable_declarators
+ ;
+
+
+local_constant_declaration
+ : CONST constant_declarators
+ {
+ if ($2 != null)
+ $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
+ else
+ $$ = null;
+ }
+ ;
+
+constant_declarators
+ : constant_declarator
+ {
+ ArrayList decl = new ArrayList ();
+ if ($1 != null)
+ decl.Add ($1);
+
+ $$ = decl;
+ }
+ | constant_declarators COMMA constant_declarator
+ {
+ ArrayList decls = (ArrayList) $1;
+ if ($3 != null)
+ decls.Add ($3);
+
+ $$ = $1;
+ }
+ ;
+
+constant_declarator
+ : variable_name opt_type_decl opt_variable_initializer
+ {
+ VarName vname = (VarName) $1;
+ string varname = (string) vname.Name;
+ current_rank_specifiers = (ArrayList) vname.Rank;
+ object varinit = $3;
+ ArrayList a_dims = null;
+
+ if (varinit == null)
+ Report.Error (
+ 30438, lexer.Location, "Constant should have a value"
+ );
+
+ if (vname.Type != null && $2 != null)
+ Report.Error (
+ 30302, lexer.Location,
+ "Type character cannot be used with explicit type declaration" );
+
+ Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
+
+ if (current_rank_specifiers != null)
+ {
+ Report.Error (30424, lexer.Location, "Constant doesn't support array");
+ $$ = null;
+ }
+ else
+ $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
+ }
+ ;
+
+variable_declarators
+ : variable_declarator
+ {
+ ArrayList decl = new ArrayList ();
+ decl.AddRange ((ArrayList) $1);
+ $$ = decl;
+ }
+ | variable_declarators COMMA variable_declarator
+ {
+ ArrayList decls = (ArrayList) $1;
+ decls.AddRange ((ArrayList) $3);
+ $$ = $1;
+ }
+ ;
+
+variable_declarator
+ : variable_names opt_type_decl opt_variable_initializer
+ {
+ ArrayList names = (ArrayList) $1;
+ object varinit = $3;
+ ArrayList VarDeclarations = new ArrayList();
+ Expression vartype;
+ ArrayList a_dims = null;
+
+ if ((names.Count > 1) && (varinit != null))
+ Report.Error (
+ 30671, lexer.Location,
+ "Multiple variables with single type can not have " +
+ "a explicit initialization" );
+
+
+ foreach (VarName vname in names)
+ {
+ string varname = (string) vname.Name;
+ current_rank_specifiers = (ArrayList) vname.Rank;
+ a_dims = null;
+ varinit = $3;
+
+ if(vname.Type != null && $2 != null)
+ Report.Error (
+ 30302, lexer.Location,
+ "Type character cannot be used with explicit type declaration" );
+
+ // Some checking is required for particularly weird declarations
+ // like Dim a As Integer(,)
+ if ($2 is Pair) {
+ vartype = (Expression) ((Pair) $2).First;
+
+ /*if ($3 != null && $3 is ArrayList)
+ Report.Error (205, "End of statement expected.");*/
+
+ ArrayList args = (ArrayList) ((Pair) $2).Second;
+ if (current_rank_specifiers != null)
+ Report.Error (31087, lexer.Location,
+ "Array types specified in too many places");
+
+ if (VariableDeclaration.IndexesSpecifiedInRank (args))
+ 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); */
+ }
+ else
+ vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
+
+ // if the variable is an array with explicit bound
+ // and having explicit initialization throw exception
+ if (current_rank_specifiers != null && varinit != null)
+ {
+ bool broken = false;
+ foreach (ArrayList exprs in current_rank_specifiers)
+ {
+ foreach (Expression expr in exprs)
+ {
+ if (!((Expression)expr is EmptyExpression ))
+ {
+ Report.Error (
+ 30672, lexer.Location,
+ "Array declared with explicit bound " +
+ " can not have explicit initialization");
+ broken = true;
+ break;
+ }
+ }
+ if (broken)
+ break;
+ }
+ }
+
+ /*
+ Check for a declaration like Dim a(2) or Dim a(2,3)
+ If this is the case, we must generate an ArrayCreationExpression
+ and, in case, add the initializer after the array has been created.
+ */
+ if (VariableDeclaration.IsArrayDecl (this)) {
+ if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
+ a_dims = (ArrayList) current_rank_specifiers;
+ VariableDeclaration.VBFixIndexLists (ref a_dims);
+ varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
+ }
+ vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
+ }
+
+ if (vartype is New) {
+ if (varinit != null) {
+ Report.Error (30205, lexer.Location, "End of statement expected");
+ $$ = null;
+ }
+ else
+ {
+ varinit = vartype;
+ vartype = ((New)vartype).RequestedType;
+ }
+ }
+ VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
+ }// end of for
+ $$ = VarDeclarations;
+ }
+ ;
+
+variable_names
+ : variable_name
{
- $$ = new DictionaryEntry (TypeManager.system_object_expr, $2);
+ ArrayList list = new ArrayList ();
+ list.Add ($1);
+ $$ = list;
}
- /*| DIM variable_declarators AS object_creation_expression
- {
- if ($4 != null)
- $$ = new DictionaryEntry ($4, $2);
- else
- $$ = null;
-
- } */
- ;
-
-
-local_constant_declaration
- : CONST constant_declarator
+ | variable_names COMMA variable_name
{
- if ($2 != null)
- $$ = new DictionaryEntry ($1, $2);
- else
- $$ = null;
+ ArrayList list = (ArrayList) $1;
+ list.Add ($3);
+ $$ = list;
}
- ;
+ ;
-constant_declarator
- : IDENTIFIER ASSIGN constant_expression
+variable_name
+ : identifier opt_type_character opt_array_name_modifier
{
- $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
+ $$ = new VarName ($1, $2, $3);
}
- ;
+ ;
-variable_declarators
- : variable_declarator
- {
- ArrayList decl = new ArrayList ();
- decl.Add ($1);
- $$ = decl;
+opt_type_spec
+ : /* empty */
+ {
+ $$ = null;
}
- | variable_declarators COMMA variable_declarator
- {
- ArrayList decls = (ArrayList) $1;
- decls.Add ($3);
- $$ = $1;
+ | AS type
+ {
+ $$ = (Expression) $2;
}
;
-
-variable_declarator
- : variable_identifier opt_type_decl opt_variable_initializer
- {
- string varname = (string)$1;
- string dims = "";
- Expression vartype = (Expression) $2;
- Expression varinit = (Expression) $3;
- /*
- Check for a declaration like Dim a(2) or Dim a(2,3)
- If this is the case, we must generate an ArrayCreationExpression
- and, in case, add the initializer after the array has been created.
- */
- if (VariableDeclaration.IsArrayDecl (varname)) {
- if (VariableDeclaration.HasDimBounds(varname)) {
- varname = VariableDeclaration.StripDims (varname, ref dims);
- ArrayList a_dims = VariableDeclaration.ParseDims(dims);
- varinit = new ArrayCreation (vartype, a_dims,"", null, lexer.Location);
- }
- vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.GetRank (dims), lexer.Location);
- }
- $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
- }
- ;
-
-variable_identifier
- : IDENTIFIER opt_array_name_modifier
+opt_type_with_ranks
+ : opt_type_spec
+ | AS type rank_specifiers
{
- $$ = $1;
- if ($2 != null)
- $$ = (string)$$ + (string)$2;
+ $$ = TypeManager.system_object_expr;
}
- ;
+ ;
opt_type_decl
- : /* empty */
+ : opt_type_spec
{
- $$ = null;
+ $$ = $1;
}
- | AS type opt_argument_list /* FIXME must handle argument list*/
+ | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
{
- $$ = $2;
+ $$ = new Pair ($2, $4);
}
- | AS NEW type opt_argument_list /* FIXME must handle NEW clause + argument list */
+ | AS NEW type
{
- $$ = $3;
+ New n = new New ((Expression)$3, null, lexer.Location);
+ $$ = (Expression) n;
}
- ;
+ | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
+ {
+ New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
+ $$ = (Expression) n;
+ }
+ /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
+ {
+ 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
: /* empty */ { $$ = null; }
- | array_type_modifier { $$ = $1; }
- | array_initialization_modifier
+ | array_type_modifier { $$ = $1; }
;
array_type_modifier
- : rank_specifiers { $$ = $1; }
- ;
-
-opt_dim_separators
- : /* empty */
- {
- $$ = "";
- }
- | dim_separators
- {
- $$ = $1;
- }
+ : rank_specifiers { $$ = $1; }
;
-dim_separators
- : COMMA
- {
- $$ = ",";
- }
- | dim_separators COMMA
- {
- $$ = (string) $1 + ",";
- }
- ;
-
opt_variable_initializer
: /* empty */ { $$ = null; }
| ASSIGN variable_initializer { $$ = $2; }
;
-
-array_initialization_modifier
- : /* empty */ { $$ = null; }
- ;
variable_initializer
: expression
{
$$ = $1;
}
- /*| array_initializer
+ | array_initializer
{
$$ = $1;
}
- */
+
;
-
-/*
- * The following is from Rhys' grammar:
- * > Types in local variable declarations must be recognized as
- * > expressions to prevent reduce/reduce errors in the grammar.
- * > The expressions are converted into types during semantic analysis.
- */
-local_variable_type
- : primary_expression opt_rank_specifier
- {
- // FIXME: Do something smart here regarding the composition of the type.
-
- // Ok, the above "primary_expression" is there to get rid of
- // both reduce/reduce and shift/reduces in the grammar, it should
- // really just be "type_name". If you use type_name, a reduce/reduce
- // creeps up. If you use qualified_identifier (which is all we need
- // really) two shift/reduces appear.
- //
-
- // So the super-trick is that primary_expression
- // can only be either a SimpleName or a MemberAccess.
- // The MemberAccess case arises when you have a fully qualified type-name like :
- // Foo.Bar.Blah i;
- // SimpleName is when you have
- // Blah i;
-
- Expression expr = (Expression) $1;
- if (!(expr is SimpleName || expr is MemberAccess)) {
- Error_ExpectingTypeName (lexer.Location, expr);
- $$ = null;
- } else {
- //
- // So we extract the string corresponding to the SimpleName
- // or MemberAccess
- //
- if ((string) $2 == "")
- $$ = $1;
- else
- $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
- }
- }
- | builtin_types opt_rank_specifier
+
+array_initializer
+ : OPEN_BRACE CLOSE_BRACE
{
- if ((string) $2 == "")
- $$ = $1;
- else
- $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+ ArrayList list = new ArrayList ();
+ $$ = list;
}
- ;
-
-rank_specifiers
- : rank_specifier
+ | OPEN_BRACE variable_initializer_list CLOSE_BRACE
{
- $$ = $1;
+ $$ = (ArrayList) $2;
}
- | rank_specifiers rank_specifier
- {
- $$ = (string) $2 + (string) $1;
- }
- ;
+ ;
-rank_specifier
- : OPEN_PARENS opt_dim_separators CLOSE_PARENS
+variable_initializer_list
+ : variable_initializer
+ {
+ ArrayList list = new ArrayList ();
+ list.Add ($1);
+ $$ = list;
+ }
+ | variable_initializer_list COMMA variable_initializer
{
- $$ = "[" + (string) $2 + "]";
+ ArrayList list = (ArrayList) $1;
+ list.Add ($3);
+ $$ = list;
}
;
-
-opt_rank_specifier
+
+opt_rank_specifiers
: /* empty */
{
- $$ = "";
+ // $$ = "";
+ $$ = null;
}
| rank_specifiers
{
$$ = $1;
}
- ;
+ ;
+rank_specifiers
+ : rank_specifier
+ {
+ ArrayList rs = new ArrayList();
+ rs.Add ($1);
+ $$ = rs;
+ }
+ | rank_specifiers rank_specifier
+ {
+ ArrayList rs = (ArrayList) $1;
+ rs.Add ($2);
+ $$ = rs;
+ }
+ ;
+
+rank_specifier
+ : OPEN_PARENS opt_dim_separators CLOSE_PARENS
+ {
+ $$ = $2;
+ }
+ ;
+
opt_dim_separators
: /* empty */
{
- $$ = "";
+ ArrayList ds = new ArrayList();
+ ds.Add (new EmptyExpression());
+ $$ = ds;
}
| dim_separators
{
- $$ = $1;
+ ArrayList ds = (ArrayList) $1;
+ ds.Add (new EmptyExpression());
+ $$ = ds;
}
| dim_specifiers
{
dim_separators
: COMMA
{
- $$ = ",";
+ ArrayList ds = new ArrayList();
+ ds.Add (new EmptyExpression());
+ $$ = ds;
}
| dim_separators COMMA
{
- $$ = (string) $1 + ",";
+ ArrayList ds = (ArrayList) $1;
+ ds.Add (new EmptyExpression());
+ $$ = ds;
}
;
-
+
dim_specifiers
- : integer_literal { $$ = ((IntLiteral)$1).AsString(); }
- | dim_specifiers COMMA integer_literal { $$ = $1 + "," + ((IntLiteral)$3).AsString(); }
+ : expression
+ {
+ ArrayList ds = new ArrayList();
+ ds.Add ((Expression) $1);
+ $$ = ds;
+ }
+ | dim_specifiers COMMA expression
+ {
+ ArrayList ds = (ArrayList) $1;
+ ds.Add ((Expression) $3);
+ $$ = ds;
+ }
;
-
-/* Expressions */
+
primary_expression
: literal
{
- // 7.5.1: Literals
+ //TODO
}
-
+ | parenthesized_expression
+ | this_access
+ | base_access
| qualified_identifier
{
string name = (string) $1;
-
- $$ = null;
$$ = DecomposeQI (name, lexer.Location);
}
- | parenthesized_expression
+ //FIXME: address_of_expression is apparently missing here
+ | get_type_expression
+ {
+ // TODO
+ }
| member_access
| invocation_expression
- | element_access
- | this_access
- | base_access
+ //| element_access
| new_expression
+ | cast_expression
;
literal
: boolean_literal
| integer_literal
| real_literal
+ | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
| LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
| LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
- | NOTHING { $$ = NullLiteral.Null; }
+ | NOTHING { $$ = NullLiteral.Null; }
;
real_literal
object v = lexer.Value;
if (v is int)
- $$ = new IntLiteral ((Int32) v);
- else if (v is uint)
- $$ = new UIntLiteral ((UInt32) v);
+ $$ = new IntLiteral ((Int32)v);
+ else if (v is short)
+ $$ = new ShortLiteral ((Int16)v);
else if (v is long)
- $$ = new LongLiteral ((Int64) v);
- else if (v is ulong)
- $$ = new ULongLiteral ((UInt64) v);
+ $$ = new LongLiteral ((Int64)v);
else
Console.WriteLine ("OOPS. Unexpected result from scanner");
;
member_access
- : primary_expression DOT IDENTIFIER
+ : primary_expression DOT identifier
{
- $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+ if ($1 != null) {
+ string id_name = (string)$3;
+ if (id_name.ToUpper() == "NEW")
+ id_name = ".ctor";
+ $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
+ }
+ else
+ {
+ if (with_stack.Count > 0) {
+ Expression e = (Expression) with_stack.Peek();
+ $$ = new MemberAccess (e, (string) $3, lexer.Location);
+ }
+ else
+ {
+ // OOps
+ }
+ }
}
- | predefined_type DOT IDENTIFIER
+/* | primary_expression DOT NEW
{
- $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+ $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
+ } */
+ | predefined_type DOT identifier
+ {
+ if ($1 != null)
+ $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+ else
+ {
+ if (with_stack.Count > 0) {
+ Expression e = (Expression) with_stack.Peek();
+ $$ = new MemberAccess (e, (string) $3, lexer.Location);
+ }
+ else
+ {
+ // OOps
+ }
+ }
}
;
Report.Error (1, l, "THIS IS CRAZY");
}
$$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
- }
+// Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
+ }
;
+
+base_access
+ : MYBASE DOT IDENTIFIER
+ {
+ string id_name = (string) $3;
+ if (id_name.ToUpper() == "NEW")
+ id_name = "New";
+ $$ = new BaseAccess (id_name, lexer.Location);
+ }
+/* | MYBASE DOT NEW
+ {
+ $$ = new BaseAccess ("New", lexer.Location);
+ }*/
+ ;
opt_argument_list
- : /* empty */ { $$ = null; }
- | argument_list
+ : argument_list
+ {
+ /*
+ The 'argument' rule returns an 'empty' argument
+ of type NoArg (used for default arguments in invocations)
+ if no arguments are actually passed.
+
+ If there is only one argument and it is o type NoArg,
+ we return a null (empty) list
+ */
+ ArrayList args = (ArrayList) $1;
+ if (args.Count == 1 &&
+ ((Argument)args[0]).ArgType == Argument.AType.NoArg)
+ $$ = null;
+ else
+ $$ = $1;
+ }
;
argument_list
{
$$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
}
+ | ADDRESSOF expression
+ {
+ $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
+ }
;
variable_reference
: expression {/* note ("section 5.4"); */ $$ = $1; }
;
-element_access
- : primary_expression OPEN_PARENS expression_list CLOSE_PARENS
- {
- $$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
- }
- /*| primary_expression rank_specifiers
- {
- // So the super-trick is that primary_expression
- // can only be either a SimpleName or a MemberAccess.
- // The MemberAccess case arises when you have a fully qualified type-name like :
- // Foo.Bar.Blah i;
- // SimpleName is when you have
- // Blah i;
- Expression expr = (Expression) $1;
- if (!(expr is SimpleName || expr is MemberAccess)) {
- Error_ExpectingTypeName (lexer.Location, expr);
- $$ = TypeManager.system_object_expr;
- } else {
- //
- // So we extract the string corresponding to the SimpleName
- // or MemberAccess
- //
- $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
- }
- }*/
+expression
+ : conditional_xor_expression { $$ = $1; }
+ /*| assignment_expression*/
;
opt_expression
: /* empty */
| expression
;
-
-expression_list
- : expression
- {
- ArrayList list = new ArrayList ();
- list.Add ($1);
- $$ = list;
- }
- | expression_list COMMA expression
- {
- ArrayList list = (ArrayList) $1;
- list.Add ($3);
- $$ = list;
- }
- ;
-
+
this_access
: ME
{
$$ = new This (current_block, lexer.Location);
}
- ;
-
-base_access
- : MYBASE DOT IDENTIFIER
- {
- $$ = new BaseAccess ((string) $3, lexer.Location);
- }
- | MYBASE OPEN_BRACKET expression_list CLOSE_BRACKET
+ | MYCLASS
{
- $$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location);
+ // FIXME: This is actually somewhat different from Me
+ // because it is for accessing static (classifier) methods/properties/fields
+ $$ = new This (current_block, lexer.Location);
}
;
-post_increment_expression
- : primary_expression OP_INC
+cast_expression
+ : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
{
- $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement,
- (Expression) $1, 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);
+ }
;
-
-unary_expression
+
+cast_operator
+ : CBOOL { $$ = TypeManager.system_boolean_expr; }
+ | CBYTE { $$ = TypeManager.system_byte_expr; }
+ | CCHAR { $$ = TypeManager.system_char_expr; }
+ | CDATE { $$ = TypeManager.system_date_expr; }
+ | CDBL { $$ = TypeManager.system_double_expr; }
+ | CDEC { $$ = TypeManager.system_decimal_expr; }
+ | CINT { $$ = TypeManager.system_int32_expr; }
+ | CLNG { $$ = TypeManager.system_int64_expr; }
+ | COBJ { $$ = TypeManager.system_object_expr; }
+ | CSHORT { $$ = TypeManager.system_int16_expr; }
+ | CSNG { $$ = TypeManager.system_single_expr; }
+ | CSTR { $$ = TypeManager.system_string_expr; }
+ ;
+
+get_type_expression
+ : GETTYPE OPEN_PARENS type CLOSE_PARENS
+ {
+ //TODO
+ }
+ ;
+
+exponentiation_expression
: primary_expression
- | NOT prefixed_unary_expression
+ | exponentiation_expression OP_EXP primary_expression
{
- $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
- }
+ //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);
}
- | ADDRESSOF prefixed_unary_expression
- {
- // FIXME: We should generate an error if AddressOf is NOT used
- // during delegate creation
- $$ = $2;
- }
;
multiplicative_expression
}
| multiplicative_expression DIV prefixed_unary_expression
{
- $$ = new Binary (Binary.Operator.Division,
- (Expression) $1, (Expression) $3, lexer.Location);
+ $$ = new Binary (Binary.Operator.Division,
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
+ ;
+
+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);
+ }
+ ;
+
+mod_expression
+ : integer_division_expression
+ | mod_expression MOD integer_division_expression
+ {
+ $$ = new Binary (Binary.Operator.Modulus,
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
+ ;
+
+additive_expression
+ : mod_expression
+ | additive_expression PLUS mod_expression
+ {
+ $$ = new Binary (Binary.Operator.Addition,
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
+ | additive_expression MINUS mod_expression
+ {
+ $$ = new Binary (Binary.Operator.Subtraction,
+ (Expression) $1, (Expression) $3, lexer.Location);
+ }
+ ;
+
+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
+ {
+ // TODO
}
- | multiplicative_expression OP_MODULUS prefixed_unary_expression
+ | shift_expression OP_SHIFT_RIGHT concat_expression
{
- $$ = new Binary (Binary.Operator.Modulus,
- (Expression) $1, (Expression) $3, lexer.Location);
+ //TODO
}
;
-additive_expression
- : multiplicative_expression
- | additive_expression PLUS multiplicative_expression
+relational_expression
+ : shift_expression
+ | relational_expression ASSIGN shift_expression
{
- $$ = new Binary (Binary.Operator.Addition,
+ $$ = new Binary (Binary.Operator.Equality,
(Expression) $1, (Expression) $3, lexer.Location);
}
- | additive_expression MINUS multiplicative_expression
+ | relational_expression OP_NE shift_expression
{
- $$ = new Binary (Binary.Operator.Subtraction,
+ $$ = new Binary (Binary.Operator.Inequality,
(Expression) $1, (Expression) $3, lexer.Location);
- }
- ;
-
-relational_expression
- : additive_expression
- | relational_expression OP_LT additive_expression
+ }
+ | 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 type
+ | relational_expression IS shift_expression
{
- $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
+ //FIXME: Is this rule correctly defined ?
}
- | relational_expression AS type
+ | TYPEOF shift_expression IS namespace_or_type_name
{
- $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
+ //FIXME: Is this rule correctly defined ?
}
;
-equality_expression
+negation_expression
: relational_expression
- | equality_expression OP_EQ relational_expression
+ | NOT negation_expression
{
- $$ = 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 OP_AND equality_expression
- {
- $$ = new Binary (Binary.Operator.BitwiseAnd,
- (Expression) $1, (Expression) $3, lexer.Location);
+ //FIXME: Is this rule correctly defined ?
+ $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
}
;
-
-exclusive_or_expression
- : and_expression
- | exclusive_or_expression OP_XOR and_expression
+
+conditional_and_expression
+ : negation_expression
+ | conditional_and_expression AND negation_expression
{
- $$ = new Binary (Binary.Operator.ExclusiveOr,
+ $$ = new Binary (Binary.Operator.LogicalAnd,
(Expression) $1, (Expression) $3, lexer.Location);
}
- ;
-
-conditional_and_expression
- : exclusive_or_expression
- | conditional_and_expression OP_AND 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_or_expression
: conditional_and_expression
- | conditional_or_expression OP_OR conditional_and_expression
+ | conditional_or_expression OR conditional_and_expression
{
$$ = new Binary (Binary.Operator.LogicalOr,
(Expression) $1, (Expression) $3, lexer.Location);
}
+ | conditional_or_expression ORELSE conditional_and_expression
+ { // FIXME: this is likely to be broken
+ $$ = new Binary (Binary.Operator.LogicalOr,
+ (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
: prefixed_unary_expression ASSIGN expression
- {
+ {
$$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
}
- ;
-
-expression
- : conditional_expression
- | assignment_expression
+ | 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
;
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
;
-array_type
- : type rank_specifiers
- {
- $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
- }
- ;
-
-rank_specifiers
- : rank_specifier opt_rank_specifier
- {
- $$ = (string) $2 + (string) $1;
- }
- ;
-
-rank_specifier
- : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
- {
- $$ = "[" + (string) $2 + "]";
- }
+builtin_types
+ : OBJECT { $$ = TypeManager.system_object_expr; }
+ | primitive_type
;
-opt_dim_separators
- : /* empty */
- {
- $$ = "";
- }
- | dim_separators
- {
- $$ = $1;
- }
+primitive_type
+ : numeric_type
+ | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
+ | DATE { $$ = TypeManager.system_date_expr; }
+ | CHAR { $$ = TypeManager.system_char_expr; }
+ | STRING { $$ = TypeManager.system_string_expr; }
;
+
-dim_separators
- : COMMA
- {
- $$ = ",";
- }
- | dim_separators COMMA
- {
- $$ = (string) $1 + ",";
- }
- ;
-/* Built-in / Integral types */
-builtin_types
- : OBJECT { $$ = TypeManager.system_object_expr; }
- | STRING { $$ = TypeManager.system_string_expr; }
- | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
+numeric_type
+ : integral_type
+ | floating_point_type
| DECIMAL { $$ = TypeManager.system_decimal_expr; }
- | SINGLE { $$ = TypeManager.system_single_expr; }
- | DOUBLE { $$ = TypeManager.system_double_expr; }
- | integral_type
;
integral_type
- : /*SBYTE { $$ = TypeManager.system_sbyte_expr; }
+ :
| BYTE { $$ = TypeManager.system_byte_expr; }
| SHORT { $$ = TypeManager.system_int16_expr; }
- | USHORT { $$ = TypeManager.system_uint16_expr; }
- | */ INTEGER { $$ = TypeManager.system_int32_expr; }/*
- | UINT { $$ = TypeManager.system_uint32_expr; }
+ | INTEGER { $$ = TypeManager.system_int32_expr; }
| LONG { $$ = TypeManager.system_int64_expr; }
- | ULONG { $$ = TypeManager.system_uint64_expr; }
- | CHAR { $$ = TypeManager.system_char_expr; }
- | VOID { $$ = TypeManager.system_void_expr; }*/
+ ;
+
+floating_point_type
+ : SINGLE { $$ = TypeManager.system_single_expr; }
+ | DOUBLE { $$ = TypeManager.system_double_expr; }
;
interface_type
- : type_name
+ : namespace_or_type_name
;
+
+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)
+ {
+ string id = ($2 as string);
+
+ 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");
+ }
+
+ ;
+
%%
}
}
-Expression DecomposeQI (string name, Location loc)
+public static Expression DecomposeQI (string name, Location loc)
{
Expression o;
Expression expr;
Expression type = decl.type;
- if (decl.expression_or_array_initializer is Expression){
+ if ((decl.expression_or_array_initializer is Expression) ||
+ (decl.expression_or_array_initializer is New)) {
expr = (Expression) decl.expression_or_array_initializer;
-
} else {
ArrayList init = (ArrayList) decl.expression_or_array_initializer;
return implicit_block;
}
-
-Block declare_local_constant (Expression type, VariableDeclaration decl)
+Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
{
Block implicit_block;
+ VariableDeclaration.FixupTypes (variable_declarators);
if (current_block.Used)
implicit_block = new Block (current_block, true);
else
implicit_block = current_block;
- if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
- current_local_parameters, decl.Location))){
+ foreach (VariableDeclaration decl in variable_declarators){
+ Expression type = decl.type;
+ implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
+ current_local_parameters, decl.Location);
}
return implicit_block;
}
+struct VarName {
+ public object Name;
+ public object Type;
+ public object Rank;
+
+ public VarName (object n, object t, object r)
+ {
+ Name = n;
+ Type = t;
+ Rank = r;
+ }
+ }
+
+
// <summary>
// A class used to pass around variable declarations and constants
// </summary>
public Attributes OptAttributes;
public Expression type;
public ArrayList dims;
-
- public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
- (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
- {
- }
-
+
public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
{
this.identifier = id;
{
}
+ public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
+ {
+ }
+
+ public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
+ (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
+ {
+ }
+
+ public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
+ {
+ // FIXME : This is broken: only the first rank is parsed
+ return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
+ }
+
public static void FixupTypes (ArrayList vars)
{
int varcount = vars.Count;
- VariableDeclaration lf = (VariableDeclaration) vars[varcount - 1];
+ VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
- if (lf.type == null)
- lf.type = TypeManager.system_object_expr;
+ if (last_var.type == null)
+ last_var.type = TypeManager.system_object_expr;
- Expression cur_type = lf.type;
+ Expression cur_type = last_var.type;
int n = varcount - 1;
while (n >= 0) {
}
}
- public static bool HasDimBounds (string varname)
+ public static bool IndexesSpecifiedInRank (ArrayList IndexList)
{
bool res = false;
- if (varname.IndexOf("[") >= 0) {
- char[] ds = {'1','2','3','4','5','6','7','8','9'};
-
- string dimpart = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
- if (dimpart.IndexOfAny (ds) >= 0)
- res = true;
+ if (IndexList != null) {
+ foreach (Expression e in IndexList)
+ if (!(e is EmptyExpression)) {
+ res = true;
+ break;
+ }
+ }
+ return (res);
+ }
+
+
+ public static bool IndexesSpecified (ArrayList ranks)
+ {
+ bool res = false;
+
+ if (ranks != null) {
+ foreach (ArrayList IndexList in ranks) {
+ if (IndexesSpecifiedInRank (IndexList)) {
+ res = true;
+ break;
+ }
+ }
}
return (res);
}
return (res);
}
- public static string GetRank (string dims)
+ public static string StripDims (string varname)
{
- string res = "";
- int x;
+ string dres = "";
- for (x = 0; x < dims.Length; x++) {
- if (dims[x] == '[' || dims[x] == ']' || dims[x] == ',')
- res = res + dims[x];
- }
- return (res);
- }
+ return (StripDims(varname, ref dres));
+ }
+
+ public static string StripIndexesFromDims (string dims)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ foreach (char c in dims)
+ if (c == ',' || c == ']' || c == '[')
+ sb.Append (c);
+
+ return sb.ToString();
+ }
- public static ArrayList ParseDims (string dims)
+ public static string BuildRank (ArrayList rank)
{
- ArrayList res = new ArrayList();
- string d = dims.Substring (1, dims.Length -2);
- Array a = d.Split (',');
+ string res = "";
+
+ res += "[";
+ for (int x = 0; x < (rank.Count -1 ); x++)
+ res += ",";
+
+ res += "]";
+ return res;
+ }
- if (a.GetLength(0) > 32) {
- Report.Error (999, "Arrays cannot have more than 32 dimensions");
+ public static string BuildRanks (Parser t)
+ {
+ string res = "";
+
+ foreach (ArrayList rank in t.current_rank_specifiers)
+ res += BuildRank (rank);
+
+ return res;
+ }
+
+ public static void VBFixIndexList (ref ArrayList IndexList)
+ {
+ if (IndexList != null) {
+ for (int x = 0; x < IndexList.Count; x++) {
+ Expression e = (Expression) IndexList[x];
+ if (!(e is EmptyExpression)) {
+ IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
+ }
+ }
}
-
- foreach (string s in a)
- res.Add (new IntLiteral ((Int32) Convert.ToInt32(s)));
-
- return (res);
}
- public static bool IsArrayDecl (string varname)
+ public static bool IsArrayDecl (Parser t)
{
- return (varname.IndexOf("[") >= 0);
+ // return (varname.IndexOf("[") >= 0);
+ return (t.current_rank_specifiers != null);
}
+ public static void VBFixIndexLists (ref ArrayList ranks)
+ {
+ if (ranks != null) {
+ for (int x = 0; x < ranks.Count; x++) {
+ ArrayList IndexList = (ArrayList) ranks[x];
+ VBFixIndexList (ref IndexList);
+ }
+ }
+ }
+
public static void FixupArrayTypes (ArrayList vars)
{
int varcount = vars.Count;
}
}
+
public Property BuildSimpleProperty (Expression p_type, string name,
Field p_fld, int mod_flags,
Attributes attrs, Location loc)
return (p);
}
-
+
void start_block ()
{
current_block = new Block (current_block, current_local_parameters,
AddHandler (current_block, evt_definition, handler_name);
}
-private void AddHandler (Block b, Expression evt_definition, string handler_name)
+void CheckAttributeTarget (string a)
+{
+ switch (a) {
+
+ case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
+ return;
+
+ default :
+ Location l = lexer.Location;
+ Report.Error (658, l, "`" + a + "' is an invalid attribute target");
+ break;
+ }
+}
+
+private void AddHandler (Block b, Expression evt_id, string handler_name)
{
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.Addition, evt_definition, (Expression) se, loc);
-
- Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc));
- b.AddStatement (s);
+ 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);
+}
+
+private void RaiseEvent (string evt_name, ArrayList args)
+{
+ Location loc = lexer.Location;
+
+ Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
+ Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
+ current_block.AddStatement (s);
}
-// FIXME: THIS DOES NOT WORK!!!
private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
{
- 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;
+ string evt_target = evt_definition.ToString();
+ evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
+ Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
+ b.AddStatement (s);
}
// <summary>
RemoveHandler (current_block, evt_definition, handler_name);
}
-
+private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
+{
+ ConstructorInitializer ci = null;
+
+ if (s.Count > 0) {
+ if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
+ Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
+
+ if (i.expr is BaseAccess) {
+ BaseAccess ba = (BaseAccess) i.expr;
+ if (ba.member == "New" || ba.member == ".ctor") {
+ ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
+ s.RemoveAt(0);
+ }
+ }
+ if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
+ ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
+ s.RemoveAt(0);
+ }
+ }
+ }
+ return ci;
+}
void Error_ExpectingTypeName (Location l, Expression expr)
{
return true;
}
-public override int parse ()
+private void ReportError9998()
{
- current_namespace = new Namespace (null, "");
+ Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
+}
+
+protected override int parse ()
+{
+ RootContext.InitializeImports(ImportsList);
+ current_namespace = new Namespace (null, RootContext.RootNamespace);
current_container = RootContext.Tree.Types;
current_container.Namespace = current_namespace;
oob_stack = new Stack ();
switch_stack = new Stack ();
-
+ expr_stack = new Stack ();
+ tmp_blocks = new Stack();
+ with_stack = new Stack();
+ statement_stack = new Stack();
+
UseExtendedSyntax = name.EndsWith(".mbs");
+ OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
+ OptionStrict = InitialOptionStrict || UseExtendedSyntax;
+ OptionCompareBinary = InitialOptionCompareBinary;
lexer = new Tokenizer (input, name, defines);
+
+ ifElseStateMachine = new IfElseStateMachine();
+ tokenizerController = new TokenizerController(lexer);
+
StringBuilder value = new StringBuilder ();
- //yacc_verbose_flag=true;
- try
- {
+ try {
if (yacc_verbose_flag)
yyparse (lexer, new yydebug.yyDebugSimple ());
- else
+ else {
yyparse (lexer);
+ cleanup();
+ }
}
- catch (Exception e)
- {
- Console.WriteLine (lexer.location + " : Parsing error in " + lexer.ref_name);
- Report.Error (9999, lexer.Location, "");
- Console.WriteLine (e);
+ catch(MBASException e) {
+ Report.Error(e.code, e.loc, e.Message);
}
-
+ catch (Exception e) {
+ Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.EffectiveSource + "\n" + e.ToString());
+ }
+
+ 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 */
}