duangsuse::Echo
首先我们来学习第一个模式,拼接 Uint8Array fun concat(buf0, buf1) { let buf01 = new Uint8Array(buf0.byteLength+buf1.byteLength); buf01.set(buf0, 0); buf01.set(buf1, buf0.byteLength); return buf01; } 注意 buffers = buffer; 那一段的类型正确性: buffer 没有 it.buffer.byteLength? 其实用…
better flat than deep 之所以是一个原则,是因为若不作为原则,它也不是不可替代的选择,例如
较浅的块嵌套层次对好的代码很重要,比如 Promise——把 callback 和 error handling 结合在一起,如果我们用
对于代码来说,一致性也是相当重要的——所以当你开始降低嵌套层次,就会更容易和其它浅嵌套的部分契合一些,也更容易发现可以重构的一些细节。
我们来看看一个更广义的 if:(下文 f() f1() 是对立的两条分支, cont() 是 continued block 的意思)
如果我们用线性指令流来表达:
这种 if/else 的结构没法用 early-return 改写,举个例子:
不过,如果有可能还是得做进一步封装,比如 C++ 里如果 cont() 仅包含对资源的 close(),你就可以用 RAII(resource acquire is actual initialization) 技术,它能够在离开局部作用域 (return, ...) 之前自动回收资源。
if (p) {
f();
}
cont();
当然也可以写成if (!p) return; // 或者 break 之类能够跳过下面的 else branch 的东西但是,语义上条件执行并不能证明
f();
cont();
if (p) f(); 或者 if (!p) { return; } f(); 是唯一的正确选项。较浅的块嵌套层次对好的代码很重要,比如 Promise——把 callback 和 error handling 结合在一起,如果我们用
onOver/onDone 加 if (res.error) else …… 那代码还能看么?对于代码来说,一致性也是相当重要的——所以当你开始降低嵌套层次,就会更容易和其它浅嵌套的部分契合一些,也更容易发现可以重构的一些细节。
我们来看看一个更广义的 if:(下文 f() f1() 是对立的两条分支, cont() 是 continued block 的意思)
if (p) {
f();
} else {
f1();
}
cont(); 如果我们用线性指令流来表达:
(br.not b) a (jmp c) b c或者
(br.if a) b (jmp c) a c其实控制流图上,c 一般被称为 merge block…… 这里就用
cont() 代表了:P这种 if/else 的结构没法用 early-return 改写,举个例子:
if (!p) return; f(); cont();但是 if (!p) return 的 false branch 不包括 cont 就是了,如果 dirty 一点可以随意 jump (goto),但不建议。
(test p) (br.not return) (call f) (call cont) return
if (p) f(); else f1();
(test p) (br.not f1) (call f) (jmp cont) f1 (call f1) cont
不过,如果有可能还是得做进一步封装,比如 C++ 里如果 cont() 仅包含对资源的 close(),你就可以用 RAII(resource acquire is actual initialization) 技术,它能够在离开局部作用域 (return, ...) 之前自动回收资源。
#phonetic https://zh.wikipedia.org/wiki/%E5%85%83%E9%9F%B3 vowel 是『元音』的意思 🤔
Wikipedia
元音
母音(vowel)又称母音,是音位的一种,与子音(又稱子音)相对。元音是在发音过程中由气流通过口腔而不受阻碍发出的音。发元音时,气流从肺部通过声门冲击声带,使声带发出均匀震动,然后震音气流不受阻碍地通过口腔、鼻腔,通过舌、唇的调节而发出不同的声音。发元音时声带必然震动,这叫做浊音。也有的语言发元音时声带不振动,发出清元音(voiceless vowel)。元音并非在所有的语言中都与元音字母一一对应,一些元音字母的组合也可以表示特殊的元音,比如汉语中的某些複韵母;某些语言中一些元音字母在某些情况下不发音,如法语中元音字母“e”在词末。
https://github.com/dhakehurst/net.akehurst.language/blob/efafa3e57f89ddea2f81ca3080121f2e70cce9e0/net.akehurst.language/agl-processor/src/commonMain/kotlin/processor/Agl.kt#L57
草,学到了,原来 Kotlin/Multiplatform 重载要这么用
草,学到了,原来 Kotlin/Multiplatform 重载要这么用
GitHub
dhakehurst/net.akehurst.language
Generic Language (DSL) support for kotlin multiplatform (parser, syntax-analyser, formatter, processor, etc) - dhakehurst/net.akehurst.language
https://github.com/dhakehurst/net.akehurst.language/blob/efafa3e57f89ddea2f81ca3080121f2e70cce9e0/net.akehurst.language/agl-processor/src/commonMain/kotlin/processor/LanguageProcessorDefault.kt#L94
草,觉得可以学习一下,自带补齐方法
草,觉得可以学习一下,自带补齐方法
override fun expectedAt(goalRuleName: String, inputText: CharSequence, position: Int, desiredDepth: Int): List<CompletionItem>
override fun expectedAt(inputText: CharSequence, position: Int, desiredDepth: Int): List<CompletionItem>GitHub
dhakehurst/net.akehurst.language
Generic Language (DSL) support for kotlin multiplatform (parser, syntax-analyser, formatter, processor, etc) - dhakehurst/net.akehurst.language
https://github.com/dhakehurst/net.akehurst.language/blob/efafa3e57f89ddea2f81ca3080121f2e70cce9e0/net.akehurst.language/agl-processor/src/commonMain/kotlin/parser/scannerless/ScannerlessParser.kt#L130
看到这里我被宏大的一个
看到这里我被宏大的一个
fun 给震惊到了,忽然想到为什么 ParserKt 不能 lazy 处理 SourceLocation 的问题,才记起 ParserKt 的输入是纯 Feed<T> 流,不可能回溯……GitHub
dhakehurst/net.akehurst.language
Generic Language (DSL) support for kotlin multiplatform (parser, syntax-analyser, formatter, processor, etc) - dhakehurst/net.akehurst.language
https://github.com/dhakehurst/net.akehurst.language/blob/efafa3e57f89ddea2f81ca3080121f2e70cce9e0/net.akehurst.language/agl-processor/src/commonMain/kotlin/parser/scannerless/InputFromCharSequence.kt
看到这个“新”Parser lib 我就知道 ParserKt 的设计是有多不容易了……
遇到 parser 既没有 lexer/parser 又没有 TERMINAL/NON-TERMINAL 还不强调scannerless因为它本身概念上就不存在scanner这…… 虽然和 Haskell 系的 Parserc 差不多,但更 Kotlin 一些
如今又得重构了……
看到这个“新”Parser lib 我就知道 ParserKt 的设计是有多不容易了……
遇到 parser 既没有 lexer/parser 又没有 TERMINAL/NON-TERMINAL 还不强调scannerless因为它本身概念上就不存在scanner这…… 虽然和 Haskell 系的 Parserc 差不多,但更 Kotlin 一些
如今又得重构了……
GitHub
dhakehurst/net.akehurst.language
Generic Language (DSL) support for kotlin multiplatform (parser, syntax-analyser, formatter, processor, etc) - dhakehurst/net.akehurst.language
https://github.com/dhakehurst/net.akehurst.kotlin.kt2ts #Kotlin #TypeScript #dev #tools 🤔 第一次知道可以这么干
看来 ParserKt 的 Kotlin/JS document 要靠这个人的实践经验了
看来 ParserKt 的 Kotlin/JS document 要靠这个人的实践经验了
GitHub
GitHub - dhakehurst/net.akehurst.kotlin.kt2ts: Typescript definition file generator for kotlin (js) classes
Typescript definition file generator for kotlin (js) classes - dhakehurst/net.akehurst.kotlin.kt2ts
https://github.com/dhakehurst/net.akehurst.language/blob/efafa3e57f89ddea2f81ca3080121f2e70cce9e0/net.akehurst.language/agl-processor/src/commonMain/kotlin/parser/sppt/SharedPackedParseTreeDefault.kt
这一系列操作…… 很算法啊
一般类似 ANTLR 一样的工具也会有 rewrite/action 的选择吧,可这个几乎只有 SPPT(shared packed parse tree) 一样……
ParserKt 是纯递归下降解析组合子,所以没有 YaCC 系的 Parser-Tree 说法,只有内部递归的调用树和临时的 Fold 对象,没有这种……
这一系列操作…… 很算法啊
一般类似 ANTLR 一样的工具也会有 rewrite/action 的选择吧,可这个几乎只有 SPPT(shared packed parse tree) 一样……
ParserKt 是纯递归下降解析组合子,所以没有 YaCC 系的 Parser-Tree 说法,只有内部递归的调用树和临时的 Fold 对象,没有这种……
GitHub
dhakehurst/net.akehurst.language
Generic Language (DSL) support for kotlin multiplatform (parser, syntax-analyser, formatter, processor, etc) - dhakehurst/net.akehurst.language