Olen tässä CoolBasicistä insipoituneena kehitellyt vapaa-ajallani omaa virtuaalikonetta, joka nyt pääpiirteittäin toimii. Ideana olisi kasata sen päälle jokin CoolBasic:iä muistuttava Basic syntaksilla toimiva koodikieli ja siihen C++:lla taustalla toimiva pelimoottori.
Virtuaalikone on toteutettu C++:lla ja toimii tulkkiperiaatteella (compiler tekee keksimästäni "assemblystä" tavukoodia, jota virtuaalikone osaa suorittaa). Olen myös toteuttanut oman työkalun, joka osaa reflektoida natiiviluokat virtuaalikoneen käyttöön. Työkalun (build tool) avulla voin nopeasti lisätä uuden C++-funktion/luokan, joka tulee automaattisesti virtuaalikoneen käytettäväksi. Pääideanani oli saada tavukoodi toimimaan saumattomasti natiivikoodin kanssa, jolloin funktioita voidaan kutsua aina mistä vaan olkoon se sitten C++-funktio tai tavukoodissa toteutettu funktio.
Tällä hetkellä toimii funktiot (mukana myös virtual-funktiot), luokat (myös periytyminen), muuttujat, uusien objektien alustus luokasta, objektien propertyjen lukeminen ja kirjoittaminen, dynaaminen taulukko (myös objektitaulukot), dynaaminen map (key value pari), natiivi funktioiden kutsuminen sekä tavukoodiin luodun "event-funktion" kutsuminen C++-koodista.
Code: Select all
#pragma once
#include "GBXCoreLib.h"
#include "GBXPlatform.h"
#if GBX_PLATFORM == GBX_PLATFORM_WINDOWS
#include <Windows.h>
#endif
#include "GBXConsole.gen.h"
GBX_GENERATE_FILE()
namespace GBX
{
GBX_CLASS(Static)
class Console
{
public:
GBX_GENERATED_BODY_Console()
public:
Console();
~Console();
// Prints line of text to the console
GBX_FUNCTION()
static void Print(gbx::string Text);
private:
};
GBX_END_CLASS()
}
Reflektointi makroille voidaan myös antaa parametreja, jotka muokkaavat generointia. Esim. GBX_CLASS(Static) tekee luokasta staattisen, jolloin kyseisestä luokasta ei voida alustaa objekteja. GBX_FUNCTION(ImplementableEvent)-parametrilla reflektoitu funktio generoi uuden C++-funktion, jota kutsumalla virtuaalikone suorittaa tavukoodiin määrietllyn toteutuksen kyseiselle funktiolle.
Esimerkki eventeistä:
Code: Select all
// Header
GBX_FUNCTION(ImplementableEvent)
void OnUpdate(gbx::float32 DeltaTime, gbx::int32 FrameCount, gbx::boolean SkipFrame);
//Cpp
void TestObjectClass::OnUpdate(gbx::float32 DeltaTime, gbx::int32 FrameCount, gbx::boolean SkipFrame)
{
ExecuteEventImplementation_OnUpdate(this, DeltaTime, FrameCount, SkipFrame);
}
Oma "assembly"-koodini toimii välikielenä, jota olisi tarkoitus muodostaa Basic-syntaksi tyylisestä kielestä. Tällä hetkellä kieli näyttää kutakuinkin tältä:
Code: Select all
$decl_class 1 NameClass ObjectBase
$property string Name
$decl_class 1 NameClassDerived ObjectBase
$parent NameClass
$decl_func 1 string GetName NameClass 1 0 0 0
$RET this NameClass:Name <<p
$decl_func 2 void SetName NameClass 0 0 0 1 name string
$EXEC name << this NameClass:Name =p
$RET
$decl_func 1 string GetName NameClassDerived 1 0 0 0
$RET this NameClass:Name <<p " added string .+.
$decl_func 9 int32 Main global 0 0 0 0
$BS
$REG ref obj
$EXEC NameClassDerived new obj =
$EXEC obj << . "Nimi NameClass:SetName (m)
$REG string name
$EXEC obj << . NameClass:GetName (v) name =
$EXEC name << Console:Print ()
$ES
$RET 0
Seuraavan olisi tarkoitus lähteä miettimään, basic-syntaksia ja kääntäjää sille, joka tuottaa ylläolevaa koodia.