Порт LUA (5.2.0)

...
  • Значит, что у меня кривые руки. Подключаю kolibri.h из shell, получаю падение приложения при вызове элементарной kol_board_puts.
  • Sorcerer
    Хочешь console.obj подключить ?
    >>kol_board_puts А чем printf() не устраивает ? Тоже на доску пишет.
  • Не только console.obj. Там же куча всяких полезных функций, которые неплохо бы вызывать из lua например вот так: kolibri.define_window.
    А printf всем устраивает, но kol_board_puts - самая наглядно показывающая что все работает функция.
    upd: В который раз убеждаюсь, что нужно больше кушать и спать. Передавать указатель на стек параметров lua вместо указателя на строку было не лучшей идеей. Надеюсь, к выходным сделаю обертки для некоторого минимума оберток функций Колибри. Было бы здорово, если бы получилось сделать загрузку библиотек. Тогда можно было бы подключить libPNG, boxlib и всё такое.
  • :roll: Что-то я туплю.

    1) Код в kolibri.c:

    Code: Select all

    unsigned kol_event_wait(){asm ("int $0x40"::"a"(10));}
    
    Код в моей библиотеке:

    Code: Select all

    static int luaB__waitevent (lua_State *L){
    lua_pushnumber(L, kol_event_wait());
    return 1;}
    
    Замечательно работает.

    2) Код в kolibri.c:

    Code: Select all

    unsigned kol_key_get(){asm ("int $0x40"::"a"(2));}
    
    Код в моей библиотеке:

    Code: Select all

    static int luaB__getkey (lua_State *L){
    lua_pushnumber(L, kol_key_get());
    return 1;}
    
    Возвращает число в 256 раз большее (т.е. сдвиг на байт). Аналогичная история с kol_btn_get(). Причем число в 256 раз большее возвращается именно функцией, код Lua отношения к таким чудесам не имеет.

    3) Код в kolibri.c:

    Code: Select all

    void kol_paint_string(unsigned x, unsigned y,  unsigned c, char *s)
    {asm ("int $0x40"::"a"(4), "b"(x*65536+y), "c"(c), "d"(s));}
    
    Код в моей библиотеке:

    Code: Select all

    static int luaB__textout (lua_State *L){
      int n = lua_gettop(L);  /* number of arguments */
      int i, r[n];
      const  char * s;
      lua_getglobal(L, "tostring");
      for (i=1; i<=n; i++) {
        lua_pushvalue(L, -1);  /* function to be called */
        lua_pushvalue(L, i);   /* value to print */
        lua_call(L, 1, 1);
        s = lua_tostring(L, -1);
        r[i]=atoi(s);
        lua_pop(L, 1);  /* pop result */}
      printf ("%s \n", s);
      kol_paint_string (r[1],r[2],r[3],s);
      return 0;}
    
    На доску отладки выводятся правильные значения. То есть я даю команду textout(3,13,0, "LuaCalc") и получаю на доске LuaCalc, и больше ничего лишнего. Однако в окне наблюдаю следующее:
    Снимок.png
    Снимок.png (2.52 KiB)
    Viewed 8746 times
    Дело в несоответствии типов (unsigned/int и static char */char *)? Если да, то как бороться?
  • Sorcerer

    kol_key_get() возвращает код формате ф.2 - регистре ah.
    kol_paint_string (r[1],r[2],r[3],s); - проверь r[3]

    textout(3,13,0, "LuaCalc") - ага, у тебя в вызове ф.4 выводится esi символов.
    ecx = 0xX0RRGGBB, где
    RR, GG, BB задают цвет текста
    X=ABnn (биты):
    nn задает используемый шрифт: 0=системный моноширинный, 1=системный шрифт переменной ширины
    A=0 - выводить esi символов, A=1 - выводить ASCIIZ-строку
    B=1 - закрашивать фон цветом edi
  • Ок,понятно. Там, где значение больше в 256 раз, можно просто делить?
  • Там надо правильно разбирать возвращаемое значение или в самом LUA, или адаптировать функцию

    Code: Select all

    если буфер пуст, возвращается eax=1 
    если буфер непуст, то возвращается al=0, ah=код нажатой клавиши, старшее слово регистра eax обнулено 
    если есть "горячая клавиша", то возвращается al=2, ah=сканкод нажатой клавиши (0 для управляющих клавиш), старшее слово регистра eax содержит состояние управляющих клавиш в момент нажатия горячей клавиши 
    
  • Понятно. Тот, кто не читает мануалы (то есть я) - ССЗБ.

    Code: Select all

    * старшие 24 бита eax содержат идентификатор кнопки
          (в частности, в ah оказывается младший байт идентификатора;
          если все кнопки имеют идентификатор, меньший 256,
          то для различения достаточно ah)
        * al = 0 - кнопка была нажата левой кнопкой мыши
        * al = бит, соответствующий нажавшей кнопке мыши, если не левой
    
    Как будет выглядеть тогда eax побитово, если левой кнопкой мыши нажата кнопка с идентификатором 1?
    Вот так: 00000000000000000000000100000000
    То есть нужно брать первые 24 бита, и отбрасывать свойство "левая/правая кнопка была нажата". Или же менять функцию, чтобы она возвращала два параметра как таблицу.
  • Не первые, а старшие.
    mouse_button = button_id &0xFF;
    button_id = button_id >>8;
  • Пока что занимаюсь перетягиванием функций Колибри в LUA, но на самом деле даже версия, собранная Serge, вполне работоспособна. А пока что покажу пару вкусностей, которые могут быть полезны (для второй из них можно легко написать графический интерфейс, как только я допилю вывод текста и обработку клавиатуры, а осталось, я верю, совсем немного).

    1) Парсер XML. Я использовал его, чтобы распарсить SVG-файл, и это удалось мне без проблем. Код взят с luaforge

    Code: Select all

    function parseargs(s)
    local arg = {}
    string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
    arg[w] = a
    end
    return arg
    end
    
    function collect(s)
    local stack = {}
    local top = {}
    table.insert(stack, top)
    local ni,c,label,xarg, empty
    local i, j = 1, 1
    while true do
    ni,j,c,label,xarg, empty = string.find(s, "<(%/?)(%w+)(.-)(%/?)>", i)
    if not ni then break end
    local text = string.sub(s, i, ni-1)
    if not string.find(text, "^%s*$") then
    table.insert(top, text)
    end
    if empty == "/" then -- empty element tag
    table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
    elseif c == "" then -- start tag
    top = {label=label, xarg=parseargs(xarg)}
    table.insert(stack, top) -- new level
    else -- end tag
    local toclose = table.remove(stack) -- remove top
    top = stack[#stack]
    if #stack < 1 then
    error("nothing to close with "..label)
    end
    if toclose.label ~= label then
    error("trying to close "..toclose.label.." with "..label)
    end
    table.insert(top, toclose)
    end
    i = j+1
    end
    local text = string.sub(s, i)
    if not string.find(text, "^%s*$") then
    table.insert(stack[#stack], text)
    end
    if #stack > 1 then
    error("unclosed "..stack[stack.n].label)
    end
    return stack[1]
    end
    
    --Открываем файл picture.svg
    fi=io.open("picture.svg","r")
    --Читаем из него всё
    all=fi:read("*a")
    --Можно закрыть, но это будет сделано автоматически при завершении программы
    
    --Даем команду распарсить
    var=collect(all)
    
    for key, value in pairs(var) do --переберем все поля таблицы первого уровня вложенности
    	print ("\n")    
    	print(key, value)
    end
    
    Результат работы программы - таблица var, содержащая в себе много-много вложенных таблиц с полями XML.

    2) HTML-парсер. Конвертирует HTML-страницы в текстовые файлы, все ссылки записываются как сноски.

    Code: Select all

    --[[
    HTML Parser in Lua
    Inspired by this C# code:
    http://www.codeproject.com/useritems/HTML_to_Plain_Text.asp
    
    It does exactly the same as described there.
    Only converts offline files.
    
    Distributed under a modified BSD license, see at the end of the file]]
    
    -- What is the desired newline?
    nl = "\n"
    
    filename = "Kolibri.html"
    
    function HTML_ToText (file)
      -- Declare variables, load the file. Make tags lowercase.
      local text
      local f=io.open (file)
      if f then
        if f:seek("end") <= 0 then return end
        f:seek("set")
        text = f:read ("*a")
        f:close()
      end
      text = string.gsub (text,"(<([^>]-)>)",function (str) return str:lower() end)
      --[[
      First we kill the developer formatting (tabs, CR, LF)
      and produce a long string with no newlines and tabs.
      We also kill repeated spaces as browsers ignore them anyway.
      ]]
      local devkill=
        {
          ["("..string.char(10)..")"] = " ",
          ["("..string.char(13)..")"] = " ",
          ["("..string.char(15)..")"] = "",
          ["(%s%s+)"]=" ",
        }
      for pat, res in pairs (devkill) do
        text = string.gsub (text, pat, res)
      end
      -- Then we remove the header. We do this by stripping it first.
      text = string.gsub (text, "(<%s*head[^>]*>)", "<head>")
      text = string.gsub (text, "(<%s*%/%s*head%s*>)", "</head>")
      text = string.gsub (text, "(<head>,*<%/head>)", "")
      -- Kill all scripts. First we nuke their attribs.
      text = string.gsub (text, "(<%s*script[^>]*>)", "<script>")
      text = string.gsub (text, "(<%s*%/%s*script%s*>)", "</script>")
      text = string.gsub (text, "(<script>,*<%/script>)", "")
      -- Ok, same for styles.
      text = string.gsub (text, "(<%s*style[^>]*>)", "<style>")
      text = string.gsub (text, "(<%s*%/%s*style%s*>)", "</style>")
      text = string.gsub (text, "(<style>.*<%/style>)", "")
     
      -- Replace <td> and <th> with tabulators.
      text = string.gsub (text, "(<%s*td[^>]*>)","\t")
      text = string.gsub (text, "(<%s*th[^>]*>)","\t")
     
      -- Replace <br> with linebreaks.
      text = string.gsub (text, "(<%s*br%s*%/%s*>)",nl)
     
      -- Replace <li> with an asterisk surrounded by spaces.
      -- Replace </li> with a newline.
      text = string.gsub (text, "(<%s*li%s*%s*>)"," *  ")
      text = string.gsub (text, "(<%s*/%s*li%s*%s*>)",nl)
     
      -- <p>, <div>, <tr>, <ul> will be replaced to a double newline.
      text = string.gsub (text, "(<%s*div[^>]*>)", nl..nl)
      text = string.gsub (text, "(<%s*p[^>]*>)", nl..nl)
      text = string.gsub (text, "(<%s*tr[^>]*>)", nl..nl)
      text = string.gsub (text, "(<%s*%/*%s*ul[^>]*>)", nl..nl)
       
      -- Some petting with the <a> tags. :-P
      local addresses,c = {},0
      text=string.gsub(text,"<%s*a.-href=[\'\"](%S+)[\'\"][^>]*>(.-)<%s*%/*%s*a[^>]->", -- gets URL from a tag, and the enclosed name
      function (url,name)
        c = c + 1
        name = string.gsub (name, "<([^>]-)>","") -- strip name from tags (e. g. images as links)
       
        -- We only consider the URL valid if the name contains alphanumeric characters.
        if name:find("%w") then print(url, name, c) table.insert (addresses, {url, name}) return name.."["..#addresses.."]" else return "" end   
      end)
    
      -- Nuke all other tags now.
      text = string.gsub (text, "(%b<>)","")
     
      -- Replace entities to their correspondant stuff where applicable.
      -- C# is owned badly here by using a table. :-P
      -- A metatable secures entities, so you can add them natively as keys.
      -- Enclosing brackets also get added automatically (capture!)
      local entities = {}
      setmetatable (entities,
      {
        __newindex = function (tbl, key, value)
          key = string.gsub (key, "(%#)" , "%%#")
          key = string.gsub (key, "(%&)" , "%%&")
          key = string.gsub (key, "(%;)" , "%%;")
          key = string.gsub (key, "(.+)" , "("..key..")")
          rawset (tbl, key, value)
        end
      })
      entities =
      {
        [" "] = " ",
        ["•"] = " *  ",
        ["‹"] = "<",
        ["›"] = ">",
        ["™"] = "(tm)",
        ["⁄"] = "/",
        ["<"] = "<",
        [">"] = ">",
        ["©"] = "(c)",
        ["®"] = "(r)",
        -- Then kill all others.
        -- You can customize this table if you would like to,
        -- I just got bored of copypasting. :-)
        -- http://hotwired.lycos.com/webmonkey/reference/special_characters/
        ["%&.+%;"] = "",
      }
      for entity, repl in pairs (entities) do
        text = string.gsub (text, entity, repl)
      end
    --   text = text..nl..nl..("-"):rep(27)..nl..nl
    --   
    --   for k,v in ipairs (addresses) do
    --     text = text.."["..k.."] "..v[1]..nl
    --   end
      if #addresses > 0 then
        text=text..nl:rep(2)..("-"):rep(2)..nl
        for key, tbl in ipairs(addresses) do
          text = text..nl.."["..key.."]"..tbl[1]
        end
      end
     
      return text
     
    end
    
    local f=io.open(filename..".txt", "w")
    f:write(HTML_ToText (filename))
    f:close()
    
    --[[
    Copyright (c) 2007, bastya_elvtars
    
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without modification,
    are permitted provided that the following conditions are met:
    
        * Redistributions of source code must retain the above copyright notice, this
          list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above copyright notice,
          this list of conditions and the following disclaimer in the documentation
          and/or other materials provided with the distribution.
        * Neither the name of the author nor the names of contributors may be used
          to endorse or promote products derived from this code without specific
          prior written permission.
    
    THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    CODE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ]]
    
    Сайт kolibrios.org выглядит так:

    Code: Select all

     KolibriOS 0.7.7.0       
    
     	 KolibriOS 0.7.7.0   
    
     	 previous releases[1]   
    
     	 Kolibri is a small x86 assembler hobby operating system. It forked off MenuetOS[2] in 2004 and has mostly been developed by ex-USSR community since. API and ABI is being enreached with developer-friendly features. User interface is not that good yet but we are trying to improve it as well. Your feedback is very appreciated, although help would always be much more valuable.   
    
     	      
    
     	 Current 0.7.7.0 release introduces several kernel, applications and libraries updates. We thank everyone participated and tried making this release a better one. Huge networking code changes, ATI video driver, HTMLV and DOWNLOADER integration for convenient web browsing and many other improvements - that is what we would like to get you excited today. Full list of changes could be found at a special wiki page[3].   
    
     	   	 Floppy image to be used for various virtual machines, writing on diskette or putting to hard disk to boot from.  	     
    
     	   	 Compact disk (LiveCD) image to be used for various virtual machines or burning to CDs to boot from.  	     
    
     	   	 Kernel, applications and libraries source code at the time of release.  	    
    
     	   	 Software development kit (SDK) for people interested in developing applications for Kolibri.  	    
    
     	 For feedback and support, please visit our bug-tracker[4], forums[5] or IRC channel[6]. You can also drop us an e-mail[7].   
    
     	  2004-2009 KolibriOS team    
    
    --
    
    [1]http://kolibrios.org/releases.html
    [2]http://menuetos.net/
    [3]http://wiki.kolibrios.org/wiki/changes_in_0770
    [4]http://bugs.kolibrios.org/
    [5]http://board.kolibrios.org/
    [6]irc://irc.freenode.net/kolibrios
    
    
    Как запустить эти программы в Колибри:
    Spoiler:1. Код каждой из программ нужно сохранить в отдельный файл с любым именем. Неплохой идеей будет сделать у этого файла расширение lua, но это не обязательно.
    2. Затем нужно взять файл lua.kex, выложенный в этой теме на прошлой странице (он в архиве lua52.7z).
    3. Для работы программ нужны xml и html файлы. В качестве xml подойдет, например, какой-нибудь svg рисунок. В качестве htm - любая веб-страница htm.
    4. Сейчас xml-парсер открывает picture.svg, а html-парсер - kolibri.html, но это можно изменить, исправив исходный код.
    5. Нужно поместить файлы на дискету с Колибри, или же упаковать в образ дискеты для загрузки. А можно просто положить эти файлы на жесткий диск, который видится в Колибри - все в одну папку. (Я пользуюсь qemu и образом дискеты,а добавляю файлы в образ командой mcopy)
    6. Теперь нужно загрузиться в Колибри, запустить программу RUN и дать команду:
    /путь/к/папке/в/которой/всё/лежит/lua.kex имя_программы

    Например, если вы сохранили html-парсер в файл html.lua, и положили все файлы на рам-диск, то команда будет такой:
    /rd/1/lua.kex html.lua

    Результат работы HTML-парсера - файл с тем же именем, что и исходная страница, но с расширением txt.
    Результат работы XML-парсера выводится на доску отладки. Если он будет "1 table 2 table 3 table", то это нормально.
  • Маленький вопрос: как правильно использовать for ... do ... end

    Я так понял

    Code: Select all

    i=1
    k=5
    step=1
    
    For i,k,step, do .... end
    Т.е. это будет эквивалентно

    Code: Select all

    for i:=1 to 5 step 1 do ...
  • Синтаксис for выглядит так:
    for i=start,end,step do ... end

    Руководство на русском языке есть на lua.ru, оно подходит практически полностью (только в lua 4 другие команды работы с файлами, а в 5.2 еще нет части нужных функций).

    p.s. неясно, почему не работает require, хотя это может быть вызвано тем, что компилировался ansi-вариант, ОС-независимый, и внешние библиотеки могут отсутствовать как класс.
    Last edited by SoUrcerer on Mon Mar 14, 2011 11:04 am, edited 1 time in total.
  • Свеженькая версия lua 5.2 с поддержкой некоторых функций Колибри. В архиве так же "учебный" калькулятор на lua.
    lua52-lib.7z (92.6 KiB)
    Downloaded 327 times

    Функции Колибри ОС (изменений по сравнению с версией lua4lib мало):
    paintstart() --начать перерисовку
    paintend() --закончить перерисовку
    window(10,10,153,180,65069280) --задать окно
    textout(3,13,0,"LuaCalc") --вывести текст
    makebutton(6,60,20,20,17,13619151) --создать/удалить кнопку
    waitevent() --ждать события
    checkevent() --проверить наличие нового события
    getkey() --получить код нажатой клавиши
    getbutton() --получить код нажатой кнопки
    sysexit() --завершить программу

    Команда print теперь выводит текст на доску отладки.
    Какие еще функции системы нужны /я имею в виду в первую очередь/?
  • Получение текущего времени и даты.
  • Who is online

    Users browsing this forum: No registered users and 6 guests