Links

Categories

Tags


« | Main | »

Anatomy of a new feature

By Jewe | May 25, 2014

I’m currently adding namespaces to JewelScript. This is some test-code I’ve written. The patient pretty much examines itself in self-diagnosis.

// Option 1: Create multiple namespaces at once
namespace System::Application
{
    // define class System::Application::Test
    class Test
    {
        // define delegate System::Application::Test::Del
        delegate float Del(float);

        // define cofunction System::Application::Test::Count
        cofunction int Count(int i) { yield i; }

        // define constant System::Application::Test::PI
        const float PI = 3.141;

        float f;
        Del d;          // use delegate type without full-qualified name
        Count c;        // use cofunction type without fqn
        method Test()
        {
            f = PI;             // use constant without fqn
            d = SetValue;       // use delegate without fqn
            c = new Count(0);   // use cofunction without fqn
        }
        method float SetValue(float f)
        {
            this.f = f;
            return f;
        }
        function string Hello(string s);
    }

    // Option 2: Nest namespaces
    namespace IO
    {
        // define interface System::Application::IO::IConsole
        interface IConsole
        {
            method Print(string);
            method string Input();
        }

        // define class System::Application::IO::Console and implement interface
        class Console : IConsole
        {
            Test::Del d;        // use partial namespace for delegate type
            Test::Count c;      // use partial namespace for cofunction type
            float f;
            method Console()
            {
                Test t;                     // use class Test from parent namespace
                d = t.SetValue;             // use delegate from class Test
                c = new Test::Count(0);     // use cofunction from class Test
                f = Test::PI;               // use constant from class Test
            }
        }
    }
}

// Option 3: Create namespaces in class declaration
class System::Application::Foo
{
    alias Test::Del Proc;   // use partial namespace for alias to delegate type

    function string main(const string[] args)
    {
        Test test = new Test();     // use partial namespace to access class Test
        IO::Console con = new IO::Console();  // use partial namespace to access
        return "";                            // class Console
    }
    function test(Proc pro)
    {
        string s = main({"", ""});
        s = Test::Hello(s);         // use partial namespace to access function Hello()
        float f = Test::PI;         // use partial namespace to access constant PI
    }
}

// implement function declared in namespace at global scope
function string System::Application::Test::Hello(string s)
{
    IO::Console con = new IO::Console(); // use partial namespace to access
    return s;                            // class Console
}

// implement interface from namespace out of namespace
class Terminal : System::Application::IO::IConsole
{
    method Terminal()
    {
    }
}

// create shortcut to System::Application::Test in global scope
alias System::Application::Test TestAlias;

// map System::Application::Test into global scope
using TestAlias;

function string main(const string[] args)
{
    // create instance of Test
    System::Application::Test t1 = new System::Application::Test();

    // create instance of Test via alias
    TestAlias t2 = new TestAlias();

    // create via 'using'
    Test t3 = new Test();

    // access constant PI
    float f = System::Application::Test::PI;

    // access via alias
    f = TestAlias::PI;

    // access via 'using'
    f = PI;

    // access global function from Test
    string s = System::Application::Test::Hello("Blah.");

    // access global function from Test via alias
    s = TestAlias::Hello("Hi!");

    // access global function via 'using'
    s = Hello("Hi!");

    // access delegate type from class Test
    System::Application::Test::Del d = t2.SetValue;

    // access cofunction type from class Test
    System::Application::Test::Count c = new System::Application::Test::Count(0);

    // access interface from System::Application::IO
    System::Application::IO::IConsole con = new System::Application::IO::Console();

    // access class from System::Application::IO
    System::Application::IO::Console con2 = (System::Application::IO::Console) con;

    // test operator '.' type-cast using alias
    var v = t1;
    v.TestAlias::SetValue(0.5);

    // test cast-operator type-cast using alias
    TestAlias t4 = (TestAlias) v;

    // test full-qualified operator '.' type-cast
    v.System::Application::Test::SetValue(0.5);

    // test full-qualified cast-operator
    t4 = (System::Application::Test) v;

    // test operator typeof() with fqn
    bool b = (typeof(v) == typeof(System::Application::Test));

    // test operator typeof() with alias
    b = (typeof(v) == typeof(TestAlias));

    return "";
}

Topics: code examples | Comments Off on Anatomy of a new feature

Comments are closed.