1. Логику нужно скриптовать на OS, работать со стеком может понадобиться при прикручивании к OS пользовательской библиотеки.
2. Исключения в виде try catch пока не реализованы, но это планируется ввести при необходимости. Сейчас есть triggerError и возможность обработки ошибок на OS или C++, например, деление на 0 кидает ошибку, которую можно перехватить.
3. замыкания реализованы, без них не было бы никакого смысла
Пример: вызовем функцию concat с двумя параметрами и получим результат в C++:
os->getGlobal("concat"); // добавляем в стек глобальную функцию concat
os->pushNull(); // добавляем this для функции concat
os->pushNumber(5); // первый параметр для concat
os->pushString(" big differences"); // второй параметр для concat
os->call(2, 1); // вызываем функцию concat с 2 параметрами, затребуем 1 результат
OS::String res = os->popString(); // сохраним результат в виде строки и уберем его из стека
OS API реализует целый ряд функций для преобразования значений в стеке в простые типы, например, toFloat, toDouble, toInt, toString, toUserdata, popFloat, popBool и т.д.
Пример функции, которую я использую для преобразования объекта {x=10 y=20} в стеке по смещению offs в b2Vec2 (это из интеграции с Box2d):
Скриптование игровой и программной логики, кросс переносимость между разными платформами. Как известно, во многих играх используется Lua для написания UI и т.п. OS нацелен на аналогичные задачи, все то, что решает Lua и JS в качестве скриптовых языков, можно делать на OS, но в более удобной форме. Я, например, занимаюсь разработкой кросс платформенного мобильного движка на OS. Не исключаю эффективное использование OS на веб серверах, т.е. на задачах, которые сейчас решает PHP и node-js.
Важно понимать, что цели заменить С++ или другой подобный язык не было. JavaScript — замечательный язык программирования. Но после разработки на нем нескольких больших проектов, мне крайне стало не хватать более человеческого ООП. Когда в очередном мобильном проекте в очередной раз пришлось нагараживать пятиэтажные конструкции и писать кучу кода на C++ вместо одной строчки на JS-подобном языке, я все таки собрался и сделал ObjectScript, сделал для своих проектов, ну а в процессе уже решил выложить в паблик. При этом тянуть на с свои проекты V8 с теми недостатками JS, кот. я перечислил выше, Lua фактически с теми же недостатками или др. язык я просто не стал по идеологическим соображениям. Сделал ObjectScript, чтобы писать для мобильных платформ. Если вам кажется, что OS похож на JS, то правильно кажется, у них и названия похожи. Я планировал сохранить все, что есть в JS и добавить при этом то, чего не хватало.
Класс IvanPerson не знает, как реализован метод walk() из класса Person, но может использовать этот метод. В классе IvanPerson нет необходимости даже определять walk() до тех пор, пока не понадобиться изменить его. Все классы наследуют методы своих родителей и определяют только новые методы или те, которые нужно изменить — это называется инкапсуляция.
Перегрузка методов
Опишем класс IvanPerson следующим образом
var IvanPerson = extends Person {
__construct = function(){
super("Ivan", "Petrov")
}
walk = function(){
echo "Soneone named "
super()
}
}
var p = IvanPerson() // создадим экземпляр класса IvanPerson
p.walk()
print p
Выведется:
Soneone named Ivan Petrov is walking!
{"firstname":"Ivan","lastname":"Petrov"}
super вызывает метод родительского класса (прототипа) с именем метода, из которого он был вызван! Тут речь идет о любом методе, нужно просто вызвать super с нужными параметрами.
Ручная передача this в функцию
Чтобы вызвать функцию и передать в нее нужный нам this, воспользуйтесь методом call класса Function. Продолжая предыдущий пример:
Person.walk.call(p)
Выведется:
Ivan Petrov is walking!
Метод call вызывает функцию с нужным нам this и остальными параметрами, с которыми call был вызван. Если остальные параметры собраны в масив, то воспользуйтесь методом apply класса Function.
function foo(a, b){ return a + b }
function bar(){ return foo.apply(null, arguments) }
print bar(2 3)
print bar(4 5)
Выведется:
5
9
P.S. заодно проверил и исправил баг в apply, если вы уже клонировали репозиторй, обновитесь пожалуйста
В начале я планировал использовать ref-counting + GC для решения проблем с cyclic references, но в ходе реализации сборщика мусора ref-counting как таковой был убран, т.к. ничего не упрощал в процессе сбора мусора. В текущей реализации ref-count присутствует, но только как счетчик использования объекта где-то на стороне (за пределами OS) и зовется в коде external_ref_count. Иначе говоря сам OS ref-count не использует, а сборщик мусора не удаляет объекты с external_ref_count > 0. Cyclic references при этом разруливается без проблем.
Я попробовал реализовать tri-color incremental garbage collector, иначе говоря сборка мусора делается не за один проход, а за много во избежании высокой нагрузки самого сборщика на систему. Что из этого получилось? Работает и не падает, все что надо удаляет, удалось затюнить сборщик для максимально возможного fps на моем мобильнике HTC Desire (в тех демках, что я делаю на OS). Тем не менее, я не доволен тем, что fps не ровный, но пока не уверен в чем именно проблема, в сборщике мусора или в чем-то другом.
Изначально язык нацелен на аудиторию лояльную к C-подобным языкам, к ним я отношу JavaScript, PHP, Lua ну и некоторые другие.
А в целом я работаю над реализацией движка для написания кросс платформенных приложений по типу Corona SDK, но на ObjectScript и Marmalade SDK. Не отказался бы от интеграции с др. платформами, например, Irrlicht, Shiva3D и др. В принципе область применения может быть довольно большой, тот же node.os (как аналог node.js).
Насколько мне известно, от русскоязычного комьюнити мировому сообществу пока не предложено языков высокого уровня. Что я предлагаю — завершить спецификацию ObjectScript, создать комьюнити, может быть найти инвестиции.
Будет синтаксическая ошибка, попытается вернуть b, а там равно, равно в OS не возвращает значение. По крайней мере в текущей версии, тут прямой аналог — Lua, и нужно это для множественного присваивания, когда значение вынимается из стека, чтобы корректно присвоить следующее значение. Поэтому после return следует ставить ; чтобы однозначно отделить синтаксис.
1. в Lua работают и запятые и точки с запятой, тут я не усмотрел криминала, хотя и соглашусь с тем, что лучше использовать один синтаксис
2. согласен
3. дело в том, что
a = {x=1, y=3; "zero" "one", "two" last:7,}
эквивалентен объекту на JS
a = {x:1, y:3, 0:"zero", 1:"one", 2:"two", last:7}
поэтому print a[1] выведет one
4. в OS (ObjectScript) изначально все функции — лямбды, запись с ключевым словом function на мой взгляд воспринимается более читабельно
5. код obj = { null awesome={1,2} {12, 24}} for({k, v} in obj){ print( k " --> " v ) } не совсем валидный в части for({k, v}, тут требуется writeable, а {k, v} не writeable и компилятор будет ругаться
6. 7. согласен get color { return .... } выглядит лучше. Я хочу лишь отметить, что это все равно будет скомпилировано в метод с именем __get@color, а это нужно программисту теоретически знать. Сейчас уже есть синтаксис вида:
var alphaBlending
function get alphaBlending(){ return alphaBlending }
function set alphaBlending(a){
alphaBlending = a
if(a){
glEnable(GL_BLEND)
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST)
}else{
glDisable(GL_BLEND)
}
}
см. director.os — это из 2d движка, который я пишу для мобильных платформ на ObjectScript. Данный синтаксис пока не добавлен в описание объекта.
8. delete работает также как в JS, т.е. удаляется не само значение, а ссылка на него или свойство в данном случае. Сам же объект разрушается в процессе сбора мусора
9. согласен
10. есть например такой язык objective-c, который используется в продуктах Apple (по сути все не кроссплатформенные приложения для Apple App Store написаны на objective-c), там можно вызвать метод для null объекта и это будет проглочено молча без единного предупреждения, что произойдет? да ничего, просто метод (там это называется событие) не будет вызван. Текущая версия OS поведет себя так же, но я планирую более детально проработать этот момент. Например, в текущий момент при разработке на OS мне очень сильно помогает лог доступа к необъявленым свойсвам и делается это средствами самого же OS. Например, посмотрим файл core.os
function __get(name){
echo("global property \""name"\" is not declared\n")
echo "back trace\n"
printBackTrace(1)
echo "\n"
}
function Object.__get(name, autoCreate){
if(autoCreate) return;
echo("object property \""name"\" is not declared\n")
echo "back trace\n"
printBackTrace(1) // skip current function
echo("=======\ntarget "this"\n\n")
}
function Userdata.__set(name, value){
echo("userdata property \""name"\" is not declared, set value "value"\n")
echo "back trace\n"
printBackTrace(1) // skip current function
echo("=======\ntarget "this"\n\n")
}
function assert(a, message){
if(!a){
print(message || "assert failed")
printBackTrace(1)
terminate()
}
}
setErrorHandler(function(code message file line){
var type = "ERROR"
if(code == E_WARNING)
type = "WARNING"
else if(code == E_NOTICE)
type = "NOTICE"
echo("["type"] "message"\n")
echo "back trace\n"
printBackTrace(1) // skip current function
})
function printBackTrace(skipNumFuncs){
for(var i, t in debugBackTrace(skipNumFuncs + 1)){ // skip printBackTrace
echo("======= ["i"]\n")
// echo(" line: "t.line", pos: "t.pos", token: "t.token", file: "t.file"\n")
echo(" line: "t.line", pos: "t.pos", file: "t.file"\n")
echo(" function: "t.name", arguments: "t.arguments"\n")
// print concat(" object: "(t.object === _G && "<<GLOBALS>>" || t.object)"\n")
}
}
Весь вывод через echo & print перехватывается в виртуальной функции унаследованного от класса ObjectScript и записывается в файл. Таким образом я всегда вижу наличие проблемы, printBackTrace при этом дампит детальный call stack, поэтому я могу понять от куда был вызов и с какими параметрами.
Я могу лишь сказать, что изменение/удаление итератора для стандартных типов (array, object) не приведет к падению, более того отработает как задумано программистом. Но я бы не применял такую практику.
2. Исключения в виде try catch пока не реализованы, но это планируется ввести при необходимости. Сейчас есть triggerError и возможность обработки ошибок на OS или C++, например, деление на 0 кидает ошибку, которую можно перехватить.
3. замыкания реализованы, без них не было бы никакого смысла
concatс двумя параметрами и получим результат в C++:OS API реализует целый ряд функций для преобразования значений в стеке в простые типы, например,
toFloat, toDouble, toInt, toString, toUserdata, popFloat, popBoolи т.д.Пример функции, которую я использую для преобразования объекта
{x=10 y=20}в стеке по смещениюoffsвb2Vec2(это из интеграции с Box2d):Но в то же время, любые разумные предложения приветствуются, предложения и способы реализации.
Простые типы это: number, string, boolean, null. Оператор valueof преобразует аргумент в простой тип.
Но на практике часто используются др. сопутствующие операторы, например, numberof и т.п., например:
в JavasScript часто пишут так:
что полностью допустимо в ObjectScript, а в сочетании с objectof дополнительная проверка типа.
Инкапсуляции
Класс
IvanPersonне знает, как реализован методwalk()из классаPerson, но может использовать этот метод. В классеIvanPersonнет необходимости даже определятьwalk()до тех пор, пока не понадобиться изменить его. Все классы наследуют методы своих родителей и определяют только новые методы или те, которые нужно изменить — это называется инкапсуляция.Перегрузка методов
Опишем класс IvanPerson следующим образом
Выведется:
super вызывает метод родительского класса (прототипа) с именем метода, из которого он был вызван! Тут речь идет о любом методе, нужно просто вызвать super с нужными параметрами.
Ручная передача this в функцию
Чтобы вызвать функцию и передать в нее нужный нам
this, воспользуйтесь методомcallклассаFunction. Продолжая предыдущий пример:Выведется:
Метод
callвызывает функцию с нужным намthisи остальными параметрами, с которымиcallбыл вызван. Если остальные параметры собраны в масив, то воспользуйтесь методомapplyклассаFunction.Выведется:
P.S. заодно проверил и исправил баг в apply, если вы уже клонировали репозиторй, обновитесь пожалуйста
А в целом я работаю над реализацией движка для написания кросс платформенных приложений по типу Corona SDK, но на ObjectScript и Marmalade SDK. Не отказался бы от интеграции с др. платформами, например, Irrlicht, Shiva3D и др. В принципе область применения может быть довольно большой, тот же node.os (как аналог node.js).
Насколько мне известно, от русскоязычного комьюнити мировому сообществу пока не предложено языков высокого уровня. Что я предлагаю — завершить спецификацию ObjectScript, создать комьюнити, может быть найти инвестиции.
2. согласен
3. дело в том, что
эквивалентен объекту на JS
поэтому
print a[1]выведет one4. в OS (ObjectScript) изначально все функции — лямбды, запись с ключевым словом function на мой взгляд воспринимается более читабельно
5. код
obj = { null awesome={1,2} {12, 24}} for({k, v} in obj){ print( k " --> " v ) }не совсем валидный в частиfor({k, v}, тут требуется writeable, а{k, v}не writeable и компилятор будет ругаться6. 7. согласен
get color { return .... }выглядит лучше. Я хочу лишь отметить, что это все равно будет скомпилировано в метод с именем__get@color, а это нужно программисту теоретически знать. Сейчас уже есть синтаксис вида:см. director.os — это из 2d движка, который я пишу для мобильных платформ на ObjectScript. Данный синтаксис пока не добавлен в описание объекта.
8. delete работает также как в JS, т.е. удаляется не само значение, а ссылка на него или свойство в данном случае. Сам же объект разрушается в процессе сбора мусора
9. согласен
10. есть например такой язык objective-c, который используется в продуктах Apple (по сути все не кроссплатформенные приложения для Apple App Store написаны на objective-c), там можно вызвать метод для null объекта и это будет проглочено молча без единного предупреждения, что произойдет? да ничего, просто метод (там это называется событие) не будет вызван. Текущая версия OS поведет себя так же, но я планирую более детально проработать этот момент. Например, в текущий момент при разработке на OS мне очень сильно помогает лог доступа к необъявленым свойсвам и делается это средствами самого же OS. Например, посмотрим файл core.os
Весь вывод через
echo & printперехватывается в виртуальной функции унаследованного от класса ObjectScript и записывается в файл. Таким образом я всегда вижу наличие проблемы,printBackTraceпри этом дампит детальный call stack, поэтому я могу понять от куда был вызов и с какими параметрами.