ПроектыФорумОцените

ObjectScript — добавлено видео по установке под Windows, новый встраиваемый язык программирования (скрипты, веб, 2d mobile engine) (7 стр)

Страницы: 16 7 8 912 Следующая »
#90
10:34, 5 апр 2013

Обновление ObjectScript 1.6.3-dev - улучшение производительности.

ObjectScript - динамический язык, тем не менее компилятор теперь умеет автоматически определять тип переменных.

Как OS определяет тип переменных?

Компилятор смотрит, в каком контексте используется локальная переменная. Если переменной присваиваются только числовые константы и результаты выражений, которые возвращают число, то компилятор OS маркирует тип данной переменной, как числовой.

Как это работает на практике (код компилятора с комментариями, из файла objectscript.cpp):

  switch(exp->type){
  case EXP_TYPE_CONST_NUMBER:
    // это числовая константа, определенно результат - числовой тип
    exp->local_var.type = CVT_NUMBER;
    break;

  case EXP_TYPE_GET_LOCAL_VAR:
    // считываем тип локальной переменной из декларативной области,
    // компилятор сохраняет туда рассчитанный тип переменной
    exp->local_var.type = scope->getLocalVar(exp->local_var).type;
    break;

  // записываем в локальную переменную значение
  case EXP_TYPE_SET_LOCAL_VAR:
    {
      Expression * exp2 = exp->list[0];
      // если ранее компилятор не определил, что тип переменной динамический,
      // то пытаемся определить тип сейчас
      if(exp->local_var.type != CVT_DYNAMIC){
        ECompiledValueType old_type = exp->local_var.type;
        // если переменной присваивается числовое значение
        if(exp2->local_var.type == CVT_NUMBER){
          // то маркируем тип переменной, как числовой
          exp->local_var.type = CVT_NUMBER;
        }else{
          // иначе, переменная имеет динамический тип
          // т.е. если даже ранее переменной присваивались числовые значения,
          // то теперь мы понимаем, что переменная все же используется
          // не только как число
          exp->local_var.type = CVT_DYNAMIC;
        }
        if(old_type != exp->local_var.type){
          // сохраняем тип в декларативной области
          scope->getLocalVar(exp->local_var).type = exp->local_var.type;
        }
      }
      break;
    }

  // обрабатываем разные математические операторы
  case EXP_TYPE_BIT_AND: // &
  case EXP_TYPE_BIT_OR: // |
  case EXP_TYPE_BIT_XOR: // ^
  case EXP_TYPE_COMPARE: // <=>
  case EXP_TYPE_ADD: // +
  case EXP_TYPE_SUB: // -
  case EXP_TYPE_MUL: // *
  case EXP_TYPE_DIV: // /
  case EXP_TYPE_MOD: // %
  case EXP_TYPE_LSHIFT: // <<
  case EXP_TYPE_RSHIFT: // >>
  case EXP_TYPE_POW: // **
    {
      Expression * left_exp = exp->list[0];
      Expression * right_exp = exp->list[1];
      // если аргументы операторов - числовые
      if(left_exp->local_var.type == CVT_NUMBER && right_exp->local_var.type == CVT_NUMBER){
        // то определенно результат будет числовой
        exp->local_var.type = CVT_NUMBER;
      }else{
        // иначе результат оператора является не известным на момент
        // компиляции типом
        exp->local_var.type = CVT_DYNAMIC;
      }
      break;
    }

Далее при генерации команд для виртуальной машины OS, компилятор смотрит, можно ли задействовать более быстрые варианты команд. В виртуальную машину были добавлены новые команды (OP_NUMBER_ADD, OP_NUMBER_SUB и др.) для выполнения математических операторов над числовыми аргументами, которые сразу выполняют математическую операцию без необходимости проверки типа. На этом и строится новая модель виртуальной машины и улучшение производительности. 

Основной мой тест производительности - это fannkuch. В этом тесте компилятор соптимизировал всего несколько переменных, но даже это дало выигрыш. Все тестировалось на виндах в win32 версиях всех языков:

OS 1.6.3-dev - 9,79 сек (это на секунду быстрее предыдущей версии)
Lua 5.1 - 10,89 сек
Ruby 2.0 - 18,45 сек
PHP 5.3.22 - 27,87 сек

Чем меньше время, тем лучше.

Тут показано среднее время по 20 итерациям с параметром запуска алгоритма равным 10.

P.S. по такому же принципу можно реализовать автоматическое определение булевых выражений и некоторых др. типов.

#91
15:27, 5 апр 2013

Скажи, а ты синтаксис языка нигде не описывал в каком-то кратком виде?
Ну примерно вот что-то такое http://www.lua.org/manual/5.1/manual.html#8

#92
19:24, 5 апр 2013

Я вот коротко отвечу вам на вопросы в первом посте. Зачем там запятая, здесь точка, скобка и т.п. Почему программу нужно выделять в Begin/End, подробно описывать переменные до их использования, вместо того что бы целые конструкции заменить парой-тройкой закарючек...
Ответ простой: языки, которые вы осуждаете/упрощаете созданы Программистами и для Программистов, а не быдло-кодерами и прежде всего были рассчитаны на получение удовольствия от программирования и базировались на человекопонятности. При этом находя отличный компромисс между удобством интерпритированием кода машиной и написанием его человеком. Вы же пытаетесь изобрести очередной язык, далёкий от удобности и человеку и машине… Зачем? Куда ещё "круче", чем уже есть?!
Хотите что бы программист после сотой строчки своего кода, уже как баран на новые ворота смотрел на первую?

#93
22:27, 5 апр 2013

UnitPoint

Уважаю твой труд. Но все же не могу понять, зачем изобретать велосипед ?

Просто не увидел ничего принципиально нового, кроме очень-очень сомнительного "облегчения синтаксиса" с запятыми.
Меньше кол-во знаков - не значит более читабельный код. По-русски когда пишешь, можно тоже писать все строчными буквами и без знаков препинания. Народ все поймет, но не заценит. Знаки форматирования/препинания - они именно и нужны для облечения восприятия и конкретизации текста. Это не блажь, и не подсказка "тупому компилятору". Они нужны самому программисту.

#94
22:47, 5 апр 2013

Маг
> кроме очень-очень сомнительного "облегчения синтаксиса" с запятыми.
+1
Мало какой редактор кода сегодня не умеет дополнять скобки, функции, методы и запятые, а также следить за отступами. Для этого же велосипеда не будет ни одной IDE, а универсальные редакторы просто не разберутся в синтаксисе. Как говорится язык - это пол-дела. Когда он будет мейнстримом - вот в чём вопрос.

Нет, серьёзно, ни один адекватный программист не забросит Си/С++ за сложный синтаксис, а вот отсутствие stdlib и вменяемого редактора...

#95
23:15, 5 апр 2013

Информация на первой странице не совсем актуально, надо бы ее обновить. Запятые - must have с версии 1.5-dev от 14 марта 2013.

x
> Скажи, а ты синтаксис языка нигде не описывал в каком-то кратком виде?

Полное описание синтаксиса языка есть на вики Programming in ObjectScript, в кратком виде не описывал.

#96
23:22, 5 апр 2013
CMake Error at proj.win32/os/CMakeLists.txt:50 (add_executable):
  Cannot find source file:

    ./../../source/ext-curl/os-curl.h

вы каждым релизом ломаете сборку на линуксе)

#97
23:35, 5 апр 2013

RPG
> вы каждым релизом ломаете сборку на линуксе)

Да вроде не сломалось, только что проверил, делал так:

git clone git://github.com/unitpoint/objectscript.git
cd ./objectscript
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/../ ..
make 
make install

OS использует при компиляции либы cURL (загрузка по протоколу http и др.) и PCRE (регулярные выражения), уже установленые в linux. Правда скомпилится и без них (ругнется немного при сборке), но классы Curl и Regexp тогда будут недоступны. Сейчас в комплекте также идет sqlite3. Примеры использования есть в test.os

запуск тестового скрипта:

../bin/oscript ../examples-os/test.os

P.S. oscript надо бы переименовать в os

#98
21:13, 6 апр 2013

UnitPoint
Как хранятся "порядковые" поля объектов?

var o = {}
o[123] = "aaa"
o["key"] = "bbb"

Ну т.е. понятно что числа тоже какой-то хэшмап формируют, но он общий со строковыми ключами или их два разных?

#99
11:16, 8 апр 2013

Выполнение операции в хеш-таблице начинается с вычисления хеш-функции от ключа. Получающееся хеш-значение  играет роль индекса в массиве H. Затем выполняемая операция (добавление, удаление или поиск) перенаправляется объекту, который хранится в соответствующей ячейке массива . Ситуация, когда для различных ключей получается одно и то же хеш-значение, называется коллизией. Существует несколько способов разрешения коллизий.

ObjectScript использует метод цепочек: каждая ячейка массива H является указателем на связный список (цепочку) пар ключ-значение, соответствующих одному и тому же хеш-значению ключа. Коллизии просто приводят к тому, что появляются цепочки длиной более одного элемента.

В ObjectScript хеш-функция от ключа реализована следующим образом:

int OS::Core::getValueHash(const Value& index)
{
  switch(OS_VALUE_TYPE(index)){
  case OS_VALUE_TYPE_NULL:
    return 0;

  case OS_VALUE_TYPE_BOOL:
    return OS_VALUE_VARIANT(index).boolean;

  case OS_VALUE_TYPE_NUMBER:
    {
      float d = (float)OS_VALUE_NUMBER(index);
      OS_BYTE * buf = (OS_BYTE*)&d;
      int hash = OS_STR_HASH_START_VALUE;
      OS_ADD_STR_HASH_VALUE; buf++;
      OS_ADD_STR_HASH_VALUE; buf++;
      OS_ADD_STR_HASH_VALUE; buf++;
      OS_ADD_STR_HASH_VALUE;
      return hash;
    }

  case OS_VALUE_TYPE_STRING:
    return OS_VALUE_VARIANT(index).string->hash;
  }
  // all other values share same area with index.v.value so just use it as hash
  return OS_PTR_HASH(OS_VALUE_VARIANT(index).value);
}

т.е. хеш от строки уже хранится в объекте строки (это позволяет хранить одинаковые строки в одном экземпляре, даже полученные в рантайме), хеш от числа - некая контрольная сумма от бинарного представления числа в виде float (это нужно, чтобы задействовать по возможности все биты хеша примерно одинакого), хеш для булевого значения - само значение, для остальных типов хеш высчитывается на основе указателя аллоцированного объекта.

Для строк легко проверить, что одинаковые строки хранятся в одном экземпляре на следующем примере:

var s1 = "John Smith"
print(s1, "id: " .. s1.id)

var s2, s3 = "John", "Smith"
print(s2, "id: " .. s2.id)
print(s3, "id: " .. s3.id)

var s4 = s2 .. " " .. s3
print(s4, "id: " .. s4.id)

выведет:

John Smith      id: 1031
John    id: 1036
Smith   id: 1037
John Smith      id: 1031

id - внутренний идентификатор объекта в системе сборки мусора, он всегда уникальный. Видно, что константная строка "John Smith" и полученная в рантайме с помощью конкатенации строка "John Smith" получила идентификатор равный 1031. Это резко уменьшает размер используемой памяти в ObjectScript.

#100
15:40, 26 апр 2013

Добавил к языку расширение OpenGL и немного примеров, матрица:

+ Показать

полный исходник этого примера

Звездное небо:

+ Показать

полный исходник этого примера

Папка с примерами: https://github.com/unitpoint/objectscript/tree/master/examples-os/opengl

Как выглядит сркрипт:

+ Показать

Т.е. очень похоже на C++, можно на скрипте быстро написать и сразу запустить. Для чего это может использоваться? - скорее всего для обучения OpenGL или чтобы быстро что-то проверить.

P.S. пока не весь функционал OpenGL реализован, компиляция настроена под windows, запускаемый файл bin\os.exe скомпилирован с поддержкой этого расширения

P.P.S. генератор для source/ext-opengl/os-opengl.inc реализован на самом OS в этом файле source/ext-opengl/parse-gl.os

#101
21:44, 27 апр 2013

UnitPoint
Верной дорогой идёте, товарищ!

#102
13:19, 28 апр 2013

Возможно использовать OS в моих играх в том качестве как Lua?

#103
13:27, 28 апр 2013

polyfrag
> Возможно использовать OS в моих играх в том качестве как Lua?
UnitPoint
> Для чего это может использоваться? - скорее всего для обучения OpenGL или чтобы
> быстро что-то проверить.
Lua давно используется вовсю в играх как язык программирования (логики как минимум). Так что если язык до этого дорастёт - почему нет?:)

#104
14:24, 28 апр 2013

Нельзя использовать как библиотеку, я так понял.

Страницы: 16 7 8 912 Следующая »
ПроектыФорумОцените

Тема в архиве.