abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 12:44 | Pozvánky

    V sobotu 1. června lze navštívit Maker Faire Ostrava, festival plný workshopů, interaktivních činností a především nadšených a zvídavých lidí.

    Ladislav Hagara | Komentářů: 0
    dnes 12:22 | Nová verze

    Webový server Caddy (Wikipedie) s celou řadou zajímavých vlastností byl vydán ve verzi 2.8 (𝕏). Přehled novinek na GitHubu.

    Ladislav Hagara | Komentářů: 0
    včera 22:11 | Nová verze

    Byla vydána verze 3.0 (@, 𝕏) svobodného softwaru HAProxy (The Reliable, High Performance TCP/HTTP Load Balancer; Wikipedie) řešícího vysokou dostupnost, vyvažování zátěže a reverzní proxy. Detailní přehled novinek v příspěvku na blogu společnosti HAProxy Technologies.

    Ladislav Hagara | Komentářů: 3
    včera 21:11 | IT novinky

    Společnost Framework Computer představila novou vylepšenou verzi svého modulárního notebooku Framework Laptop 13 s Intel Core Ultra Series 1, displej s lepším rozlišením a novou webovou kameru. Přímo do Česka jej zatím koupit nelze.

    Ladislav Hagara | Komentářů: 0
    včera 15:44 | Nová verze

    Byla vydána nová verze 2.16 svobodného video editoru Flowblade (GitHub, Wikipedie). Přehled novinek v poznámkách k vydání. Videoukázky funkcí Flowblade na Vimeu. Instalovat lze také z Flathubu.

    Ladislav Hagara | Komentářů: 2
    28.5. 21:22 | Zajímavý software

    TerminalTextEffects (TTE) je engine pro vizuální efekty v terminálu. Zdrojové kódy jsou k dispozici na GitHubu pod licencí MIT.

    Ladislav Hagara | Komentářů: 38
    28.5. 17:11 | Pozvánky

    Od čtvrtka 30. 5. do soboty 1. 6. lze v Praze navštívit Veletrh vědy, tj. největší populárně naučnou akci v České republice, kterou každoročně od roku 2015 pořádá Akademie věd ČR. Vstup zdarma.

    Ladislav Hagara | Komentářů: 13
    28.5. 14:11 | Komunita

    Canonical představil Ubuntu optimalizované pro jednodeskový počítač s RISC-V procesorem Milk-V Mars.

    Ladislav Hagara | Komentářů: 0
    27.5. 21:22 | Nová verze

    Armbian, tj. linuxová distribuce založená na Debianu a Ubuntu optimalizovaná pro jednodeskové počítače na platformě ARM a RISC-V, ke stažení ale také pro Intel a AMD, byl vydán ve verzi 24.5.1 Havier. Přehled novinek v Changelogu.

    Ladislav Hagara | Komentářů: 0
    27.5. 19:44 | IT novinky

    Společnost xAI založena Elonem Muskem a stojící za AI LLM modelem Grok získala investici 6 miliard dolarů.

    Ladislav Hagara | Komentářů: 1
    Podle hypotézy Mrtvý Internet mj. tvoří většinu online interakcí boti.
     (89%)
     (3%)
     (4%)
     (4%)
    Celkem 997 hlasů
     Komentářů: 16, poslední 14.5. 11:05
    Rozcestník

    Uclang - integrace skriptovacích jazyků

    27.6.2015 14:34 | Přečteno: 979× | Vývoj software | Výběrový blog

    Kolem rozšířených skriptovacích jazyků, které se dokázaly prosadit v konkurenci, a dnes se stále aktivně vyvíjejí se vytvořil bohatý ekosystém modulů a knihoven, které jsou programátorovi programujícímu v takovémto jazyku k dispozici. Bylo by užitečné zprostředkovat přístup k těmto prostředkům i programátorovi programujícím v jazyce uclang. V následujícím zápisku vám předvedu, jak je možné prostřednictvím existujících modulů jazyka uclang využívat knihovny a moduly některých rozšířených skriptovacích jazyků.

    Následující text se skládá ze tří částí popisujících integraci tří různých skriptovacích jazyků, pokud čtenáře zajímá pouze to, jak je obecně řešena integrace jiného skriptovacího jazyka v jazyce uclang, stačí mu k pochopení tohoto principu přečtení pouze jedné z těchto tří částí.

    Motivace pro využití skriptovacích jazyků

    Jak bylo uvedeno v úvodu, obsáhle knihovny modulů vytvořené pro rozšířené skriptovací jazyky jsou zdrojem velkého množství použitelných algoritmů. Snadný přístup k těmto algoritmům a nástrojům z prostředí skriptu zapsaného v jazyce uclang je hlavním motivačním bodem pro integrování externích skriptovacích jazyků.

    Dalším důvodem pro integraci externího skriptovacího jazyka je možnost parametrizace programu napsaného v jazyce uclang, jazykem, který je rozšířený a jehož syntaxe je známá velkému počtu programátorů.

    Třetím důvodem pro integraci externích skriptovacích jazyků do jazyka uclang je sjednocení rozhraní pro přístup k integrovaným skriptovacím jazykům. Přístup k implementaci C/C++ rozhraní v rámci jednotlivých skriptovacích jazyků se podstatně liší jazyk od jazyka. Rozhraní v rámci jazyka uclang je více méně stejné pro všechny integrované skriptovací jazyky. Teoreticky by neměl být problém vytvořit C/C++ sdílenou knihovnu založenou na modulech jazyka uclang, která by zprostředkovala jednoduché rozhraní k integrovaným skriptovacím jazykům.

    Integrace jazyka python

    Jazyk python je jedním z množiny nejrozšířenějších skriptovacích jazyků. V rámci práce na jazyku python vzniklo velké množství modulů, které je možné využít při řešení různorodých úloh. Jazyk python je možné integrovat jako rozšiřující skriptovací jazyk do libovolné aplikace. Na základě takové integrace je možné vytvořit modul zprostředkující nástroje jazyka python skriptu zapsanému v jazyce uclang.

    Příklad použití jazyka python

    Předpokládejme dva níže uvedené skripty. První skript je zapsán v jazyce python a reprezentuje triviální modul, v rámci kterého jsou definovány jednoduché třídy, funkce a objekty.

    class Person:
        def __init__(self,a_name,a_surname):
            self.name = a_name;
            self.surname = a_surname;
    
    persons = {
      'omar' : Person('Omar','Little'),
      'avone' : Person('Avone','Barksdale')
    }
    
    def person_dict():
        result = {}
    
        for id in persons:
            result[id] = persons[id].__dict__;
    
        return result
    
    def person_list():
        result = []
    
        for id in persons:
            person = persons[id]
            result.append(person.name + ' ' + person.surname)
    
        return result
    
    def json(a_json,a_dict):
        return a_json.dumps(a_dict,separators=(',',':'))

    Druhý skript je zapsán v jazyce uclang a importuje první skript za účelem využití tříd, funkcí a objektů definovaných v prvním skriptu. Jednotlivé části uvedeného skriptu jsou podrobně popsány dále v textu.

    import containers;
    import python;
    import json;
    
    class Main
    {
      // - print information about person -
      public person_info(a_person)
      {
        return "%s %s" % [
          a_person.name.to_string(),
          a_person.surname.to_string()];
      }
    
      public Main(a_argv)
      {
        sys  = PyObject.module("sys");
        os   = PyObject.module("os");
        json = PyObject.module("json");
    
        // - update python import path -
        sys.path.append("%s/%s" % [
            os.getcwd().value(),
            os.path.split(a_argv[0])[0].value()]);
    
        // - load demo module -
        demo = PyObject.module("demo");
    
        // - module demo properties -
        ("demo properties: %s\n" % demo.dir().value().to_string()).print();
    
        // - retrieve person from dictionary -
        avone = demo.persons["avone"];
        ("person: %s\n" % person_info(avone)).print();
        ("persons: %s\n" % demo.person_list().value().to_string()).print();
    
        // - add person to dictionary -
        frank = demo.Person("Frank","Sobotka");
        demo.persons["frank"] = frank;
        ("person: %s\n" % person_info(frank)).print();
        ("persons: %s\n" % demo.person_list().value().to_string()).print();
    
        // - create persons JSON in python -
        python_json = demo.json(json,demo.person_dict());
        ("python_json: %s\n" % python_json.value()).print();
    
        // - create persons JSON in uclang -
        ucl_json = Json.create(demo.person_dict().value());
        ("ucl_json:    %s\n" % ucl_json).print();
      }
    
      static public main(argv)
      {
        new Main(argv);
      }
    }

    Popis skriptu používajícího jazyk python

    Prvním krokem je import modulů, kde moduly containers a python jsou stěžejní, a bez těchto není možné použít prvky jazyka python. Modul containers obsahuje třídy Set a Dict, které jsou nezbytné pro popis dat, obsažených v objektech jazyka python. Modul python, který obsahuje uvedenou závislost na modulu containers, importuje všechny třídy, které umožňují využít skriptovací jazyk python v jazyce uclang.

    import containers;
    import python;
    import json;

    Následuje základní kostra programu, která je víceméně shodná s kostrou libovolného skriptu zapsaného v jazyce uclang. Kód popisovaný níže v textu bude vkládán do konstruktoru třídy Main.

    class Main
    {
      public Main(a_argv)
      {
        ...
      }
    
      static public main(argv)
      {
        new Main(argv);
      }
    }

    Inicializace virtuálního stroje (interpretu) jazyka python proběhne už při importu modulu python. V rámci tohoto importu se také provede načtení nezbytných dynamických knihoven. V případě, kdy není modul python importován nemá skript jazyka uclang ani jeho interpret s jazykem python nic co do činění. V dalším kroku, je možné importovat základní moduly jazyka python.

    sys  = PyObject.module("sys");
    os   = PyObject.module("os");
    json = PyObject.module("json");

    Pro potřeby importu modulu jazyka python z adresáře ve kterém se nachází spuštěný uclang skript musí být rozšířena proměnná os.path jazyka python. Za tímto účelem použijeme importované moduly, následujícím způsobem.

    // - update python import path -
    sys.path.append("%s/%s" % [
        os.getcwd().value(),
        os.path.split(a_argv[0])[0].value()]);
    
    // - load demo module -
    demo = PyObject.module("demo");

    Z výše uvedeného kódu je již možné vycítit jak funguje rozhraní mezi jazykem uclang a jazykem python. Objekty jazyka python jsou reprezentovány objekty třídy PyObject. Při volání metody, která jako parametr očekává PyObject jsou parametry, které nejsou tohoto typu na tento typ automaticky konvertovány. Hodnoty je možné mezi jazykem python a jazykem uclang převádět následujícím způsobem:

    // - uclang to python value -
    py_obj = new PyObject(ucl_obj);
    
    // - python to uclang value -
    ucl_obj = py_obj.value();

    Výpis všech vlastností (attributes) modulu demo.

    // - module demo properties -
    ("demo properties: %s\n" % demo.dir().value().to_string()).print();

    Odpovídající výstup programu:

    demo properties: [Person,__builtins__,__doc__,__file__,__name__,__package__,json,person_dict,person_list,persons]

    Kde demo.dir() je volání python metody dir nad modulem demo, které vrátí python objekt popisující pole. Pole je poté pomocí metody value převedeno na pole jazyka uclang a následně je z něj pomocí metody to_string vytvořen řetězec, který je vytištěn. Z výše uvedeného vyplývá, že je možný i alternativní zápis, který provádí převod pole na řetězec prostřednictvím jazyka python.

    // - module demo properties -
    ("demo properties: %s\n" % demo.dir().__str__().value()).print();

    Odpovídající výstup programu:

    demo properties: ['Person', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'json', 'person_dict', 'person_list', 'persons']

    Následuje demonstrace výběru objektu ze slovníku jazyka python.

    // - retrieve person from dictionary -
    avone = demo.persons["avone"];
    ("person: %s\n" % person_info(avone)).print();
    ("persons: %s\n" % demo.person_list().value().to_string()).print();

    Odpovídající výstup programu:

    person: Avone Barksdale
    persons: [Avone Barksdale,Omar Little]

    Vytvoření objektu třídy nadefinované v modulu demo a jeho vložení do slovníku jazyka python.

    // - add person to dictionary -
    frank = demo.Person("Frank","Sobotka");
    demo.persons["frank"] = frank;
    ("person: %s\n" % person_info(frank)).print();
    ("persons: %s\n" % demo.person_list().value().to_string()).print();

    Odpovídající výstup programu:

    person: Frank Sobotka
    persons: [Frank Sobotka,Avone Barksdale,Omar Little]

    Vytvoření JSON řetězce ze slovníku jazyka python prostřednictvím jazyka python a následně prostřednictvím jazyka uclang.

    // - create persons JSON in python -
    python_json = demo.json(json,demo.person_dict());
    ("python_json: %s\n" % python_json.value()).print();
    
    // - create persons JSON in uclang -
    ucl_json = Json.create(demo.person_dict().value());
    ("ucl_json:    %s\n" % ucl_json).print();

    Odpovídající výstup programu:

    python_json: {"frank":{"surname":"Sobotka","name":"Frank"},"avone":{"surname":"Barksdale","name":"Avone"},"omar":{"surname":"Little","name":"Omar"}}
    ucl_json:    {"omar":{"name":"Omar","surname":"Little"},"avone":{"name":"Avone","surname":"Barksdale"},"frank":{"name":"Frank","surname":"Sobotka"}}

    Implementace modulu python

    Zdrojové soubory modulu python_uclm, které mohou sloužit jako inspirace pro integraci pythonu do libovolné aplikace je možné nalézt zde. Rozhraní jazyka uclang k objektům jazyka python je možné rozpoznat v souboru python_module.h. Funkce provádějící konverzi mezi hodnotami jazyka uclang a hodnotami jazyka python jsou implementovaný v souboru ucl_python.cc.

    Integrace jazyka LUA

    Programovací jazyk LUA vznikl sloučením dvou nástrojů usnadňujících zápis konfigurace a popis vstupních dat programu, a díky své jednoduchosti a síle se stal jedním z nejpoužívanějších parametrizačních skriptovacích jazyků. Pro jazyk LUA vzniklo množství modulů usnadňujících práci s různými datovými typy, knihovnami apod. Protože byl tento jazyk vytvořen jako jednoduchý nástroj pro konfiguraci a skriptování složitějších aplikací je celý koncept tomuto zamýšlenému použití jazyka podřízen, a proto bylo snadné vytvořit modul zprostředkující skriptu zapsanému v jazyce uclang přístup k prvkům jazyka LUA.

    Příklad použití jazyka LUA

    Využití jazyka LUA a jeho interpretu budu demonstrovat na níže uvedeném skriptu zapsaném v jazyce uclang. Jednotlivé části uvedeného skriptu jsou podrobně popsány dále v textu.

    import containers;
    import lua;
    import json;
    
    class Main
    {
      // - lua source script -
      script_src = ("
    Person = {}
    Person.__index = Person
    
    function Person.create(a_name,a_surname)
      local person = {}
      setmetatable(person,Person)
      person.name = a_name
      person.surname = a_surname
      return person
    end
    
    persons = 
    {
      omar = Person.create('Omar','Little'),
      avone = Person.create('Avone','Barksdale')
    }
    
    function person_list()
      local result = {}
    
      for id, person in pairs(persons) do
        table.insert(result,person.name..' '..person.surname)
      end
    
      return result;
    end
    ");
    
      // - print information about person -
      public person_info(a_person)
      {
        return "%s %s" % [
          a_person.name.to_string(),
          a_person.surname.to_string()];
      }
    
      public Main()
      {
        // - create new lua state -
        L = new LuaState();
    
        // - run lua code -
        L.do_string(script_src);
    
        // - retrieve global table -
        _G = L.get_global();
    
        // - export global symbols from lua library -
        _G.package.loadlib("liblua5.2.so","*");
    
        // - load json module -
        json = _G.require("json");
    
        // - list global properties -
        ("global properties: %s\n" % _G.keys().value().to_string()).print();
    
        // - retrieve person from table -
        avone = _G.persons.avone;
        ("person: %s\n" % person_info(avone)).print();
        ("persons: %s\n" % _G.person_list().value().to_string()).print();
    
        // - add person to table -
        frank = _G.Person.create("Frank","Sobotka");
        _G.persons.frank = frank;
        ("person: %s\n" % person_info(frank)).print();
        ("persons: %s\n" % _G.person_list().value().to_string()).print();
    
        // - create persons JSON in lua -
        lua_json = json.encode.encode(_G.persons);
        ("lua_json: %s\n" % lua_json.value()).print();
    
        // - create persons JSON in uclang -
        ucl_json = Json.create(_G.persons.value());
        ("ucl_json: %s\n" % ucl_json).print();
      }
    
      static public main(argv)
      {
        new Main();
      }
    }

    Popis skriptu používajícího jazyk LUA

    Prvním krokem při použití jazyka LUA je import modulů, kde moduly containers a lua jsou stěžejní, a bez těchto není možné použít prvky jazyka LUA. Modul containers obsahuje třídu Dict nutnou pro popis dat, obsažených v hodnotách (values) jazyka LUA. Modul lua, který obsahuje uvedenou závislost na modulu containers, importuje všechny třídy, které umožňují využít skriptovací jazyk LUA v jazyce uclang.

    import containers;
    import lua;
    import json;

    Následuje základní kostra programu, která je shodná s kostrou předvedenou v předcházejícím příkladě (proto ji zde neuvádím).

    Stejně jako v předcházejícím případě inicializace interpretu jazyka LUA a načtení dynamických knihoven proběhne již v rámci importování modulu lua. V následujícím kroku je vytvořen objekt třídy LuaState reprezentující stav jednoho interpretu jazyka LUA. Tento interpret se spustí nad řetězcem obsahujícím kód zapsaný v jazyce LUA.

    // - create new lua state -
    L = new LuaState();
    
    // - run lua code -
    L.do_string(script_src);

    Z objektu třídy LuaState se získá reference na globální prostředí reprezentované objektem třídy LuaValue.

    // - retrieve global table -
    _G = L.get_global();

    Aby bylo možné v jazyce LUA importovat moduly prostřednictvím funkce require, je nutné, aby pro potřeby dynamických knihoven reprezentujících tyto moduly byly přístupné C symboly funkcí umožňující práci s LUA stavem a jeho zásobníkem. Moduly nevyžadující přístup k těmto prostředkům mohou být importovány i bez exportovaných C symbolů.

    // - export global symbols from lua library -
    _G.package.loadlib("liblua5.2.so","*");
    
    // - load json module -
    json = _G.require("json");

    Následuje výpis všech vlastností (attributes) globální tabulky daného LUA stavu.

    // - list global properties -
    ("global properties: %s\n" % _G.keys().value().to_string()).print();

    Odpovídající výstup programu:

    global properties: [load,debug,xpcall,string,rawlen,table,tonumber,type,dofile,collectgarbage,ipairs,setmetatable,rawequal,getmetatable,loadstring,_VERSION,_G,Person,rawget,next,persons,person_list,assert,json,math,select,print,coroutine,io,module,bit32,require,error,rawset,pairs,loadfile,unpack,tostring,pcall,os,package]

    Kde _G.keys() je volání LUA metody keys nad LUA hodnotou _G, které vrátí pole klíčů LUA tabulky ve formě objektu třídy LuaValue. Toto pole je pomocí metody value převedeno do pole jazyka uclang, které je následně převedeno na řetězec a vytištěno.

    Princip komunikace jazyka uclang s jazykem LUA je obdobný jako v předcházejícím případě. Objekty jazyka LUA jsou reprezentovány objekty třídy LuaValue. Při volání metody, která jako parametr očekává objekt třídy LuaValue, jsou parametry, které nejsou tohoto typu na tento typ automaticky konvertovány. Hodnoty je možné mezi jazykem LUA a jazykem uclang převádět následujícím způsobem:

    // - uclang to LUA value -
    lua_val = L.new_value(ucl_obj);
    
    // - LUA to uclang value -
    ucl_obj = lua_val.value();

    Následuje demonstrace výběru hodnoty z tabulky jazyka LUA.

    // - retrieve person from table -
    avone = _G.persons.avone;
    ("person: %s\n" % person_info(avone)).print();
    ("persons: %s\n" % _G.person_list().value().to_string()).print();

    Odpovídající výstup programu:

    person: Avone Barksdale
    persons: [Avone Barksdale,Omar Little]

    Vytvoření objektu třídy popsané v LUA skriptu, který byl spuštěn v jednom z předcházejících kroků a jeho vložení do LUA tabulky.

    // - add person to table -
    frank = _G.Person.create("Frank","Sobotka");
    _G.persons.frank = frank;
    ("person: %s\n" % person_info(frank)).print();
    ("persons: %s\n" % _G.person_list().value().to_string()).print();

    Odpovídající výstup programu:

    person: Frank Sobotka
    persons: [Frank Sobotka,Avone Barksdale,Omar Little]

    Vytvoření JSON řetězce z tabulky jazyka LUA prostřednictvím jazyka LUA a následně prostřednictvím jazyka uclang.

    // - create persons JSON in lua -
    lua_json = json.encode.encode(_G.persons);
    ("lua_json: %s\n" % lua_json.value()).print();
    
    // - create persons JSON in uclang -
    ucl_json = Json.create(_G.persons.value());
    ("ucl_json: %s\n" % ucl_json).print();

    Odpovídající výstup programu:

    lua_json: {"frank":{"surname":"Sobotka","name":"Frank"},"avone":{"surname":"Barksdale","name":"Avone"},"omar":{"surname":"Little","name":"Omar"}}
    ucl_json: {"omar":{"name":"Omar","surname":"Little"},"avone":{"name":"Avone","surname":"Barksdale"},"frank":{"name":"Frank","surname":"Sobotka"}}

    Implementace modulu lua

    Zdrojové soubory modulu lua_uclm, které mohou sloužit jako inspirace pro integraci jazyka LUA do libovolné aplikace je možné nalézt zde. Rozhraní jazyka uclang k objektům jazyka LUA je možné rozpoznat v souboru lua_module.h. Funkce provádějící konverzi mezi hodnotami jazyka uclang a hodnotami jazyka LUA jsou implementovaný v souboru ucl_lua.cc.

    Integrace JavaScript engine V8

    JavaScript je dnes velice rozšířený jazyk, který se již dávno nepoužívá pouze pro skriptování dynamického webu. Velice často se dnes setkáme s aplikacemi, které využívají JavaScript jako rozšiřující konfigurační nástroj. JavaScript engine V8 je vytvořen tak, aby usnadnil svou integraci do C++ aplikace. Implementace modulu zprostředkujícího přístup k prvkům JavaScript engine V8 byla tímto značně usnadněna.

    Příklad použití JavaScript engine V8

    Využití JavaScript engine V8 budu demonstrovat na níže uvedeném skriptu zapsaném v jazyce uclang. Jednotlivé části uvedeného skriptu jsou podrobně popsány dále v textu.

    import containers;
    import v8;
    import json;
    
    class Main
    {
      // - v8 source script -
      script_src = ("
    Person = function(a_name,a_surname)
    {
      this.name    = a_name;
      this.surname = a_surname;
    }
    
    var persons = 
    {
      omar  : new Person('Omar','Little'),
      avone : new Person('Avone','Barksdale')
    }
    
    var person_list = function()
    {
      var result = [];
    
      for (id in persons)
      {
        person = persons[id];
        result.push(person.name + ' ' + person.surname);
      }
    
      return result;
    }
    ");
    
      // - print information about person -
      public person_info(a_person)
      {
        return "%s %s" % [
          a_person.name.to_string(),
          a_person.surname.to_string()];
      }
    
      public Main()
      {
        // - create new context -
        ctx = new V8Context();
        ctx.enter();
    
        // - compile and run script -
        script = V8Script.compile(script_src);
        script.run();
    
        // - retrieve global object -
        go = ctx.global_object();
    
        // - list global properties -
        ("global properties: %s\n" % go.prop_names().value().to_string()).print();
    
        // - retrieve person from object -
        avone = go.persons.avone;
        ("person: %s\n" % person_info(avone)).print();
        ("persons: %s\n" % go.person_list().value().to_string()).print();
    
        // - add person to object -
        frank = go.Person.construct(["Frank","Sobotka"]);
        go.persons.frank = frank;
        ("person: %s\n" % person_info(frank)).print();
        ("persons: %s\n" % go.person_list().value().to_string()).print();
    
        // - create persons JSON in javascript -
        v8_json = go.JSON.stringify(go.persons);
        ("v8_json:  %s\n" % v8_json.value()).print();
    
        // - create persons JSON in uclang -
        ucl_json = Json.create(go.persons.value());
        ("ucl_json: %s\n" % ucl_json).print();
      }
    
      static public main(argv)
      {
        new Main();
      }
    }

    Popis skriptu používajícího JavaScript engine V8

    Prvním krokem je import modulů, kde moduly containers a v8 jsou stěžejní, a bez těchto není možné použít prvky JavaScript engine V8. Modul containers obsahuje třídu Dict nutnou pro popis dat, obsažených v JavaScript objektech. Modul v8, který obsahuje uvedenou závislost na modulu containers, importuje všechny třídy, které umožňují využít JavaScript engine V8 v jazyce uclang.

    import containers;
    import v8;
    import json;

    Následuje základní kostra programu, která je shodná s kostrou uvedenou v příkladě popisujícího integraci jazyka python (proto ji zde neuvádím).

    Stejně jako v případě jazyka python proběhne inicializace a načtení potřebných dynamických knihoven už v rámci importování modulu v8. JavaScript engine V8 funguje na principu kontextů, který budeme respektovat. Následuje vytvoření nového kontextu JavaScript engine V8 a jeho nastavení jako aktuálního pracovního kontextu.

    // - create new context -
    ctx = new V8Context();
    ctx.enter();

    V rámci tohoto kontextu je zkompilován a spuštěn skript v jazyce JavaScript, který je uveden na začátku popisovaného skriptu v jazyce uclang. Tento skript v aktivním kontextu nadefinuje demonstrační třídy, funkce a objekty.

    // - compile and run script -
    script = V8Script.compile(script_src);
    script.run();

    Z kontextu je získán jeho globální objekt. Získání globální objektu nezávisí na spouštění skriptu, a tyto akce jsou na sobě nezávislé.

    // - retrieve global object -
    go = ctx.global_object();

    Výpis všech vlastností (properties) globálního objektu.

    // - list global properties -
    ("global properties: %s\n" % go.prop_names().value().to_string()).print();

    Odpovídající výstup programu:

    global properties: [persons,person_list,Person]

    Na rozdíl od předcházejících příkladů, zde není za účelem získání pole identifikujícího vlastnosti globálního objektu použita JavaScript metoda. Místo toho je použita metoda jazyka uclang prop_names, která v rámci své implementace volá C++ metodu GetPropertyNames. Volání metody prop_names vrátí pole reprezentované JavaScript objektem, které je prostřednictvím metod value a to_string převedeno na řetězec a vytištěno na výstup.

    Princip komunikace jazyka uclang s JavaScript engine V8 je obdobný jako v předcházejícím případě. Objekty JavaScript engine V8 jsou reprezentovány objekty třídy V8Object. Při volání metody, která jako parametr očekává objekt třídy V8Object, jsou parametry, které nejsou tohoto typu na tento typ automaticky konvertovány. Hodnoty objektů je možné mezi jazykem uclang a JavaScript engine V8 převádět následujícím způsobem:

    // - uclang to V8 value -
    v8_obj = new V8Object(ucl_obj);
    
    // - V8 to uclang value -
    ucl_obj = v8_obj.value();

    Následuje demonstrace výběru prvku z JavaScript objektu.

    // - retrieve person from object -
    avone = go.persons.avone;
    ("person: %s\n" % person_info(avone)).print();
    ("persons: %s\n" % go.person_list().value().to_string()).print();

    Odpovídající výstup programu:

    person: Avone Barksdale
    persons: [Omar Little,Avone Barksdale]

    Vytvoření objektu třídy nadefinované v JavaScript kódu, který byl v kontextu spuštěn v jednom z předcházejících kroků. Vložení nově vytvořeného objektu do existujícího JavaScript objektu.

    // - add person to object -
    frank = go.Person.construct(["Frank","Sobotka"]);
    go.persons.frank = frank;
    ("person: %s\n" % person_info(frank)).print();
    ("persons: %s\n" % go.person_list().value().to_string()).print();

    Odpovídající výstup programu:

    person: Frank Sobotka
    persons: [Omar Little,Avone Barksdale,Frank Sobotka]

    Vytvoření JSON řetězce z JavaScript objektu prostřednictvím JavaScript engine V8 a následně prostřednictvím jazyka uclang.

    // - create persons JSON in javascript -
    v8_json = go.JSON.stringify(go.persons);
    ("v8_json:  %s\n" % v8_json.value()).print();
    
    // - create persons JSON in uclang -
    ucl_json = Json.create(go.persons.value());
    ("ucl_json: %s\n" % ucl_json).print();

    Odpovídající výstup programu:

    v8_json:  {"omar":{"name":"Omar","surname":"Little"},"avone":{"name":"Avone","surname":"Barksdale"},"frank":{"name":"Frank","surname":"Sobotka"}}
    ucl_json: {"omar":{"name":"Omar","surname":"Little"},"avone":{"name":"Avone","surname":"Barksdale"},"frank":{"name":"Frank","surname":"Sobotka"}}

    Implementace modulu v8

    Zdrojové soubory modulu v8_uclm, které mohou sloužit jako inspirace pro integraci JavaScript engine do libovolné aplikace je možné nalézt zde. Rozhraní jazyka uclang k objektům JavaScript engine V8 je možné rozpoznat v souboru v8_module.h. Funkce provádějící konverzi mezi hodnotami jazyka uclang a hodnotami JavaScript engine V8 jsou implementovaný v souboru ucl_v8.cc.

           

    Hodnocení: 100 %

            špatnédobré        

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    27.6.2015 21:27 RM
    Rozbalit Rozbalit vše Re: Uclang - integrace skriptovacích jazyků
    Pěkné, díky!
    Bedňa avatar 27.6.2015 22:34 Bedňa | skóre: 34 | blog: Žumpa | Horňany
    Rozbalit Rozbalit vše Re: Uclang - integrace skriptovacích jazyků
    Jak tak na to pozerám vidím script = V8Script.compile(script_src); a hovorím si kurwa VBsvript :-)

    Inak dobré, až to má človek chuť vyskúšať či nás neťaháš za nos :-)
    KERNEL ULTRAS video channel >>>
    28.6.2015 08:24 zuzanak | skóre: 10 | blog: zuzanak
    Rozbalit Rozbalit vše Re: Uclang - integrace skriptovacích jazyků

    No jestli tě ještě chuť nepřešla, tak zkoušej. Vytvořil jsem skript try_uclang.sh, který by to mohl celé provést sám.

    Kompilace by měla automaticky detekovat moduly, které je možné zkompilovat (na základě přítomnosti knihoven v systému), ale není to dokonalé (rozdílné verze knihoven apod.). Pokud to některý modul nezkompiluje, tak jen k jeho jménu v souboru uclang/uclang_build/mf_mods.py napiš False a spusť výše uvedený skript (try_uclang.sh) znovu. Ostatně takto můžeš pro kompilaci vybrat jen moduly, které tě zajímají (python, lua, v8, json, base).

    Bedňa avatar 28.6.2015 19:48 Bedňa | skóre: 34 | blog: Žumpa | Horňany
    Rozbalit Rozbalit vše Re: Uclang - integrace skriptovacích jazyků
    Toto tam máš bug s premennými:
    /home/mario/tmp/uclang/uclang/uclang_build/proc_files/python_uclm/p.ucl_python.cc: In static member function ‘static location_s* python_c::py_object_value(interpreter_thread_s&, PyObject*, uli)’: /home/mario/tmp/uclang/uclang/uclang_build/proc_files/python_uclm/p.ucl_python.cc:16084:53: error: cannot convert ‘int*’ to ‘Py_ssize_t* {aka long int*}’ for argument ‘3’ to ‘int PyString_AsStringAndSize(PyObject*, char**, Py_ssize_t*)’ PyString_AsStringAndSize(pyo_obj,&buffer,&length);
    KERNEL ULTRAS video channel >>>
    29.6.2015 05:42 zuzanak | skóre: 10 | blog: zuzanak
    Rozbalit Rozbalit vše Re: Uclang - integrace skriptovacích jazyků

    No to se podívejme, a přitom při volání jiných python funkcí Py_ssize_t používám. Díky za report, bug jsem opravil. Bude potřeba provést git pull v adresáři uclang, nebo tento adresář smazat, aby si jej skript try_uclang.sh znovu naklonoval. Otestoval jsem opravu na 64bit systému a vypadá to, že už to funguje.

    Bedňa avatar 1.7.2015 16:18 Bedňa | skóre: 34 | blog: Žumpa | Horňany
    Rozbalit Rozbalit vše Re: Uclang - integrace skriptovacích jazyků
    Funguje to na jedničku, fandím ti a som rád, že sa tu občas ukáže aj hacker.
    KERNEL ULTRAS video channel >>>

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.