duangsuse::Echo
585 subscribers
4.12K photos
118 videos
579 files
6.14K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
Forwarded from Richard Yu
C里面一般是 #define NULL (void*)0 的,C++ 里面 nullptr 转换为指针的时候也是 0。
duangsuse::Echo
慢慢来吧,先写 RangeMap 算…… 🤔
#task 现在我们知道衬衫的价格是十五便士,所以你选择 C 语言,并将国考的答案填涂在显示器上,鏂不 😐

这周到底是有啥好康的东西,呢,又有哪些东西,因为我的时间不够所以不得不暂时没份呢?
感兴趣的朋友可以看这里。

+ 小说《抓周》 Share/Zhuazhou 的修改(订正)和 NumPreety.js
因为作者暂时用不上这本小说了,而且 NumPreety.js 还莫名有点困难(因为作者的数学不好,我还以为现在有改进了呢……)所以暂时就不修改(我一点也不惋惜)
NumPreety.js 是什么呢……

然后我就可以 new Stream(titles).zipWith(titles.withIndex().map(it => fmt(numpreety.hanShow(it.index)) )) ((t, t_no) => t.innerText = t_no)
可是这个把 9 转化成 250 转化成 二百五十 的函数,还有点难写…… 何况我没时间,而且困难的算法对我来说太多了,所以就没多说……

+ Dokuss
Dokuss 的 Byte/Short ZExt 特性是要加上的,只剩下最后一个类,就可以框架式的读写东西了……

+ Parser.kt / Reflex
我就想早点写这个,不过现在看看(Parser.kt 目前有的一点代码其实急需重构,我之前写的时候觉得手酸果然是有原因的,一个该子类的逻辑放错位置了)
我打算拿 Java 重写,也正是因为打算(滚回去)用 Java 的缘故
本来我们 Parser.kt 可是相当优秀的,它是 Kotlin/Common 1.41…… 现在一巴掌打回 Java 8
不过不要紧,我相信为了这一点体积的问题,也不至于会难看非常

+ Montage.py / Badge.dex
montage 也是很有意思但也有点麻烦(主要是,我是第一次写)的 DIP 算法
实际上,每次我实现自己之前设计的那种东西,往往都会浪费很多时间
Badge.dex,就是那个可以用 builder pattern 的 Spannable 快捷方式了
现在想起来,我可以用 Lombok……

+ PL/0 的解析器(和编译器)
前几天看了从 USTC GitHub 分享那拿到的一些资料,和 LLVM Cookbook
我早就想实现一个编译器了
并且,为了实现它,我还特意思考了一整天那个 Lua 的跳转链表,最后终于搞懂了跳转链表是怎么一回事、嵌套内层跳外层还是怎么着,以及它的确需要 loc, succ 两个(而不是两者之一)来构造的事实……
至于那个 bp, sp, lr (一般 bp 上就存储上一个 bp 的 link……)什么的,不用担心我搞不懂这些
存储的层次差需要动态维护,我当然会啊,不就是生成几个循环减法加法……
解析器还要支持『自动处理错误』(镇定原则)…… 这个,我的 Parser.kt 没考虑太多(它只提醒错误,不可能无视错误填上几个 Token 继续,而且 PEG 解析器不存在什么 Terminator……)
if (succ == next.loc) succ = next.succ; fold right 就可以了。
我还想了个『面向对象』 poly(name, Variants, Fields); is(v, type) 宏…… (当然不能面向对象,只是 sum type 一样的而已)

#defnie poly(name, Variants, Fields) \
typedef enum (Variants) name##Type;
typedef union (Fields) Poly##name;
typedef struct { name##Type type; Poly##name unwrap; } (name);

#define is(v, type) (v.type == type)

蛮没用,不过可以充当类似 sealed class 的东西,就是可以用来装 static Token 什么的
比 LLVM Cookbook 里面什么 type id,然后什么 string idVal; int intval; 啊强多了,那还能叫 scanner 模块么。
说心里话,我真的对代码有洁癖,所以我一点点不紧凑的代码也看不下去。

+ Java JNI 体验:TrieTree
因为我个人不经常写 C++(即便我的确是会写的,也会用 CMake, Qt 什么的),所以我还是打算用 C 写
这次我不觉得有时间可以实现了。(更不要说我开始计划的 byteTrie,还 8 bin(『散列』桶) 什么的……)
不过我还是很想把之前 CoolApk 的 liba 再蓐一把,体验一次 JNI 编程。(当然我也设计了很多方便使用的宏和代码风格,很甜)(内存管理么,首先部分程序员 C++ 内存泄漏很正常,其次不是有 shared_ptr, weak_ptr refcount 么

== 下面是真正意义上的骚操作,上周后来的时间我设计的

+ RangeMap,之前想了很久了,说白了就是一个有序表二分查找的简单算法数据结构(只不过之前我不懂得简化,所以一直眼高手低,在外围什么『区间冲突策略』的地方敲打)
显然,如果我们需要一个 Map<Int, V> (我指的是,你需要映射一大堆 key 的情况)的话肯定不能用 HashMap 吧(空间复杂度……)
可是线性查找又很慢
这样就有了省空间省时间的 RangeMap,缺点是因为 Java 的 Collection framework 没有 SortedList(而必须每次更新后,我也不想定义什么 SortedList,有它自己的原因)就必须每次去重新排序,不过基于增量排序算法的话不会有什么困难
排序问题是很经典的列表处理问题,已经有很多很成熟快速优雅的解决方案,在这里我不需要怀疑 Java 平台的能力。

+ DJD (duangsuse's Java Decompiler)
我这几天拿手画出来许多基于我基于 PL/0 处理机的汇编改造,然后又设计了一个能够侦测循环(我的方法是,每个 BasicBlock 我给一个 base,这样我就有机会检查控制流是否反在向跳转)的算法
然后我就有机会,基于抽象执行,(1) 把原来逆记法的二元链、方法调用折叠回表达式 (2) 而且还能提取出基本块

有了基本块就可以在上面进行进一步的模式匹配,然后就可以还原出 if () {} while () {} 这种高级结构了

当初我因为这个算法需要随机访问指令序列所以不能用 Feeder<E> 莫名伤心了很久,不过很不幸的是,(控制流分析过程中)为了能够判断 br 系指令是否跳转到了某个基本块中间(这样就必须 trunc 那个基本块了,因为基本块都是按顺序执行的,里面的指令不能有另外的前驱和后继)
,以及保证算法的优雅性,我必须使用 RangeMap 记录一个 ip (指令指针)位置属于哪个基本块

+ DiffAlgorithm #Algorithm
这个玩意包含两个项目: (1) DiffAlgorithm 的 Java 重写
(2) Java 的『状态机』(就是 onXsInput, onYsInput, onXsEnd, ……) 版本的重写
我都想好算法了,不过现在好像是没时间做了…… (因为事情比较多,而且不管怎么说,实现算法总是费时间)

+ 比较 TypeEqualizer 和传统的 instance check (operation model)
其实这也没啥,就是 TE 比别人『多』一个 toXXX() 转换而已
TypeEqualizer 是面向数值类型进行抽象建模、instance check 是面向操作进行抽象建模

所以他们之间有个明显的区别:如果要支持新的数值类型,则 TypeEqualizer 需要修改的代码少很多
如果需要支持新的操作,instance check 的版本方便不少

+ Trace.kt 没什么,我就是想让你们看看,天才写一遍和臭皮匠断断续续想一天能轻易拉开多大的差距