Re[4]: [Nitra] Пример простого языка вычисляющего выражения
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.12.15 11:38
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>Влад, чисто политический момент: Нитра — не какая-то там саморасширяющаяся Немерля, а ажно целый конструктор таких языков! Не кажется ли тебе, что это прыжок через ступеньку?


Нет. Не кажется.

Чтобы решить сложную задзадачу нужен инструмент подходящей мощности. Или очень большие ресурсы. Их нам никто не предоставит.

У немерла куча проблем:
1. Его иерархия типов захардкожена и не расширяется. Релизация чего–то сложного приводит к созданию параллельной системы типов.
2. Сам язык типизируется горой кода в которой не могут разобраться даже авторы.
3. Изза итсутствия аналога зависимых свойств в коде очень трудно контроллировать правильность последовательности вычислений. Это приводит к огромным трудностями в отладке багов связанных с невердой последовательностью вычислений.
3. С расширяемостью синтаксиса у немерла проблемы. Тот же query comprehension (синтаксис Linq) пришлось засовывать в кавычки. На уровне типов вообще хрен расширишь.
4. Есть проблемы с интеграцией с IDE.

Подход же использованый с Nitra позволяет нам решить все проблемыиразом и за одно продемонстрировать все преимущества DSL.

Что касается кажущейся, на первый взгляд, сложности, то это ложное ощущение. Если сравнить это решение с рукапашным, то окажется, что оно очь компактное и ничего лишнего в нем нет. Одна только поддержка в IDE выльется в гору кода. А тут она будет из коробки. Ну, а чем боллее сложен будет язык, тем очевиднее будет разница.

Но пожалуй самое важное это, что DSL–подход позволяет держать сложность в рамках разумного и легко менять реализацию, если это необходимо.

K>Может, сначала саму Немерлю-2 стоило начать с чистого листа, реализовать почти так же, но с учётом всего того, что вам нехватало?


Поверь, это не намного проще получилось бы и большой шанс получить большинство проблем немерла. Причину некоторых его проблем я понял только работая над Нитрой.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [Nitra] Пример простого языка вычисляющего выражения
От: Kolesiki  
Дата: 06.12.15 19:14
Оценка:
Здравствуйте, VladD2, Вы писали:

Влад, я даже осознать не могу, насколько Нитра мощнее Немерли (ибо не знаю трудоёмкости и насколько Нитра упростит жизнь), но попробую снова высказаться за Немерле-1.5 что ли

VD>У немерла куча проблем:

VD>1. Его иерархия типов захардкожена и не расширяется.

При переписывании это легко устранить, опираясь только на внутренние типы .NET; Касательно вообще типов, мы все знаем, что .NET "объектно натянут" по самые хэдеры, т.е. "язык под .НЕТ" уже должен быть ООП, с классами и методами.
Это я к тому, что нет смысла закладываться на "язык черепашки с вкраплениями SQL", т.к. это ортогональное дотнету решение. А раз мы в рамках ООП, то и "конструктор языков" сразу можно упростить до понятия "у нас есть классы и их члены" — далее можно плясать от этой модели.

VD>2. Сам язык типизируется горой кода в которой не могут разобраться даже авторы.


Очевидно, что студенческий код рано или поздно пришлось бы выкинуть, но для этого вы и нужны — люди, которые знают старое и видят, как правильно создавать новое!

VD>3. Из-за итсутствия аналога зависимых свойств в коде очень трудно контроллировать правильность последовательности вычислений. Это приводит к огромным трудностями в отладке багов связанных с невердой последовательностью вычислений.


эээ.... даже не понял, про что это. Думаю, Туьукду(Nemerle ) не первый компилятор, построенный без них — другие же как-то справляются?

VD>3. С расширяемостью синтаксиса у немерла проблемы. Тот же query comprehension (синтаксис Linq) пришлось засовывать в кавычки. На уровне типов вообще хрен расширишь.


Ну вот! Это и есть точка улучшения. В смысле взять то, что есть и расширить.

VD>4. Есть проблемы с интеграцией с IDE.


Утилитарные мелочи, MS и сам признаёт, что нагородил фигни (потому и стал запиливать Roslyn). Опять же, кто сказал, что нужна именно VS? Сред для расширения навалом, можно и своё написать.

Но я в целом что хотел сказать: пилить "конструктор" и пилить "расширяемый язык" — две задачи, отличающиеся на порядок (понятно, последняя проще). Потому мне и кажется, что запиливание Немерли-1.5 "с нуля" (и постепенной переброской полезностей из Немерли-1) было бы проще — вы знаете слабые места и знаете, как это решить. Конструктор сразу надевает вам на голову "шлем всемогутерства", в котором... нет дырок! Вы не знаете, куда и как люди захотят расширять язык. Или наоборот — бросите кучу сил в направлении, которое окажется невостребованным.
По ср. с конструктором, Немерля-1.5 была бы проще, т.к. опиралась бы на устоявшуюся схему: классы, члены классов, точки расширения и макросы.

VD>Поверь, это не намного проще получилось бы и большой шанс получить большинство проблем немерла. Причину некоторых его проблем я понял только работая над Нитрой.


Никто ж не просит тащить старые проблемы в новый язык! Зато Немерля-1.5 — это почти вся идеология старой Немерли (по которой мы уже имеем багаж понятных доков) минус ограничения студенческой реализации.
Надеюсь, я донёс свою мысль. Время у вас может и не самый решающий фактор, но даже Немерля-1.5 отняла бы приличную долю усилий, которая за год уже дала бы ощутимый результат. Ощутимый нами, людьми извне — вот что важно.
Отредактировано 06.12.2015 19:35 Kolesiki . Предыдущая версия .
Re[4]: [Nitra] Пример простого языка вычисляющего выражения
От: novitk США  
Дата: 08.12.15 20:34
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, novitk, Вы писали:


N>>Мало? Я уверен, что реализация этой задачи на скажем ANTLR/Скале будет не больше.


VD>Я рад за твою уверенность. Сделай, сравним.


Думал оно будет очевидно. Впрочем мне не сложно набросать полсотни строчек.

[scala]
import scala.util.parsing.combinator._

object Main extends JavaTokenParsers {
class Expr;
case class NumberExpr(num: Int) extends Expr;
case class MultExpr(expr: Expr) extends Expr;
case class DivExpr(expr: Expr) extends Expr;
case class AddExpr(expr: Expr) extends Expr;
case class SubtractExpr(expr: Expr) extends Expr;
case class VarExpr(name: String) extends Expr;
case class OpExpr(expr: Expr, subExprs: List[Expr]) extends Expr;
class VarDef(val name: String, val expr: Expr)

class EvalContext(val vars: Map[String, VarDef]) {
val results = scala.collection.mutable.Map[String, Int]()
def evalVar(name: String): Int =
{
if (!results.contains(name))
results(name) = evalExpr(vars(name).expr)
results(name)
}
def evalExpr(expr: Expr): Int = expr match {
case NumberExpr(num) => num
case VarExpr(name: String) => evalVar(name)
case OpExpr(expr, subExprs: List[Expr]) =>
subExprs.foldLeft(evalExpr(expr)) {
(a, subExpr) =>
subExpr match {
case MultExpr(exprInner) => a * evalExpr(exprInner)
case DivExpr(exprInner) => a / evalExpr(exprInner)
case AddExpr(exprInner) => a + evalExpr(exprInner)
case SubtractExpr(exprInner) => a — evalExpr(exprInner)
}
}
}
}

def makeOpExpr(p: ~[Expr, List[Expr]]): Expr = p match {
case f ~ Nil => f
case f ~ l => OpExpr(f, l)
}
def factor: Parser[Expr] = wholeNumber ^^ (s => NumberExpr(s.toInt)) | ident ^^ VarExpr | "(" ~> expr <~ ")"
def term: Parser[Expr] = (factor ~ rep("*" ~> factor ^^ MultExpr | "/" ~> factor ^^ DivExpr)) ^^ makeOpExpr
def expr: Parser[Expr] = (term ~ rep("+" ~> term ^^ AddExpr | "-" ~> term ^^ SubtractExpr)) ^^ makeOpExpr
def varDef: Parser[VarDef] = ("var" ~> ident) ~ ("=" ~> expr) ^^ { case n ~ e => new VarDef(n, e) }
def varDefParseAll(in: CharSequence): ParseResult[VarDef] = parseAll(varDef, in)

def main(args: Array[String]) = {
val vars: Map[String, VarDef] = Map(args.toSeq.map(varDefParseAll).filter(_.successful).map {
pr =>
{
val vd = pr.get
vd.name -> vd
}
}: _*)
val evalCtx = new EvalContext(vars)
println(evalCtx.evalVar("b"))
}
}
[/scala]
Отредактировано 09.12.2015 21:28 VladD2 . Предыдущая версия .
Re[5]: [Nitra] Пример простого языка вычисляющего выражения
От: WolfHound  
Дата: 08.12.15 22:58
Оценка:
Здравствуйте, novitk, Вы писали:

N>Думал оно будет очевидно. Впрочем мне не сложно набросать полсотни строчек.

1)Это ужос:
  def makeOpExpr(p: ~[Expr, List[Expr]]): Expr = p match {
    case f ~ Nil => f
    case f ~ l => OpExpr(f, l)
  }
  def factor: Parser[Expr] = wholeNumber ^^ (s => NumberExpr(s.toInt)) | ident ^^ VarExpr | "(" ~> expr <~ ")"
  def term: Parser[Expr] = (factor ~ rep("*" ~> factor ^^ MultExpr | "/" ~> factor ^^ DivExpr)) ^^ makeOpExpr
  def expr: Parser[Expr] = (term ~ rep("+" ~> term ^^ AddExpr | "-" ~> term ^^ SubtractExpr)) ^^ makeOpExpr
  def varDef: Parser[VarDef] = ("var" ~> ident) ~ ("=" ~> expr) ^^ { case n ~ e => new VarDef(n, e) }
  def varDefParseAll(in: CharSequence): ParseResult[VarDef] = parseAll(varDef, in)

2)Поддержка ИДЕ где?
3)Вывод сообщений об ошибках парсинга где?
4)Вывод сообщений о неизвестных переменных где?
5)Проверка на зацикливание вычислений где?
6)Расширяемость где?
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: [Nitra] Пример простого языка вычисляющего выражения
От: novitk США  
Дата: 08.12.15 23:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>1)Это ужос:

Это обычные, известные даже детям, парсековские комбинаторы на Скале. Что в них ужасного?

WH>2)Поддержка ИДЕ где?

У меня нет Нитры. Что такого волшебного делает поддержка ИДЕ у вас для этого примера? Раскрашивает текст?

WH>3)Вывод сообщений об ошибках парсинга где?

WH>4)Вывод сообщений о неизвестных переменных где?
WH>5)Проверка на зацикливание вычислений где?
Ты ведь отлично знаешь что это три строчки. Зачем придуриваешься?

WH>6)Расширяемость где?

Расширяемость куда? Если пример неудачный, сделайте наконец нормальный, который покажет мне нафиг мне сдался все эти ваши мэппинги и прочие прелести. Пока оно не видно.
Re[7]: [Nitra] Пример простого языка вычисляющего выражения
От: WolfHound  
Дата: 08.12.15 23:53
Оценка:
Здравствуйте, novitk, Вы писали:

N>Это обычные, известные даже детям, парсековские комбинаторы на Скале. Что в них ужасного?

Примерно всё. И про парсер комбинаторы я знаю ещё с тех времен, когда скалы в проекте не было.

N>У меня нет Нитры. Что такого волшебного делает поддержка ИДЕ у вас для этого примера? Раскрашивает текст?

Раскрашивает текст.
Подсвечивает ошибки.
Работает автодополнение.

WH>>3)Вывод сообщений об ошибках парсинга где?

WH>>4)Вывод сообщений о неизвестных переменных где?
WH>>5)Проверка на зацикливание вычислений где?
N>Ты ведь отлично знаешь что это три строчки. Зачем придуриваешься?
Я отлично знаю, что ты это не сделал.

WH>>6)Расширяемость где?

N>Расширяемость куда?
Куда угодно.
Попробуй добавить новый оператор с новым приоритетом так чтобы твой код не трогать.
Например, он лежит в ДЛЛ, исходники которой ты менять не можешь.

N>Если пример неудачный, сделайте наконец нормальный, который покажет мне нафиг мне сдался все эти ваши мэппинги и прочие прелести. Пока оно не видно.

Сначала этот пример повтори.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: [Nitra] Пример простого языка вычисляющего выражения
От: _NN_ www.nemerleweb.com
Дата: 09.12.15 11:23
Оценка: +2
Здравствуйте, WolfHound, Вы писали:

N>>Если пример неудачный, сделайте наконец нормальный, который покажет мне нафиг мне сдался все эти ваши мэппинги и прочие прелести. Пока оно не видно.

WH>Сначала этот пример повтори.

Мне кажется , что нужны как раз примеры , где все эти достоинства показываются.
В простом примере вроде этого конечно трудно осознать.

Скажем, можно сделать два проекта , чтобы показать расширяемость.
Вместе с этим снимки экранов , где показана подсветка , сообщения об ошибках и автодополнения.

Тогда будет легче объяснить почему Nitra делает намного больше чем просто парсит.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: [Nitra] Пример простого языка вычисляющего выражения
От: _NN_ www.nemerleweb.com
Дата: 09.12.15 11:25
Оценка:
Здравствуйте, novitk, Вы писали:

N>Думал оно будет очевидно. Впрочем мне не сложно набросать полсотни строчек.


Можно объяснить что означает "~" в ~[Expr] и в f ~ Nil в Scala ?
  def makeOpExpr(p: ~[Expr, List[Expr]]): Expr = p match {
    case f ~ Nil => f
    case f ~ l => OpExpr(f, l)
  }
http://rsdn.nemerleweb.com
http://nemerleweb.com
Отредактировано 09.12.2015 17:52 VladD2 . Предыдущая версия .
Re[6]: [Nitra] Пример простого языка вычисляющего выражения
От: novitk США  
Дата: 09.12.15 15:16
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, novitk, Вы писали:


N>>Думал оно будет очевидно. Впрочем мне не сложно набросать полсотни строчек.


_NN>Можно объяснить что означает "~" в ~[Expr] и в f ~ Nil в Scala ?

_NN>
_NN>  def makeOpExpr(p: ~[Expr, List[Expr]]): Expr = p match {
_NN>    case f ~ Nil => f
_NN>    case f ~ l => OpExpr(f, l)
_NN>  }
_NN>


def ~[U](q: ⇒ Parser[U]): Parser[~[T, U]]
A parser combinator for sequential composition.

Грубо говоря есть две сущности: "def ~" и "case class ~". Первое возвращает парсер для второго. Второе по сути обычный двойной тупл, ака пара. Код наверху оптимизация сокращающая уровень вложености.
Re[9]: [Nitra] Пример простого языка вычисляющего выражения
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.12.15 17:45
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Скажем, можно сделать два проекта , чтобы показать расширяемость.


Ты объем работы по ручной реализации не тривиального языка представляешь?

Вот доделаем типизацию Шарпа и Немерла, можно будет сравнить первый с кодом Розлина, а второй с кодом Немерлового компилятора. Заранее могу сказать, что разница будет огромной.

_NN>Вместе с этим снимки экранов , где показана подсветка , сообщения об ошибках и автодополнения.


Может проще прочесть закрепленную в топе статью:
http://rsdn.ru/forum/nemerle/6217398.flat
Автор: VladD2
Дата: 17.10.15

?

Там в конце скриншоты есть.

_NN>Тогда будет легче объяснить почему Nitra делает намного больше чем просто парсит.


Тут вопрос в том пробовал ли человек что-то сам сделать или нет. Если упереться рогом как novitk, то можно постараться не заметить все что угодно.

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

С другой стороны в чем-то он прав. Маппинг напрягает. Но предложение жить на парстри (без отдельного АСТ-а) на практике не канает.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: [Nitra] Пример простого языка вычисляющего выражения
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.12.15 17:51
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Раскрашивает текст.


Не просто раскрашивает, а раскрашивает в зависимости от типов символов. В данном случае ссылки на переменные и переменные можно сделать отдельными цветами.

WH>Подсвечивает ошибки.


Во время правки кода, что немаловажно.

WH>Работает автодополнение.


Еще навигация к определению (к переменным по ссылкам на них) и поиск вхождений.

Так же автоматически поддерживается работа в проекте. Переменные можно разнести по отдельным файлам проекта и все будет работать.

Ну, и главное что ты забыл — это автоматическое восстановление после ошибок. Уверен, что в сколовском варианте этого нет и в помине.

N>>Ты ведь отлично знаешь что это три строчки. Зачем придуриваешься?

WH>Я отлично знаю, что ты это не сделал.

Надеюсь мы товарища дожмем и он сделает свой ужастик по истине монструозным .

WH>>>6)Расширяемость где?

N>>Расширяемость куда?
WH>Куда угодно.
WH>Попробуй добавить новый оператор с новым приоритетом так чтобы твой код не трогать.
WH>Например, он лежит в ДЛЛ, исходники которой ты менять не можешь.

Ага. Это приакольно. У них даже приоритетов операторов нет. Так что вставка любого нового правила создающего новый приоритет приведет к переписыванию грамматики.

N>>Если пример неудачный, сделайте наконец нормальный, который покажет мне нафиг мне сдался все эти ваши мэппинги и прочие прелести. Пока оно не видно.

WH>Сначала этот пример повтори.

+1

Но придумать удачный пример, чтобы он был не примитивным, но и не очень сложным тоже надо.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: [Nitra] Пример простого языка вычисляющего выражения
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.12.15 18:12
Оценка:
Здравствуйте, novitk, Вы писали:

N>Ты ведь отлично знаешь что это три строчки. Зачем придуриваешься?


Придуриваешься, как раз, ты. Раз три строчки, приведи их, а не придуривайся.

За одно скорми своему решению следующие примеры:
1.
var a = b;
var b = a;


2.
var a = b;
var b = c;


3.
var a = b // нет закрывающей ";"
var b = 1;


и расскажи нам, что произошло.

Далее можно добавить в язык еще один оператор и посмотреть на то как легко это сделать. У нас это делается без изменения исходного примера.
syntax module MyExtension
{
  extend syntax Expression
  {
  precedence Sum:
  precedence Pow: // добавляем новую группу приоритетов большую чем Sum и меньшую чем Mul
    | Power = Expression "^" Expression
  precedence Mul: 
  }
}

ast Power : Binary { Result = Math.Pow(Expression1.Result, Expression2.Result); }

map syntax MyExtension.Expression -> Expression
{
  | Power
    {
      Expression1 -> Expression1;
      Expression2 -> Expression2;
    }
}


Можно поместить это дело в тот же проект или в отдельную dll. Таким образом можно расширять другие языки. Например, прикрутить к Скале человеческий синтаксис для грамматик, а не этого уродца, что ты показал.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: [Nitra] Пример простого языка вычисляющего выражения
От: _NN_ www.nemerleweb.com
Дата: 09.12.15 19:13
Оценка:
Здравствуйте, novitk, Вы писали:

N>

N>def ~[U](q: ⇒ Parser[U]): Parser[~[T, U]]
N>A parser combinator for sequential composition.

N>Грубо говоря есть две сущности: "def ~" и "case class ~". Первое возвращает парсер для второго. Второе по сути обычный двойной тупл, ака пара. Код наверху оптимизация сокращающая уровень вложености.

Ясно.
Жаль нельзя указывать имена p: ~[left Expr, right List[Expr]] , т.е. нужно понимать контекст что есть Expr , а что List[Expr].
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[10]: [Nitra] Пример простого языка вычисляющего выражения
От: _NN_ www.nemerleweb.com
Дата: 09.12.15 19:22
Оценка: +2
Здравствуйте, VladD2, Вы писали:

VD>Ты объем работы по ручной реализации не тривиального языка представляешь?

VD>Вот доделаем типизацию Шарпа и Немерла, можно будет сравнить первый с кодом Розлина, а второй с кодом Немерлового компилятора. Заранее могу сказать, что разница будет огромной.
Это конечно интересно , однако людям нужны простые примеры.
Да даже в этом примере можно вынести операции 'Sum' и прочее в отдельный файл и показать расширяемость.

_NN>>Вместе с этим снимки экранов , где показана подсветка , сообщения об ошибках и автодополнения.


VD>Может проще прочесть закрепленную в топе статью:

VD>http://rsdn.ru/forum/nemerle/6217398.flat
Автор: VladD2
Дата: 17.10.15

VD>?
Я имел ввиду это в студии.
Желательно даже с анимацией.

_NN>>Тогда будет легче объяснить почему Nitra делает намного больше чем просто парсит.


VD>Тут вопрос в том пробовал ли человек что-то сам сделать или нет. Если упереться рогом как novitk, то можно постараться не заметить все что угодно.

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

VD>Если же ты попытался реализовать хотя бы самый маленький язычок, но целиком (с выводом вменяемой диагностики, с реализацией поддержки IDE, с заботой о поддержке и развитии), то объяснять особо и не придется ничего.

С таким подходом боюсь ничего не выйдет.
Можно сто раз рассказывать, что Nemerle лучше чем C# , однако человек выберет C# потому что не видит всей картины.
А просто тратить время на проверки ни у кого нет.

Нужно всё разжёвывать и разложить по полочкам.
Тогда и вопросы будут по существу , а не в стиле "чем это лучше".

VD>С другой стороны в чем-то он прав. Маппинг напрягает. Но предложение жить на парстри (без отдельного АСТ-а) на практике не канает.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: [Nitra] Пример простого языка вычисляющего выражения
От: novitk США  
Дата: 09.12.15 19:45
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Придуриваешься, как раз, ты. Раз три строчки, приведи их, а не придуривайся.

VD>За одно скорми своему решению следующие примеры:

твои примеры, расширяемость операторов и прочие шлюхи.
  Скрытый текст
import scala.util.parsing.combinator._

object Main extends JavaTokenParsers {
  class Expr;
  class BinOp(val evalF: (Int, Int) => Int, val expr: Expr);
  def mkBinOp = (new BinOp(_, _)).curried
  val binOpGroups = Seq(
      Seq("*" -> mkBinOp(_*_), "/" -> mkBinOp(_/_)),
      Seq("^^" -> mkBinOp(Math.pow(_, _).toInt)),
      Seq("+" -> mkBinOp(_+_), "+" -> mkBinOp(_+_)))

  case class NumberExpr(num: Int) extends Expr;
  case class VarExpr(name: String) extends Expr;
  case class OpExpr(expr: Expr, subExprs: List[BinOp]) extends Expr;
  class VarDef(val name: String, val expr: Expr)
  
  def makeOpExpr(p: ~[Expr, List[BinOp]]): Expr = p match {
    case f ~ Nil => f
    case f ~ l => OpExpr(f, l)
  }
  def binOpGroupParser(termAbove: Parser[Expr], opGroup: Seq[(String, Expr => BinOp)]): Parser[Expr] = {
    val opGroupParsers = opGroup.map { case (opCode, constr) => opCode ~> termAbove ^^ constr }.reduce(_|_)
    (termAbove ~ rep(opGroupParsers)) ^^ makeOpExpr
  }  

  def factor: Parser[Expr] = wholeNumber ^^ (s => NumberExpr(s.toInt)) | ident ^^ VarExpr | "(" ~> expr <~ ")"
  def expr: Parser[Expr] = binOpGroups.foldLeft(factor)(binOpGroupParser(_, _))
  def varDef: Parser[VarDef] = ("var" ~> ident) ~ ("=" ~> expr <~ ";") ^^ { case n ~ e => new VarDef(n, e) }
  def varDefParseAll(in: CharSequence): ParseResult[VarDef] = parseAll(varDef, in)

  class EvalContext(val vars: Map[String, VarDef]) {
    val results = scala.collection.mutable.Map[String, Int]()
    val evalStack = scala.collection.mutable.Stack[String]()
    def evalVar(name: String): Int =
      {
        if (!results.contains(name)) {
          if (evalStack.contains(name))
            throw new RuntimeException(s"looped $name")
          if (!vars.contains(name))
            throw new RuntimeException(s"undefined $name")
          evalStack.push(name)
          results(name) = evalExpr(vars(name).expr)
        }
        results(name)
      }
    def evalExpr(expr: Expr): Int = expr match {
      case NumberExpr(num) => num
      case VarExpr(name) => evalVar(name)
      case OpExpr(expr, subExprs) => subExprs.foldLeft(evalExpr(expr)) {
        (a, subExpr: BinOp) => subExpr.evalF(a, evalExpr(subExpr.expr))
        }
    }
  }

  def main(args: Array[String]) = {
    val vars: Map[String, VarDef] = Map(args.toSeq.map(varDefParseAll).map {
      pr =>
        {
          val vd = pr.get
          vd.name -> vd
        }
    }: _*)
    val evalCtx = new EvalContext(vars)
    println(evalCtx.evalVar("b"))
  }
}

VD>Например, прикрутить к Скале человеческий синтаксис для грамматик, а не этого уродца, что ты показал.
"Уродец" это субъективно, а вот 50 строчек, Карл, нет.
Re[8]: [Nitra] Пример простого языка вычисляющего выражения
От: novitk США  
Дата: 09.12.15 19:54
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Сначала этот пример повтори.


В соседней ветке.

По остальным пунктам поясню. Я это фрагмент сделал лишь потому, что Влад усомнился в возможности сделать его пример сравнимым количеством кода без Нитры, а не потому что я тебя не уважаю или считаю что Нитра не нужна. Все, горячится не надо.
Re[9]: [Nitra] Пример простого языка вычисляющего выражения
От: WolfHound  
Дата: 09.12.15 20:05
Оценка: +1
Здравствуйте, novitk, Вы писали:

WH>>Сначала этот пример повтори.

N>В соседней ветке.
Часть замечаний ты замазал.
Но большая часть осталась.

А главное код стало понять ещё сложнее.

N>По остальным пунктам поясню. Я это фрагмент сделал лишь потому, что Влад усомнился в возможности сделать его пример сравнимым количеством кода без Нитры, а не потому что я тебя не уважаю или считаю что Нитра не нужна. Все, горячится не надо.

Если тут кто и горячится то это ты.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[11]: [Nitra] Пример простого языка вычисляющего выражения
От: novitk США  
Дата: 09.12.15 20:17
Оценка:
Здравствуйте, _NN_, Вы писали:

VD>>Тут вопрос в том пробовал ли человек что-то сам сделать или нет. Если упереться рогом как novitk, то можно постараться не заметить все что угодно.

_NN>Человек пытается понять почему он должен учить что-то новое.
_NN>Мне кажется , что не хватает сравнений которые покажут, что Nitra таки да умеет то, что другим не под силу или сложно реализовать.

Не совсем так. Я как раз неплохо понимаю, что они делают и как. Просто они претендуют на некоторую универсальность и революционность, которой я не наблюдаю. А как конструктор для Немерле 2 или как оно там теперь называется, проект имеет право на жизнь. На мой вкус переборщили с DSL-ами, но я списываю это на их фанатизм и мой субъективизм.
Re[10]: [Nitra] Пример простого языка вычисляющего выражения
От: novitk США  
Дата: 09.12.15 20:44
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Часть замечаний ты замазал.

Не "замазал", а "исправил". Что за хамская манера?

WH>Но большая часть осталась.

Перечисли. Типизации в этом примере нет. Раскраска и прочая гуйня выведет размер за разумные рамки, но что тут интересного?

WH>А главное код стало понять ещё сложнее.

Перестань. Любой ФПишник сможет поддерживать этот код, тем более что у него сейчас есть нормальная IDE.
Re[12]: [Nitra] Пример простого языка вычисляющего выражения
От: _NN_ www.nemerleweb.com
Дата: 09.12.15 20:45
Оценка:
Здравствуйте, novitk, Вы писали:


N>Не совсем так. Я как раз неплохо понимаю, что они делают и как. Просто они претендуют на некоторую универсальность и революционность, которой я не наблюдаю. А как конструктор для Немерле 2 или как оно там теперь называется, проект имеет право на жизнь. На мой вкус переборщили с DSL-ами, но я списываю это на их фанатизм и мой субъективизм.


А как хочется наблюдать ?
Неужели визуализатора и работы в VS недостаточно ?


http://rsdn.org/article/nitra/Nitra-Ast-and-Symbols-doc-Pics/03000001.png
https://pbs.twimg.com/media/CPq-R9zUcAAlYLB.png:large
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.