Реализация оригинального языка Moonscript версии 0.5.0 находится в ветке 0.5.0
Yuescript. Moonscript с исправлениями и новыми функциями находится в основной ветке Yuescript. Ниже приведены изменения для каждой версии Yuescript.
Добавлены сравнения цепочек и синтаксис списков []
, запрещающий пары ключ-значение.
x = 2
res = 1 < x < 3 -- true в Yuescript, как в Python.
print res
list_with_only_one_element = [1,]
list = [
1
2
3
abc: 123 -- здесь будет сообщена ошибка
]
[a = 1, b = 2] = tab_to_be_destructured
Добавлен синтаксис from "module" import ...
.
from "CS" import
System
UnityEngine
from UnityEngine import
Object
GameObject
Transform
MonoBehaviour
Vector3
Quaternion
Добавлен синтаксис import ... from "module"
.
import a, b, c from "module"
Поддержка идентификаторов Unicode.
🌛 = 🏷️: "月之脚本"
print 🌛.🏷️
Реализовано использование ...
для объявления переменных в области видимости с использованием анонимных функций.
ok, ... = fn!
if ok
print select '#', ...
print select 1, ...
Поддерживаются закрытые переменные для Lua версии ниже 5.4.
a = 5
if a in [1, 10] or a in (20, 30) or a in {77, 88} or a not in {100, 200}
print "(1 <= a <= 10) or (20 < a < 30) or (a == 77 or a == 88) or not (a == 100 or a == 200)"
switch a when not in [1, 10]
print "not (1 <= a <= 10)"
if item in list
print "item existed in a list"
Опция -w для инструмента Yuescript для рекурсивного отслеживания изменений файлов под целевым путём и повторной компиляции кодов.
Различные литералы имён метаметодов для разных версий Lua.
Проверки на отсутствие использования оператора break
в области цикла for.
Компиляторная опция для сохранения комментариев перед операторами. Использование инструмента командной строки:
yue -c file.yue
Использование библиотеки Lua:
local yue = require("yue")
print yue.to_lua([[
-- a comment
f = ->
]], {reserve_comment = true})
Функция yue.check()
для получения ошибок компиляции в таблице Lua {{type, msg, line, col}}.
Расширение путей поиска скриптов с помощью yue.options.path
.
Новый синтаксис экспорта модулей для экспорта элементов без создания локальных переменных.
export.<name> = "My module"
export.<call> = (...) -> -- ...
компилируется в:
local _module_0 = setmetatable({ }, { })
getmetatable(_module_0).__name = "My module"
getmetatable(_module_0).__call = function(...) end
return _module_0
Уменьшен максимальный размер стека вызовов парсера.
Рефакторинг некоторых синтаксических правил для ускорения разбора.
Исправлена проблема со значением по умолчанию при деструктурировании метатаблицы.
Исправлена неоднозначная проблема синтаксиса класса при написании табличного блока после объявления класса.
Улучшен синтаксис числовых литералов для поддержки шестнадцатеричных значений точек, положительных десятичных показателей степени и шестнадцатеричных показателей степени. Макросы и нормальные значения. Модуль экспорта макросов теперь позволяет только определение макроса, импорт макроса и расширение макроса на месте для лучшей производительности компилятора.
yue.to_ast
).yue.p yue.to_ast(
"print 123"
2 --[[ast flatten level, can only be 0, 1, 2]]
)
Выводит:
{
[1] = "file"
[2] = {
[1] = "callable"
[2] = "print"
}
[3] = {
[1] = "invoke_args"
[2] = "123"
}
}
macro text = (code) -> {
:code
type: "text"
}
$text[[#!yue -e]]
nil
Компилируется в:
#!yue -e
return nil -- 8
$FILE
, $LINE
для получения имён исходных файлов и номеров строк кода.tb = {}
tb[] = 1
компилируется в:
local tb = { }
tb[#tb + 1] = 1
using
.class A using B
-- Если B является объектом класса Yuescript (у которого есть поле с именем __base),
-- то в класс объекта A будут добавлены только поля, которые не являются метаметодом.
-- Если B — обычная таблица, то все поля будут добавлены в класс объекта A,
-- чтобы можно было изменить поведение метаметода __index класса Yuescript.
try
func 1, 2, 3
catch err
print yue.traceback err
success, result = try func 1, 2, 3
компилируется в:
xpcall(function()
return func(1, 2, 3)
end, function(err)
return print(yue.traceback(err))
end)
local success, result = pcall(func, 1, 2, 3)
local a, b, c
a = b ?? c
a ??= false
компилируется в:
local a, b, c
if b ~= nil then
a = b
else
a = c
end
if a == nil then
a = false
end
{_, b, _, d} = tb
компилируется в:
local b, d
do
local _obj_0 = tb
b, d = _obj_0[2], _obj_0[4]
end
copy = {...other}
компилируется в:
local copy
do
local _tab_0 = { }
local _idx_0 = 1
for _key_0, _value_0 in pairs(other) do
if _idx_0 == _key_0 then
_tab_0[#_tab_0 + 1] = _value_0
_idx_0 = _idx_0 + 1
else
_tab_0[_key_0] = _value_0
end
end
copy = _tab_0
end
local a, b, c, d
a = b ?? c ?? d
func a ?? {}
a ??= false
компилируется в:
local a, b, c, d
if b ~= nil then
a = b
else
if c ~= nil then
a = c
else
a = d
end
end
func((function()
if a ~= nil then
return a
else
return { }
end
end)())
if a == nil then
a = false
end
#: mt = tb
mt = tb.#
a = #: mt, value: 1
b = :add#, value: 2
close _ = close#: -> print "out of scope"
компилируется в:
local mt = getmetatable(tb)
mt =
``` **Moonscript compiler**
-- Получаем две таблицы в качестве аргументов
another(hello, one, two, three, four, {
yeah = man
}, {
okay = yeah,
fine = alright
})
-- Компилируется в фиксированном компиляторе Yuescript
-- Получаем одну таблицу в качестве аргумента
another(hello, one, two, three, four, {
yeah = man,
okay = yeah,
fine = alright
})
Поддержка неявных объектов для синтаксиса блока таблиц.
inventory =
equipment:
* "sword"
* "shield"
items:
* name: "potion"
count: 10
* name: "bread"
count: 3
Компилируется в:
local inventory = {
equipment = {
"sword",
"shield"
},
items = {
{
name = "potion",
count = 10
},
{
name = "bread",
count = 3
}
}
}
Добавлена поддержка локальной переменной, объявленной с атрибутом 'close' и 'const' для Lua 5.4.
close a = setmetatable {}, __close: =>
const b = if var then 123 else 'abc'
Компилируется в:
local a <close> = setmetatable({ }, {
__close = function(self) end
})
local b <const> = (function()
if var then
return 123
else
return 'abc'
end
end)()
Изменён приоритет операторов на:
Добавлена поддержка оператора существования для инструкции with.
with? io.open "test.txt", "w"
\write "hello"
\close!
Компилируется в:
local _with_0 = io.open("test.txt", "w")
if _with_0 ~= nil then
_with_0:write("hello")
_with_0:close()
end
Добавлена поддержка инструкции repeat until.
Разрешено неявно возвращать блок макроса.
Добавлена поддержка макросистемы, расширяющейся непосредственно до кодов Lua.
Добавлена поддержка goto.
Проверяется объявление вариативных аргументов.
yue
теперь поддерживает рекурсивный обход любого каталога и компиляцию любого файла moon в пути.
yue
теперь поддерживает функции REPL для Moonscript.
В yue
добавлена функция useSpaceOverTab.
В yue
добавлен minify-код Lua.
-- file 'macro.mp'
export macro config = (debugging = true)->
global debugMode = debugging == "true"
""
export macro asserts = (cond)->
debugMode and "assert #{cond}" or ""
export macro assert = (cond)->
debugMode and "assert #{cond}" or "#{cond}"
$config!
-- file 'main.mp'
import 'macro' as {:$config, :$assert, :$asserts}
macro and = (...)-> "#{ table.concat {...}, ' and ' }"
$asserts item ~= nil
$config false
value = $assert item
if $and f1!, f2!, f3!
print "OK"
-- file 'macro.mp'
local _module_0 = { }
return _module_0
-- file 'main.mp'
assert(item ~= nil)
local value = item
if (f1() and f2() and f3()) then
print("OK")
end
Исправлено несколько случаев использования backcall с присваиванием.
Исправлен случай сбоя компилятора с пустым телом кода.
Принудительное предварительное объявление переменной для назначения локальной функции. Добавленные возможности
Разрешить многострочные списки значений в операторах for и local.
Yuescript теперь компилирует исходные файлы в нескольких потоках для ускорения компиляции.
Добавить поддержку заполнителей для оператора обратного вызова.
Добавить поддержку заполнителей для инструкции обратного вызова.
Добавить поддержку жирных стрелок для инструкции обратного вызова.
Добавьте опцию для компиляции Yuescript как Lua C lib. Выпущен Yuescript в Luarocks.
Переместите старые функции оператора export в оператор global, чтобы они соответствовали оператору local.
Измените поведение оператора export для поддержки управления модулями. Коды Moon с операторами export не могут явно возвращать значения в корневой области видимости. А коды с export default могут экспортировать только одно значение в качестве содержимого модуля. Примеры использования:
— файл 'Config.mp'
export default {flag:1, value:"x"}
— файл 'Utils.mp'
export map = (items, func)-> [func item for item in *items]
export filter = (items, func)-> [item for item in *items when func item]
— файл 'main.mp'
import 'Config' as {:flag, :value}
Компилируется в:
— файл 'Config.mp'
local _module_0 = nil
_module_0 = {
flag = 1,
value = "x"
}
return _module_0
— файл 'Utils.mp'
local _module_0 = {}
local map
map = function(items, func)
local _accum_0 = {}
local _len_0 = 1
for _index_0 = 1, #items do
local item = items[_index_0]
_accum_0[_len_0] = func(item)
_len_0 = _len_0 + 1
end
return _accum_0
end
_module_0["map"] = map
local filter
filter = function(items, func)
local _accum_0 = {}
local _len_0 = 1
for _index_0 = 1, #items do
local item = items[_index_0]
if func(item) then
_accum_0[_len_0] = item
_len_0 = _len_0 + 1
end
end
return _accum_0
end
_module_0["filter"] = filter
return _module_0
— файл 'main.mp'
local flag, value
do
local _obj_0 = require('Config')
flag, value = _obj_0.flag, _obj_0.value
end
local map, filter
do
local _obj_0 = require('Utils')
map, filter = _obj_0.map, _obj_0.filter
end
Исправленные проблемы
Исправлены проблемы в оригинальном компиляторе Moonscript:
Добавленные возможности
Поддержка многострочных комментариев.
Функции обратного вызова с новым оператором и синтаксисом. Например:
{1,2,3}
|> map((x)-> x * 2)
|> filter((x)-> x > 4)
|> reduce(0, (a,b)-> a + b)
|> print
do
(data) <- http.get "ajaxtest"
body[".result"]\html data
(processed) <- http.post "ajaxprocess", data
body[".result"]\append processed
print "done"
будет скомпилировано в:
print(reduce(filter(map({
1,
2,
3
}, function(x)
return x * 2
end), function(x)
return x > 4
end), 0, function(a, b)
return a + b
end))
do
http.get("ajaxtest", function(data)
body[".result"]:html(data)
return http.post("ajaxprocess", data, function(processed)
body[".result"]:append(processed)
return print("done")
end)
end)
end
Оператор существования. Генерирует код из:
func?!
x = tab?.value
print abc?["hello world"]?.xyz
if print and x?
print x
в:
if func ~= nil then
func()
end
local x
if tab ~= nil then
x = tab.value
end
print((function()
if abc ~= nil then
local _obj_0 = abc["hello world"]
if _obj_0 ~= nil then
return _obj_0.xyz
end
return nil
end
return nil
end)())
if print and (x ~= nil) then
print(x)
end
``` **Использование ключевого слова import.**
Будет компилировать коды из:
import 'module'
import "module.part"
import "d-a-s-h-e-s"
import "player" as Player
import "lpeg" as {:C, :Ct, :Cmt}
в:
local module = require('module')
local part = require("module.part")
local d_a_s_h_e_s = require("d-a-s-h-e-s")
local Player = require("player")
local C, Ct, Cmt
do
local _obj_0 = require("lpeg")
C, Ct, Cmt = _obj_0.C, _obj_0.Ct, _obj_0.Cmt
end
Можно использовать косую черту для вызова с Lua-ключевыми словами.
Генерировать коды из:
c.repeat.if\then("xyz")\else res
в:
local _call_3 = c["repeat"]["if"]
local _call_4 = _call_3["then"](_call_3, "xyz")
_call_4["else"](_call_4, res)
-- Moonscript 0.5.0
f = (x)->
"abc",123 -- valid meaningless codes
x + 1
в оригинальном Moonscript компилируется в:
local f
f = function(x)
local _ = "abc", 123 -- report error in Yuescript
return x + 1
end
Эта функция может привести к некоторым скрытым ошибкам. Например:
tree\addChild with Node!
\addChild subNode
В оригинальном Moonscript эти коды всё равно будут выполняться после добавления ошибки по ошибке.
tree:addChild((function()
do
local _with_0 = Node()
_with_0:addChild(subNode)
return _with_0
end
end)())
local _ -- report error in Yuescript instead of creating
do -- an anonymous function to bind the object method
local _base_0 = tree
local _fn_0 = _base_0.addChild
_ = function(...)
return _fn_0(_base_0, ...)
end
end
do
local _with_0 = Node()
_with_0:addChild(subNode)
end
with leaf
.world 1,2,3
with leaf
g = .what.is.this
print g
for x in *something
print x
в:
leaf.world(1, 2, 3)
do
local g = leaf.what.is.this
print(g)
end
for _index_0 = 1, #something do
local x = something[_index_0]
print(x)
end
вместо:
do
local _with_0 = leaf
_with_0.world(1, 2, 3)
end
do
local _with_0 = leaf
local g = _with_0.what.is.this
end
local _list_0 = something
for _index_0 = 1, #_list_0 do
local x = _list_0[_index_0]
print(x)
end
Реализованы все функции Moonscript 0.5.0.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )