Type initialization exception on Eval

Aug 30, 2011 at 11:43 PM

I'm trying to make very basic calls into IronPython from C# (using the tutorial in the Documentation area) and I'm hitting a roadblock.

If I try to use a string extension method (e.g., "(+ 1 2)".Eval()), I get a TypeInitializationException, complaining that the type initializer for IronScheme.RuntimeExtensions threw an exception.  If I use schemeEngine.Evaluate("(+ 1 2)") I get better results, but frequently run into the TypeInitializationException.  schemeEngine.ExecuteFile hits the same problem.

I'm happy to admit that I'm probably screwing up here someplace - just hoping someone can get me pointed down the right path.  I'm using the June 6, 2011 download onto a Windows 7, 64 bit machine running inside VS 2010.  I've tried setting the Target framework to both .NET Framework 4 and .NET Framework 2.0 without success.  My project references IronScheme, ironscheme.boot and Microsoft.Scripting as provided in the download.  I'm "using":

using System;
using IronScheme;
using IronScheme.Hosting;
using IronScheme.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
Running IronScheme.Console seems to work ok.  I'm able to, well, run scheme programs!  Including loading the file that causes my C# program to die.

What am I doing wrong?

Thanks,
Russell.

My little program (don't laugh - it's just to play!).  Commented code shows some of the things I've tried.

using System;
using IronScheme;
using IronScheme.Hosting;
using IronScheme.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;

namespace lear.ironScheme
{
    class SchemeHandler
    {
        private readonly IScriptEngine schemeEngine;

        public SchemeHandler()
        {
            var mgr = ScriptDomainManager.CurrentManager;
            var slp = new IronSchemeLanguageProvider(mgr);
            schemeEngine = slp.GetEngine();
        }

        public object Evaluate(string input)
        {
            //return schemeEngine.Evaluate(input);
            return input.Eval();
        }

        public void RunFile(string fn) {
            schemeEngine.ExecuteFile(fn);
        }
    }

    class Program
    {
        static void Main(string[] args) {
            var handler = new SchemeHandler();
            var lambda = handler.Evaluate("(lambda (x y) (+ x y))");
            object result = "Not set";

            // handler.Evaluate(@"(load ""Scripts\TestDefs.ss""");
            handler.RunFile(@"Scripts\TestDefs.ss");
            handler.Evaluate("(define (myadd x y) (+ x y))");
            result = handler.Evaluate("(myadd 3 7)");
            //result = "({0} {1} {2})".Eval(lambda, 1, 2);
            Console.WriteLine("result = {0}", result);
            Console.ReadKey();
        }
    }
}

Coordinator
Aug 31, 2011 at 4:42 AM
Hi
You need to reference IronScheme.Closures.dll too, or make sure it is in the application directory next to ironscheme.dll and IronScheme.boot.dll.
Cheers
leppie

Coordinator
Aug 31, 2011 at 5:26 AM

Also, RunFile will likely (actually most probably) not work.

You were almost correct with calling LOAD (the scheme proc), but that will load the file outside the scope of the interaction environment.

What you are looking for is INCLUDE, which will execute the file content in the interaction environment.

Example: (include "Scripts/TestDefs.ss")

Cheers

leppie

Aug 31, 2011 at 4:28 PM
Thanks for the notes. I'll use INCLUDE. Unfortunately, adding IronScheme.Closures.dll doesn't seem to fix my extension problem.

If I call handler.Evaluate("(+ 1 2)"), the exception says something about:

Type 'IronScheme.Hosting.IronSchemeLanguageProvider' doesn't provide a suitable public constructor or its implementation is faulty.

and the Console output says

Unhandled exception:
&undefined
&message: "attempted to use undefined symbol"
&irritants: (mod0)

If I try running from a command window (rather than from VS), I see:
Unhandled exception:
&undefined
&message: "attempted to use undefined symbol"
&irritants: (mod0)

Unhandled Exception:
Cannot print exception string because Exception.ToString() failed.

I've done a "Clean Solution" / "Rebuild Solution" after adding the new reference.

Coordinator
Aug 31, 2011 at 4:36 PM
rrlear wrote:
 If I call handler.Evaluate("(+ 1 2)"), the exception says something about:

Type 'IronScheme.Hosting.IronSchemeLanguageProvider' doesn't provide a suitable public constructor or its implementation is faulty.

Set VS to catch all exceptions, then see what is faulty in the the InnerException. 

I will try simulate from my side too.

Coordinator
Aug 31, 2011 at 4:47 PM

OK, managed to simulate it. Can't figure out why it is happening, but I have the solution. :)

Just remove the code from the constructor. Calling Eval on a string correctly initializes everything.

It is possible the 'double' initialization is causing an issue.

Cheers

leppie

Coordinator
Aug 31, 2011 at 4:50 PM

Found the reason it is causing the problem.

One should initialize the language provider as:

ScriptDomainManager.CurrentManager.GetLanguageProvider(typeof(IronSchemeLanguageProvider));

Coordinator
Aug 31, 2011 at 4:59 PM

I have fixed the issue now. See last checkin.

Well, made it so it can't happen. 

IronSchemeLanguageProvider now has internal constructors.

Aug 31, 2011 at 5:46 PM
Later today or tomorrow I'll try bringing over the IronScheme source and building from that. It might help me find something if I could poke into it.

Warning: More information than you probably want follows!

Trying to display the inner exceptions by iterating on the InnerException field. Unfortunately, at some point the InnerException is bad:

Unhandled exception:
&undefined
&message: "attempted to use undefined symbol"
&irritants: (mod0)
Getting information on the exception
Exception: TypeInitializationException
Exception: The type initializer for 'IronScheme.RuntimeExtensions' threw an exception.
Getting information on the exception
Exception: InvalidImplementationException
Exception: Type 'IronScheme.Hosting.IronSchemeLanguageProvider' doesn't provide a suitable public constructor or its implementation is faulty.
Getting information on the exception
Exception: SchemeException
*** Got an exception displaying the exception
*** The type initializer for 'IronScheme.RuntimeExtensions' threw an exception.

Although I normally hate screen shots I'm hoping you can glean something from this:


Aug 31, 2011 at 5:46 PM
erg... ignore previous note! Sorry, only now catching up with mail
Aug 31, 2011 at 6:10 PM

Thanks much!  Things are working and I'm a happy developer.

Coordinator
Aug 31, 2011 at 6:44 PM
Glad I could help Smile
And thanks for pointing out possible usage issues.