Yogurt
это Data Flow Diagram
Andrew
А чем рендеришь?
Andrew
Сам или либой?
Yogurt
я тут почти Lustre начал писать, но вовремя остановился
Yogurt
Сам или либой?
https://dreampuf.github.io/GraphvizOnline
Andrew
Ага, юзал такое)
Yogurt
я генерю текст, а дальше сую его Graphviz'у
Yogurt
Yogurt
но мне захотелось так почему-то
Yogurt
хотя возможно если юзать AST, то решится моя проблема с боксингом и вот этим всем
Ayrat
потому что тебе вообще похеру чо там писать внутри
Yogurt
Блин, вот ты это сказал, мне теперь хочется переписать это все к завтра и выспаться тоже хочется в прочем
Yogurt
meh
Ayrat
Блин, вот ты это сказал, мне теперь хочется переписать это все к завтра и выспаться тоже хочется в прочем
type FlowBuilder() = member __.Return _ = failwith "mock" member __.For _ = failwith "mock" member __.Combine _ = failwith "mock" member __.Delay _ = failwith "mock" member __.Quote _ = failwith "mock" member __.Run x : Quotations.Expr = x let flow = FlowBuilder() let a = flow { for _i = 1 to 10 do return 1 return 1 } и далее немного рекурсивного обхода AST с преобразованием во что хочешь. Хоть в брейнфак
Yogurt
а эта шутка ж грохнется, верно?
Ayrat
бонусом - не надо вообще писать тела кастомных операторов
Ayrat
она ж не выполнится никогда, это ж ВЫРАЖЕНИЕ
Yogurt
но у тебя там for, а он failwith
Yogurt
нет?
Ayrat
Yogurt
хм
Ayrat
выражение грохнется если его вычислить. Ты его не вычисляешь
Yogurt
а мне потом и вычислять нужно, между тем
Yogurt
Yogurt
руками это как-то не хочется
Ayrat
это ж выражение
Ayrat
захотел, проевалуейтил
Yogurt
я теперь запутался
Ayrat
захотел, пересобрал
Yogurt
ладно, завтра потыкаю
Yogurt
спасибо
Ayrat
окей, стой. вот тебе перед сном задачка
Yogurt
отлично, кажется я опять в какой-то секте
Ayrat
let e: Quotations.Expr = <@@ failwith "mock" @@>
Ayrat
почему оно не упадёт
Yogurt
не, ну тут экспрешен
Yogurt
я не такой глупенький
Ayrat
ну бля, там весь flow { } вернёт такой же експрешн
Yogurt
ты не понял, в чем я запутался)
Ayrat
видимо не понял
Yogurt
я понимаю разницу между вычислением экспрешена и его АСД
Ayrat
ок. вот такой flow let a = flow { return 1 } вернёт это val a : Quotations.Expr = Call (Some (ValueWithName (FSI_0008+FlowBuilder, builder@)), Delay, [Lambda (unitVar, Call (Some (ValueWithName (FSI_0008+FlowBuilder, builder@)), Return, [Value (1)]))])
Yogurt
у меня был немного в другом месте вопросы возникли
Yogurt
но нужно будет завтра потыкать и разобраться
Ayrat
как видишь, у меня return реализован через failwith
Ayrat
но ничего не падает, т.к. никого не волнует как у меня там ретурн реализован. Ну т.е. я могу через него выполнить выражение, но не хочу. Я его лучше потом пересоберу в... JS
Ayrat
или в асемблер сразу
Yogurt
ну вот я в этом моменте и запутался, нужно будет почитать доки внимательнее
Yogurt
слушай, а как в этот экспрешен значения передать?
Yogurt
для вызова
Ayrat
слушай, а как в этот экспрешен значения передать?
так эта, ты пишешь эти эксрешны своими вызовами
Ayrat
ну вот всё что ты сверху писал
Yogurt
ну это да
Yogurt
но допустим я напишу
Yogurt
return a
Ayrat
ну значит у тебя a где-то есть
Yogurt
а я не могу просто его как-то замокать?
Ayrat
можешь
Ayrat
я так делал когда писал компилятор на F# аля lisp и мне нужна была возможность заменять любые символы, как это умет делать lisp
Ayrat
F# пидор хочет иметь эти символы объявленные
Ayrat
да, можно просто всё что угодно мокать через failwith
Ayrat
если ты это потом просто в экспрешн превращаешь для перекомпиляции
Yogurt
ну мне нужно на ходу это мокать
Yogurt
хм-хм
Ayrat
на ходу. хм хм. тогда работай по правилам F#
Ayrat
ну то есть откуда-то это a берётся же
Ayrat
просто так return a, звучит странно
Yogurt
ну я прикидываю, как подобную конструкцию переписать
Ayrat
ну накидать пустых билдеров с кастомными операторами (пустыми) несложно
Ayrat
явно быстрее чем ты делал
Ayrat
а вот дальше интереснее, надо из этого АСТ собрать что ты там хочешь. текст
Ayrat
методы обхода AST могут выглядеть интересно: let (|MemberName|_|) name (SynMemberDefn.Member (mmbrDef,_)) = let (SynBinding.Binding (_,_,_,_,_,_,_,pat,_,_,_,_)) = mmbrDef match pat with | (SynPat.LongIdent (LongIdentWithDots ([id],_),_,_,_,_,_)) -> if id.idText = name then Some MemberName else None | _ -> None let (|IsStatic|_|) (SynMemberDefn.Member (mmbrDef,_)) = let (SynBinding.Binding (_,_,_,_,_,_,valData,_,_,_,_,_)) = mmbrDef let (SynValData.SynValData (flags,_,_)) = valData if flags.IsSome then if flags.Value.IsInstance then None else Some IsStatic else None let (|Type|) (SynTypeDefn.TypeDefn (info,_,members,_)) = let (SynComponentInfo.ComponentInfo (_,_,_,[ident],_,_,_,_)) = info Type (ident.idText, members)
Ayrat
ну я прикидываю, как подобную конструкцию переписать
переписал. https://gist.github.com/Szer/1462b78921afb4c9e54222ec29e33086
Yogurt
не, ну этот момент ясен
Ayrat
А дальше рекурсивную функцию обхода с аккумулятором в виде стринг билдера например куда ты кладёшь свою мега строку. Ну или промежуточный AST для себя придумай изявый