+2008-08-30 Miguel de Icaza <miguel@novell.com>
+
+ * namespace.cs (LookupType): In EvalMode, try to replace
+ the TypeBuilder from our cache with a Type as Reflection.Emit does
+ not like to mix code from older assemblies emitted and new
+ assemblies emitted.
+
+ This sounds like a serious Mono bug that prevents multiple
+ assemblies to be generated and consumed at the same time.
+
+ * cs-parser.jay (push_current_class): Do not make interactive
+ classes internal or private, make them public as we currently
+ generate each new class in a new assembly.
+
+2008-08-29 Miguel de Icaza <miguel@novell.com>
+
+ * decl.cs, roottypes.cs, class.cs:: Add an infrastructure to
+ remove types that are entered into the global namespace during
+ parsing so that we can remove them on failure.
+
+ * cs-parser.jay: Parsing: we now keep track of types that are
+ entered into global variables and queue those in case the parsing
+ or resolution fail.
+
+ This happens in a few situations: during partial-input, we invoke
+ the parser repeatedly for example with the string "class X", this
+ would cause X to be registed, and we need to remove this
+ registration so that another parse attempt later with say "class X {"
+ would actually work.
+
+ Additionally, if there is an error in the resolution phase, for
+ example: "class X : NonExistant {}" th
+
+ * cs-parser.jay: Be more precise with the errors being raised,
+ instead of flagging all exceptions during parsing to be attributed
+ to the parsing process, distinguish those from errors happening in
+ the actions and hint that using -v would produce the actual
+ exception.
+
+ * repl.cs: Do not load all compiler references on each reset,
+ doing the partial reset takes care of this.
+
+2008-08-28 Miguel de Icaza <miguel@novell.com>
+
+ * repl.cs: Add support for loading all the files from
+ ~/.config/csharp/*cs as startup scripts and ~/.config/csharp/*.dll
+ as shell libraries.
+
+ Introduce a micro-parser that is able to deambiguate on its input
+ whether we are dealing with a compilation unit (namespace, class,
+ interface, struct, delegate) declaration or a statement. This
+ allows both declarations and statements to be entered.
+
+ Set history size by default to 300 lines.
+
+ Instead of distinguishing based on the parser.InteractiveResult,
+ have only two cases: statements were parsed, or a compilation unit
+ was. Always pull the Using statement additions from the
+ compilation unit parse.
+
+ * cs-tokenizer.cs: Rename tokens to better describe their intent
+ (EvalStatementParserCharacter and EvalCompilationUnitParserCharacter).
+
+ * rootcontext.cs: Split EvalMode into EvalMode and StatementMode.
+ EvalMode is used to trigger the lookup of global variables while
+ StatementMode is used turn variable declarations into static
+ fields.
+
+ * getline.cs: Allow history size to be set.
+
2008-08-29 Marek Safar <marek.safar@gmail.com>
A fix for bug #360755
# Update manually.
qh:
MONO_PATH="../class/lib/net_2_0$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(RUNTIME_FLAGS) ../class/lib/net_2_0/gmcs.exe /codepage:65001 -d:GMCS_SOURCE -d:NET_1_1 -d:NET_2_0 -debug -target:exe -out:gmcs.exe cs-parser.cs @gmcs.exe.sources
- @ cp $(COMPILER_NAME).exe* $(topdir)/class/lib/$(PROFILE)/
q: cs-parser.cs qh
echo 'System.Console.WriteLine ("Hello");' | mono --debug gmcs.exe -v --shell
echo -e 'using System;\nConsole.WriteLine ("hello");' | mono --debug gmcs.exe -v --shell
- echo -e '"foo" == "bar"' | mono --debug gmcs.exe -v --shell
+ echo -e '"foo" == "bar";' | mono --debug gmcs.exe -v --shell
echo -e 'var a = 1;\na + 2;' | mono --debug gmcs.exe -v --shell
echo -e 'int j;\nj = 1;' | mono --debug gmcs.exe -v --shell
return false;
}
+ protected override void RemoveFromContainer (string name)
+ {
+ defined_names.Remove (name);
+ }
+
void DefineOverrides ()
{
Location loc = Location;
return AddToContainer (ds, ds.Basename);
}
+ protected virtual void RemoveMemberType (DeclSpace ds)
+ {
+ RemoveFromContainer (ds.Basename);
+ }
+
public void AddConstant (Const constant)
{
if (!AddMember (constant))
return tc;
}
+ public virtual void RemoveTypeContainer (TypeContainer next_part)
+ {
+ if (types != null)
+ types.Remove (next_part);
+ RemoveMemberType (next_part);
+ }
+
public void AddDelegate (Delegate d)
{
if (!AddMemberType (d))
/// resulting expression
public object InteractiveResult;
+ //
+ // Keeps track of global data changes to undo on parser error
+ //
+ public Undo undo;
+
+ // A counter to create new class names in interactive mode
static int class_count;
%}
%token GENERIC_DIMENSION
%token DEFAULT_COLON
-// Make the parser go into interactive parsing
-%token INTERACTIVE_PARSER
-%token INTERACTIVE_PARSER_USING_DIRECTIVES
+// Make the parser go into eval mode parsing (statements and compilation units).
+%token EVAL_STATEMENT_PARSER
+%token EVAL_COMPILATION_UNIT_PARSER
+%token EVAL_USING_DECLARATIONS_UNIT_PARSER
/* Add precedence rules to solve dangling else s/r conflict */
%nonassoc LOWPREC
e.AddEnumMember (em);
}
+ if (RootContext.EvalMode)
+ undo.AddTypeContainer (current_container, e);
current_container.AddTypeContainer (e);
+
$$ = e;
}
//
interactive_parsing
- : INTERACTIVE_PARSER EOF
- | INTERACTIVE_PARSER_USING_DIRECTIVES using_directives {
- InteractiveResult = current_namespace;
- }
- | INTERACTIVE_PARSER {
+ : EVAL_STATEMENT_PARSER EOF
+ | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives
+ | EVAL_STATEMENT_PARSER {
InteractiveShell.LoadAliases (current_namespace);
push_current_class (new Class (current_namespace, current_class, new MemberName ("Class" + class_count++),
InteractiveResult = pop_current_class ();
current_local_parameters = null;
}
+// | EVAL_COMPILATION_UNIT_PARSER {
+// InteractiveShell.LoadAliases (current_namespace);
+// }
+// compilation_unit
;
%%
void push_current_class (TypeContainer tc, object partial_token)
{
+ if (RootContext.EvalMode){
+ tc.ModFlags = (tc.ModFlags & ~(Modifiers.PRIVATE|Modifiers.INTERNAL)) | Modifiers.PUBLIC;
+ undo.AddTypeContainer (current_container, tc);
+ }
+
if (partial_token != null)
current_container = current_container.AddPartial (tc);
else
current_container = current_container.AddTypeContainer (tc);
+
+
current_class = tc;
}
// that are in the top block to be added instead to the class as
// static variables
//
- if (RootContext.EvalMode){
+ if (RootContext.StatementMode){
bool hoist = true;
for (Block b = current_block; b != null; b = b.Parent){
assign = new SimpleAssign (new SimpleName (decl.identifier, decl.Location), var);
current_block.AddStatement (new StatementExpression (assign));
} else {
- Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.NEW | Modifiers.PUBLIC | Modifiers.STATIC, decl.identifier, null, loc);
+ Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.PUBLIC | Modifiers.STATIC, decl.identifier, null, loc);
current_container.AddField (f);
// Register the field to be visible later as a global variable
public CSharpParser (SeekableStreamReader reader, CompilationUnit file)
{
+ if (RootContext.EvalMode)
+ undo = new Undo ();
+
this.file = file;
current_namespace = new NamespaceEntry (null, file, null);
current_class = current_namespace.SlaveDeclSpace;
public void parse ()
{
- int errors = Report.Errors;
-
eof_token = Token.EOF;
try {
} catch (Exception e){
if (e is yyParser.yyUnexpectedEof)
UnexpectedEOF = true;
- if (Report.Errors == errors)
+ else if (yacc_verbose_flag > 0)
+ Console.WriteLine (e);
+ if (e is yyParser.yyException)
Report.Error (-25, lexer.Location, "Parsing error");
+ else
+ Report.Error (-32, lexer.Location, "Internal compiler error during parsing, Run with -v for details");
}
Tokenizer tokenizer = lexer as Tokenizer;
tokenizer.cleanup ();
-
if (RootContext.ToplevelTypes.NamespaceEntry != null)
throw new InternalErrorException ("who set it?");
}
// impact on the tokenizer's performance.
//
- public const int InteractiveParserCharacter = 0x2190; // Unicode Left Arrow
- public const int InteractiveParserCharacterUsing = 0x2191; // Unicode Down Arrow
+ public const int EvalStatementParserCharacter = 0x2190; // Unicode Left Arrow
+ public const int EvalCompilationUnitParserCharacter = 0x2191; // Unicode Arrow
+ public const int EvalUsingDeclarationsParserCharacter = 0x2192; // Unicode Arrow
//
// XML documentation buffer. The save point is used to divide
}
}
- if (c == InteractiveParserCharacter)
- return Token.INTERACTIVE_PARSER;
-
- if (c == InteractiveParserCharacterUsing)
- return Token.INTERACTIVE_PARSER_USING_DIRECTIVES;
+ if (c == EvalStatementParserCharacter)
+ return Token.EVAL_STATEMENT_PARSER;
+ if (c == EvalCompilationUnitParserCharacter)
+ return Token.EVAL_COMPILATION_UNIT_PARSER;
+ if (c == EvalUsingDeclarationsParserCharacter)
+ return Token.EVAL_USING_DECLARATIONS_UNIT_PARSER;
error_details = ((char)c).ToString ();
return false;
}
+ protected virtual void RemoveFromContainer (string name)
+ {
+ defined_names.Remove (name);
+ }
+
/// <summary>
/// Returns the MemberCore associated with a given name in the declaration
/// space. It doesn't return method based symbols !!
Reset (true);
}
- public static void Reset (bool full)
+ public static void PartialReset ()
+ {
+ Reset (false);
+ }
+
+ public static void Reset (bool full_flag)
{
Driver.Reset ();
- RootContext.Reset ();
+ RootContext.Reset (full_flag);
Tokenizer.Reset ();
Location.Reset ();
Report.Reset ();
TypeManager.Reset ();
TypeHandle.Reset ();
- if (full)
+ if (full_flag)
RootNamespace.Reset ();
NamespaceEntry.Reset ();
// TODO:
// Enter an error (a = 1); Notice how the prompt is in the wrong line
// This is caused by Stderr not being tracked by System.Console.
-// Typing before the program start causes the cursor position to be wrong
-// This is caused by Console not reading all the available data
-// before sending the report-position sequence and reading it back.
// Completion support
-// System.Console needs to get the DELETE character, and report accordingly.
// Why is Thread.Interrupt not working? Currently I resort to Abort which is too much.
-// Console needs SIGWINCH support of some sort
//
+// Limitations in System.Console:
+// Console needs SIGWINCH support of some sort
+// Console needs a way of updating its position after things have been written
+// behind its back (P/Invoke puts for example).
+// System.Console needs to get the DELETE character, and report accordingly.
+// Typing before the program start causes the cursor position to be wrong
+// This is caused by Console not reading all the available data
+// before sending the report-position sequence and reading it back.
//
#if NET_2_0 || NET_1_1
#define IN_MCS_BUILD
using System.Text;
using System.IO;
using System.Threading;
+using System.Reflection;
namespace Mono.Terminal {
void CmdDebug ()
{
history.Dump ();
+ Console.WriteLine ();
+ Render ();
}
void Render ()
shown_prompt = prompt;
InitText (initial);
history.Append (initial);
-
+
do {
try {
EditLoop ();
string line;
while ((line = sr.ReadLine ()) != null){
- Append (line);
+ if (line != "")
+ Append (line);
}
}
}
//
tdecl.DefineType ();
t = tdecl.TypeBuilder;
+
+ if (RootContext.EvalMode){
+ // Replace the TypeBuilder with a System.Type, as
+ // Reflection.Emit fails otherwise (we end up pretty
+ // much with Random type definitions later on).
+ Type tt = t.Assembly.GetType (t.Name);
+ if (tt != null)
+ t = tt;
+ }
}
}
string lookup = t != null ? t.FullName : (fullname.Length == 0 ? name : fullname + "." + name);
declspaces.Add (name, ds);
}
+ public void RemoveDeclSpace (string name)
+ {
+ declspaces.Remove (name);
+ }
+
/// <summary>
/// The qualified name of the current namespace
/// </summary>
// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
// Copyright 2004, 2005, 2006, 2007, 2008 Novell, Inc
//
-//
+//
+// TODO:
+// Do not print results in Evaluate, do that elsewhere in preparation for Eval refactoring.
+// Driver.PartialReset should not reset the coretypes, nor the optional types, to avoid
+// computing that on every call.
//
using System;
using System.IO;
return editor.Edit (prompt, "");
}
}
+
#else
static void SetupConsole ()
{
// Here just to shut up the compiler warnings about unused invoking variable
if (invoking)
invoking = false;
+
+ Console.Error.WriteLine ("Warning: limited functionality in 1.0 mode");
}
static string GetLine (bool primary)
return Console.ReadLine ();
}
+
#endif
+ delegate string ReadLiner (bool primary);
static void Reset ()
{
- CompilerCallableEntryPoint.Reset (false);
- Driver.LoadReferences ();
+ CompilerCallableEntryPoint.PartialReset ();
+ //
+ // PartialReset should not reset the core types, this is very redundant.
+ //
if (!TypeManager.InitCoreTypes ())
throw new Exception ("Failed to InitCoreTypes");
TypeManager.InitOptionalCoreTypes ();
{
isatty = UnixUtils.isatty (0) && UnixUtils.isatty (1);
+ // Work around, since Console is not accounting for
+ // cursor position when writing to Stderr. It also
+ // has the undesirable side effect of making
+ // errors plain, with no coloring.
+ Report.Stderr = Console.Out;
SetupConsole ();
if (isatty)
}
- static public int ReadEvalPrintLoop ()
+ static void LoadStartupFiles ()
{
- InitTerminal ();
- RootContext.EvalMode = true;
+ string dir = Path.Combine (
+ Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData),
+ "csharp");
+ if (!Directory.Exists (dir))
+ return;
- InitializeUsing ();
-
+ foreach (string file in Directory.GetFiles (dir)){
+ string l = file.ToLower ();
+
+ if (l.EndsWith (".cs")){
+ try {
+ using (StreamReader r = File.OpenText (file)){
+ ReadEvalPrintLoopWith (p => r.ReadLine ());
+ }
+ } catch {
+ }
+ } else if (l.EndsWith (".dll")){
+ Driver.LoadAssembly (file, true);
+ }
+ }
+ }
+
+ static void ReadEvalPrintLoopWith (ReadLiner readline)
+ {
string expr = null;
while (true){
- string input = GetLine (expr == null);
+ string input = readline (expr == null);
if (input == null)
- return 0;
+ return;
if (input == "")
continue;
expr = Evaluate (expr);
}
}
+
+ static public int ReadEvalPrintLoop ()
+ {
+ CompilerCallableEntryPoint.Reset ();
+ Driver.LoadReferences ();
+
+ InitTerminal ();
+ RootContext.EvalMode = true;
+
+ InitializeUsing ();
+
+
+ LoadStartupFiles ();
+ ReadEvalPrintLoopWith (GetLine);
+
+ return 0;
+ }
static string Evaluate (string input)
if (partial_input)
return input;
- if (parser == null){
- ParseString (false, input, out partial_input);
- return null;
- }
+ ParseString (false, input, out partial_input);
+ return null;
}
//
//
object result = parser.InteractiveResult;
- if (result is Class){
- try {
- object rval = ExecuteBlock ((Class) result);
-
- //
- // We use a reference to a compiler type, in this case
- // Driver as a flag to indicate that this was a statement
- //
- if (rval != typeof (NoValueSet)){
- PrettyPrint (rval);
- Console.WriteLine ();
- }
- } catch (Exception e){
- Console.WriteLine (e);
+ try {
+ if (!(result is Class))
+ parser.CurrentNamespace.Extract (using_alias_list, using_list);
+
+ object rval = ExecuteBlock (result as Class, parser.undo);
+ //
+ // We use a reference to a compiler type, in this case
+ // Driver as a flag to indicate that this was a statement
+ //
+ if (rval != typeof (NoValueSet)){
+ PrettyPrint (rval);
+ Console.WriteLine ();
}
- } else if (result is NamespaceEntry){
- ((NamespaceEntry)result).Extract (using_alias_list, using_list);
- } else if (result == null){
- // Just a happy parse.
- } else {
- Console.Error.WriteLine ("Support for {0} is not available on the shell", parser.InteractiveResult);
+ } catch (Exception e){
+ Console.WriteLine (e);
}
return null;
}
+ enum InputKind {
+ EOF,
+ StatementOrExpression,
+ CompilationUnit,
+ Error
+ }
+
+ //
+ // Deambiguates the input string to determine if we
+ // want to process a statement or if we want to
+ // process a compilation unit.
+ //
+ // This is done using a top-down predictive parser,
+ // since the yacc/jay parser can not deambiguage this
+ // without more than one lookahead token. There are very
+ // few ambiguities.
+ //
+ static InputKind ToplevelOrStatement (SeekableStreamReader seekable)
+ {
+ Tokenizer tokenizer = new Tokenizer (seekable, Location.SourceFiles [0]);
+
+ int t = tokenizer.token ();
+ switch (t){
+ case Token.EOF:
+ return InputKind.EOF;
+
+ // These are toplevels
+ case Token.EXTERN:
+ case Token.OPEN_BRACKET:
+ case Token.ABSTRACT:
+ case Token.CLASS:
+ case Token.ENUM:
+ case Token.INTERFACE:
+ case Token.INTERNAL:
+ case Token.NAMESPACE:
+ case Token.PRIVATE:
+ case Token.PROTECTED:
+ case Token.PUBLIC:
+ case Token.SEALED:
+ case Token.STATIC:
+ case Token.STRUCT:
+ return InputKind.CompilationUnit;
+
+ // Definitely expression
+ case Token.FIXED:
+ case Token.BOOL:
+ case Token.BYTE:
+ case Token.CHAR:
+ case Token.DECIMAL:
+ case Token.DOUBLE:
+ case Token.FLOAT:
+ case Token.INT:
+ case Token.LONG:
+ case Token.NEW:
+ case Token.OBJECT:
+ case Token.SBYTE:
+ case Token.SHORT:
+ case Token.STRING:
+ case Token.UINT:
+ case Token.ULONG:
+ return InputKind.StatementOrExpression;
+
+ // These need deambiguation help
+ case Token.USING:
+ t = tokenizer.token ();
+ if (t == Token.EOF)
+ return InputKind.EOF;
+
+ if (t == Token.IDENTIFIER)
+ return InputKind.CompilationUnit;
+ return InputKind.StatementOrExpression;
+
+
+ // Distinguish between:
+ // delegate opt_anonymous_method_signature block
+ // delegate type
+ case Token.DELEGATE:
+ t = tokenizer.token ();
+ if (t == Token.EOF)
+ return InputKind.EOF;
+ if (t == Token.OPEN_PARENS || t == Token.OPEN_BRACE)
+ return InputKind.StatementOrExpression;
+ return InputKind.CompilationUnit;
+
+ // Distinguih between:
+ // unsafe block
+ // unsafe as modifier of a type declaration
+ case Token.UNSAFE:
+ t = tokenizer.token ();
+ if (t == Token.EOF)
+ return InputKind.EOF;
+ if (t == Token.OPEN_PARENS)
+ return InputKind.StatementOrExpression;
+ return InputKind.CompilationUnit;
+
+ // These are errors: we list explicitly what we had
+ // from the grammar, ERROR and then everything else
+
+ case Token.READONLY:
+ case Token.OVERRIDE:
+ case Token.ERROR:
+ return InputKind.Error;
+
+ // This catches everything else allowed by
+ // expressions. We could add one-by-one use cases
+ // if needed.
+ default:
+ return InputKind.StatementOrExpression;
+ }
+ }
+
//
// Parses the string @input and returns a CSharpParser if succeeful.
//
partial_input = false;
Reset ();
queued_fields.Clear ();
-
+
Stream s = new MemoryStream (Encoding.Default.GetBytes (input));
SeekableStreamReader seekable = new SeekableStreamReader (s, Encoding.Default);
- Tokenizer t = new Tokenizer (seekable, Location.SourceFiles [0]);
- //
- // Deambiguate: do we have a using statement, or a using clause
- //
- int initial_token;
- if (t.token () == Token.USING && t.token () == Token.IDENTIFIER)
- initial_token = Tokenizer.InteractiveParserCharacterUsing;
- else
- initial_token = Tokenizer.InteractiveParserCharacter;
+ InputKind kind = ToplevelOrStatement (seekable);
+ if (kind == InputKind.Error){
+ if (!silent)
+ Report.Error (-25, "Detection Parsing Error");
+ partial_input = false;
+ return null;
+ }
+
+ if (kind == InputKind.EOF){
+ if (silent == false)
+ Console.Error.WriteLine ("Internal error: EOF condition should have been detected in a previous call with silent=true");
+ partial_input = true;
+ return null;
+
+ }
seekable.Position = 0;
CSharpParser parser = new CSharpParser (seekable, Location.SourceFiles [0]);
parser.ErrorOutput = Report.Stderr;
- parser.Lexer.putback_char = initial_token;
+ if (kind == InputKind.StatementOrExpression){
+ parser.Lexer.putback_char = Tokenizer.EvalStatementParserCharacter;
+ RootContext.StatementMode = true;
+ } else {
+ //
+ // Do not activate EvalCompilationUnitParserCharacter until
+ // I have figured out all the limitations to invoke methods
+ // in the generated classes. See repl.txt
+ //
+ parser.Lexer.putback_char = Tokenizer.EvalUsingDeclarationsParserCharacter;
+ //parser.Lexer.putback_char = Tokenizer.EvalCompilationUnitParserCharacter;
+ RootContext.StatementMode = false;
+ }
+
if (silent)
Report.DisableReporting ();
try {
if (Report.Errors != 0){
if (silent && parser.UnexpectedEOF)
partial_input = true;
+
+ parser.undo.ExecuteUndo ();
parser = null;
}
if (silent)
Report.EnableReporting ();
}
-
return parser;
}
//
static ArrayList queued_fields = new ArrayList ();
- static ArrayList types = new ArrayList ();
+ //static ArrayList types = new ArrayList ();
static volatile bool invoking;
- static object ExecuteBlock (Class host)
+ static object ExecuteBlock (Class host, Undo undo)
{
RootContext.ResolveTree ();
+ if (Report.Errors != 0){
+ undo.ExecuteUndo ();
+ return typeof (NoValueSet);
+ }
+
RootContext.PopulateTypes ();
RootContext.DefineTypes ();
- if (Report.Errors != 0)
+ if (Report.Errors != 0){
+ undo.ExecuteUndo ();
return typeof (NoValueSet);
+ }
- TypeBuilder tb = host.TypeBuilder;
- types.Add (tb);
+ TypeBuilder tb = null;
MethodBuilder mb = null;
- foreach (MemberCore member in host.Methods){
- if (member.Name != "Host")
- continue;
+
+ if (host != null){
+ tb = host.TypeBuilder;
+ mb = null;
+ foreach (MemberCore member in host.Methods){
+ if (member.Name != "Host")
+ continue;
+
+ MethodOrOperator method = (MethodOrOperator) member;
+ mb = method.MethodBuilder;
+ break;
+ }
- MethodOrOperator method = (MethodOrOperator) member;
- mb = method.MethodBuilder;
- break;
+ if (mb == null)
+ throw new Exception ("Internal error: did not find the method builder for the generated method");
}
-
- if (mb == null)
- throw new Exception ("Internal error: did not find the method builder for the generated method");
RootContext.EmitCode ();
if (Report.Errors != 0)
if (Environment.GetEnvironmentVariable ("SAVE") != null)
CodeGen.Save (current_debug_name, false);
+ if (host == null)
+ return typeof (NoValueSet);
+
//
// Unlike Mono, .NET requires that the MethodInfo is fetched, it cant
// work from MethodBuilders. Retarded, I know.
//
Type tt = CodeGen.Assembly.Builder.GetType (tb.Name);
MethodInfo mi = tt.GetMethod (mb.Name);
-
+
// Pull the FieldInfos from the type, and keep track of them
foreach (Field field in queued_fields){
FieldInfo fi = tt.GetField (field.Name);
-
+
FieldInfo old = (FieldInfo) fields [field.Name];
-
+
// If a previous value was set, nullify it, so that we do
// not leak memory
if (old != null){
fields [field.Name] = fi;
}
+ //types.Add (tb);
+
queued_fields.Clear ();
HostSignature invoker = (HostSignature) System.Delegate.CreateDelegate (typeof (HostSignature), mi);
object retval = typeof (NoValueSet);
-
+
try {
invoking = true;
invoker (ref retval);
} finally {
invoking = false;
}
-
+
// d.DynamicInvoke (new object [] { retval });
return retval;
return null;
Field f = new Field (container, new TypeExpression (ret.Type, Location),
- Modifiers.NEW | Modifiers.PUBLIC | Modifiers.STATIC,
+ Modifiers.PUBLIC | Modifiers.STATIC,
name, null, Location);
container.AddField (f);
if (f.Define ())
}
}
+ public class Undo {
+ ArrayList undo_types;
+
+ public Undo ()
+ {
+ undo_types = new ArrayList ();
+ }
+
+ public void AddTypeContainer (TypeContainer current_container, TypeContainer tc)
+ {
+ if (current_container == tc){
+ Console.Error.WriteLine ("Internal error: inserting container into itself");
+ return;
+ }
+
+ if (undo_types == null)
+ undo_types = new ArrayList ();
+ undo_types.Add (new Pair (current_container, tc));
+ }
+
+ public void ExecuteUndo ()
+ {
+ if (undo_types == null)
+ return;
+
+ foreach (Pair p in undo_types){
+ TypeContainer current_container = (TypeContainer) p.First;
+
+ current_container.RemoveTypeContainer ((TypeContainer) p.Second);
+ }
+ undo_types = null;
+ }
+ }
+
/// <summary>
/// The base class for every interaction line
/// </summary>
* Mix statements with other top-level declarations.
- Currently we only process statements, but it would be useful
- to define classes, interfaces and structs inline.
+csharp> class Y {static void Main () {Console.WriteLine ("Foo"); }}
+csharp> typeof (Y);
+Y
+csharp> Y.Main ();
+Exception caught by the compiler while compiling:
+ Block that caused the problem begin at: Internal(1,1):
+ Block being compiled: [<interactive>(1,2):,<interactive>(1,11):]
+System.NotSupportedException: The invoked member is not supported in a dynamic module.
+Internal compiler error at Internal(1,1):: exception caught while emitting MethodBuilder [Class2::Host]
+System.NotSupportedException: The invoked member is not supported in a dynamic module.
+ at System.Reflection.Emit.AssemblyBuilder.get_Location () [0x00000] in /second/home/cvs/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.cs:214
+ at Mono.CSharp.Report.SymbolRelatedToPreviousError (System.Reflection.MemberInfo mi) [0x00036] in /second/home/cvs/mcs/mcs/report.cs:664
+ at Mono.CSharp.Expression.Error_MemberLookupFailed (System.Type container_type, System.Type qualifier_type, System.Type queried_type, System.String name, System.String class_name, MemberTypes mt, BindingFlags bf) [0x00121] in /second/home/cvs/mcs/mcs/ecore.cs:857
+ at Mono.CSharp.MemberAccess.DoResolve (Mono.CSharp.EmitContext ec, Mono.CSharp.Expression right_side) [0x00230] in /second/home/cvs/mcs/mcs/expression.cs:7426
+ at Mono.CSharp.MemberAccess.DoResolve (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/expression.cs:7494
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec, ResolveFlags flags) [0x00075] in /second/home/cvs/mcs/mcs/ecore.cs:479
+ at Mono.CSharp.Invocation.DoResolve (Mono.CSharp.EmitContext ec) [0x0000d] in /second/home/cvs/mcs/mcs/expression.cs:4725
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec, ResolveFlags flags) [0x00075] in /second/home/cvs/mcs/mcs/ecore.cs:479
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/ecore.cs:506
+ at Mono.CSharp.OptionalAssign.DoResolve (Mono.CSharp.EmitContext ec) [0x00013] in /second/home/cvs/mcs/mcs/repl.cs:681
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec, ResolveFlags flags) [0x00075] in /second/home/cvs/mcs/mcs/ecore.cs:479
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/ecore.cs:506
+ at Mono.CSharp.ExpressionStatement.ResolveStatement (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/ecore.cs:1307
+ at Mono.CSharp.StatementExpression.Resolve (Mono.CSharp.EmitContext ec) [0x0000b] in /second/home/cvs/mcs/mcs/statement.cs:743
+ at Mono.CSharp.Block.Resolve (Mono.CSharp.EmitContext ec) [0x000f0] in /second/home/cvs/mcs/mcs/statement.cs:2254
+ at Mono.CSharp.ExplicitBlock.Resolve (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/statement.cs:2550
+ at Mono.CSharp.EmitContext.ResolveTopBlock (Mono.CSharp.EmitContext anonymous_method_host, Mono.CSharp.ToplevelBlock block, Mono.CSharp.Parameters ip, IMethodData md, System.Boolean& unreachable) [0x00087] in /second/home/cvs/mcs/mcs/codegen.cs:796
+csharp>
+
+* Another one:
+
+csharp> class X { X (){ Console.WriteLine ("Called"); } }
+csharp> new X ();
+Exception caught by the compiler while compiling:
+ Block that caused the problem begin at: Internal(1,1):
+ Block being compiled: [<interactive>(1,2):,<interactive>(1,10):]
+System.NotSupportedException: The invoked member is not supported in a dynamic module.
+Internal compiler error at Internal(1,1):: exception caught while emitting MethodBuilder [Class0::Host]
+System.NotSupportedException: The invoked member is not supported in a dynamic module.
+ at System.Reflection.Emit.AssemblyBuilder.get_Location () [0x00000] in /second/home/cvs/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.cs:214
+ at Mono.CSharp.Report.SymbolRelatedToPreviousError (System.Reflection.MemberInfo mi) [0x00036] in /second/home/cvs/mcs/mcs/report.cs:664
+ at Mono.CSharp.Expression.Error_MemberLookupFailed (System.Type container_type, System.Type qualifier_type, System.Type queried_type, System.String name, System.String class_name, MemberTypes mt, BindingFlags bf) [0x00121] in /second/home/cvs/mcs/mcs/ecore.cs:857
+ at Mono.CSharp.Expression.MemberLookupFinal (Mono.CSharp.EmitContext ec, System.Type qualifier_type, System.Type queried_type, System.String name, MemberTypes mt, BindingFlags bf, Location loc) [0x0002f] in /second/home/cvs/mcs/mcs/ecore.cs:804
+ at Mono.CSharp.New.DoResolve (Mono.CSharp.EmitContext ec) [0x002ad] in /second/home/cvs/mcs/mcs/expression.cs:5486
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec, ResolveFlags flags) [0x00075] in /second/home/cvs/mcs/mcs/ecore.cs:479
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/ecore.cs:506
+ at Mono.CSharp.OptionalAssign.DoResolve (Mono.CSharp.EmitContext ec) [0x00013] in /second/home/cvs/mcs/mcs/repl.cs:687
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec, ResolveFlags flags) [0x00075] in /second/home/cvs/mcs/mcs/ecore.cs:479
+ at Mono.CSharp.Expression.Resolve (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/ecore.cs:506
+ at Mono.CSharp.ExpressionStatement.ResolveStatement (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/ecore.cs:1307
+ at Mono.CSharp.StatementExpression.Resolve (Mono.CSharp.EmitContext ec) [0x0000b] in /second/home/cvs/mcs/mcs/statement.cs:743
+ at Mono.CSharp.Block.Resolve (Mono.CSharp.EmitContext ec) [0x000f0] in /second/home/cvs/mcs/mcs/statement.cs:2254
+ at Mono.CSharp.ExplicitBlock.Resolve (Mono.CSharp.EmitContext ec) [0x00000] in /second/home/cvs/mcs/mcs/statement.cs:2550
+ at Mono.CSharp.EmitContext.ResolveTopBlock (Mono.CSharp.EmitContext anonymous_method_host, Mono.CSharp.ToplevelBlock block, Mono.CSharp.Parameters ip, IMethodData md, System.Boolean& unreachable) [0x00087] in /second/home/cvs/mcs/mcs/codegen.cs:796
+csharp>
+
+* Important: we need to replace TypeBuidlers with Types after things
+ have been emitted, or stuff like this happens:
+
+csharp> public class y {}
+csharp> typeof (y);
+Class1
- These pose a problem, as the grammar conflicts on a few
- elements like delegate (delegate declaration or anonymous
- method declration).
-
- To address this issue, I should build a mini-parser into
- repl.cs that does an initial pass at the input stream and
- determines with as many lookahead tokens as needed whether the
- text is regular toplevel declaration or our statement
- declaration.
-
- This would solve the grammar ambiguity that happens if we just
- allow both to be starting nodes.
* Clearing data
//
// If true, it means that the compiler is executing as
- // in eval mode.
+ // in eval mode so unresolved variables are resolved in
+ // static classes maintained by the eval engine.
//
static public bool EvalMode;
+ //
+ // If true, the compiler is operating in statement mode,
+ // this currently turns local variable declaration into
+ // static variables of a class
+ //
+ static public bool StatementMode;
+
//
// Whether to allow Unsafe code
//
//
static RootContext ()
{
- Reset ();
+ Reset (true);
}
- public static void Reset ()
+ public static void PartialReset ()
{
- root = new RootTypes ();
+ Reset (false);
+ }
+
+ public static void Reset (bool full)
+ {
+ if (full)
+ root = new RootTypes ();
+
type_container_resolve_order = new ArrayList ();
EntryPoint = null;
Report.WarningLevel = 4;
{
// TODO: It'd be so nice to have generics
Hashtable anonymous_types;
-
+
public RootTypes ()
: base (null, null, MemberName.Null, null, Kind.Root)
{
return true;
}
+ protected override void RemoveMemberType (DeclSpace ds)
+ {
+ ds.NamespaceEntry.NS.RemoveDeclSpace (ds.Basename);
+ base.RemoveMemberType (ds);
+ }
+
public override TypeContainer AddPartial (TypeContainer nextPart)
{
return AddPartial (nextPart, nextPart.Name);
}
+
}
public class RootDeclSpace : DeclSpace {