duangsuse::Echo
具体步骤: #sysadmin #Windows #Android 第一次: 控制面板-系统-系统属性 (SystemPropertiesAdvanced.exe) 改环境变量 PATH 前置 C:\msys2\usr\bin\ 每次开机: 或者用 set PATH=%PATH%;(上文本) 在 ipconfig ,找当前 以太网适配器 里的 默认网关 ,框选一次复制。 set RNDIS_HOST=(右键粘贴) 每次: 在 Android Termux (接收方)上 nc -l -p 12345…
嗯…… 今天终于知道 ncat host port 不止可以 sendto() ,也能 recvfrom() 了
而且,这个送信必须是由手机开
好像并不能连接到电脑端 ip addr iface 给的那个 inet 地址,但是网关(即开USB绑定共享的,手机电脑都易拿到地址)就可以联通,非常生草
当然如果只是这样就太没意思了,我写了个基于 #Python + socket/sl4a 的剪贴板共享脚本: #code #project
而且,这个送信必须是由手机开
nc -l
,如果是从手机送到电脑,那也是在电脑上 recvfrom() ,不能反向开服 bind() 监听,只能是在网关(手机)上。好像并不能连接到电脑端 ip addr iface 给的那个 inet 地址,但是网关(即开USB绑定共享的,手机电脑都易拿到地址)就可以联通,非常生草
当然如果只是这样就太没意思了,我写了个基于 #Python + socket/sl4a 的剪贴板共享脚本: #code #project
from socket import socket
from androidhelper import Android
sl4a = Android()
def serveTcp(saddr):
sd = socket()
sd.bind(saddr); sd.listen(1)
while True:
try: print("."); acceptReq(sd.accept()[0])
except IndexError: pass
def acceptReq(conn):
seqPrefixBytes = iter(lambda: conn.recv(1), ':'.encode())
act = chr(conn.recv(1)[0])
if act == '-': conn.send(sl4a.getClipboard().result.encode())
elif act == '+':
num = int(b"".join(seqPrefixBytes))
sl4a.setClipboard(conn.recv(num).decode())
serveTcp(("", 12345))
GitHub
qpysl4a/doc/en/APIs.rst at master · qpython-android/qpysl4a
QPySL4A is the Script Layer for Android (SL4A) Library for QPython. It allows you to program to drive Android to work. - qpython-android/qpysl4a
duangsuse::Echo
https://github.com/ice1000/arend-language-server/blob/88dd2e94ea7ae564a743d349b93487dd5aa4b5f8/src/main/kotlin/server.kt 草,原来冰封那么厉害也没有写自己的 Argument Parser... 我还以为函数式爱好者都痛恨 (org.apache.commons.cli) 需要 (opt as Options).addOption(Option.builder("i").build())…
#Java #Kotlin #GitHub #project #suggest 评论一下我之前开发的 ArgParser 😂
是个好东西,对命令行参数的建模也很好,就是,应为 addHelpVerCommand 不对,这个是显示子命令树结构的... 那个 -h -v 的也应该有,但可以另加
还有,生成命令行补全的代码也该加
存在的一些问题,包括强类型约束过于严苛(为此还有 ArgParser4~1 的泛型), 以及 subcommand&formatter 参数实现未测试的瑕疵("All tests passed" 但它太复杂了 我不敢保证) 😂
(Apache: 你敢和我比?🌚 有它强大吗? 还有
谈谈
我们的解析器是流式的(因为框架很重视不同甜度需求的复用性,它是一层层建起来的,其根基
所以实践上
一个即得的技巧是,记住上一次读的 list ,然后读 dst 时从 vararg items 里“偷” 一个项目出来,末尾有 N 项就“偷” N 次。
另一个技巧是寻找 vararg items 的 position ,解析时直接就算 srcs 有多少项,取了跳过 (有点类似 Lua 虚拟机对不定长参函数的编码方法,但这种方法可以做成支持多个 vararg 的不知道有啥样用)
ArgParser 的解决方法比较骚,因为它支持 unparse (backRun) ,换句话说它可以先用无问题的 [dst] [src...] 解析(通过动态构造解析器),再把整个 items 拼了转过来
没有那么高级,其实只需要把参数输入和解析结果,共反转两次就够了 🌝(不过依然要用到 backRun 😂
这是为什么呢? 因为我们必须先检查参数是否合法,并且取得其中 item arg 部分…… 但如果你的代码没有用到 reverse, 相应
是个好东西,对命令行参数的建模也很好,就是
addHelpSubCommand()
这样的帮助函数,没有考虑到应用的需要还有,生成命令行补全的代码也该加
存在的一些问题,包括强类型约束过于严苛(为此还有 ArgParser4~1 的泛型), 以及 subcommand&formatter 参数实现未测试的瑕疵("All tests passed" 但它太复杂了 我不敢保证) 😂
(Apache: 你敢和我比?🌚 有它强大吗? 还有
"<!s #d"
的 fmtstr...)谈谈
"both [src...] [dst] and [dst] [src...] are supported"
是怎么实现的吧我们的解析器是流式的(因为框架很重视不同甜度需求的复用性,它是一层层建起来的,其根基
SwitchParser
就是基于状态机构建输出数据结构的)所以实践上
[src...] dst
里你怎么知道 srcs 不能把最后一个 dst 也解析了(看起来 dst 也可以理解为 src 的一项啊) 🤔? Py 的 argparse 也支持这样(但我不清楚它的架构细节),总之没有一些较 dirty 的 hack 是比较不容易的。一个即得的技巧是,记住上一次读的 list ,然后读 dst 时从 vararg items 里“偷” 一个项目出来,末尾有 N 项就“偷” N 次。
另一个技巧是寻找 vararg items 的 position ,解析时直接就算 srcs 有多少项,取了跳过 (有点类似 Lua 虚拟机对不定长参函数的编码方法,但这种方法可以做成支持多个 vararg 的
ArgParser 的解决方法比较骚,
没有那么高级,其实只需要把参数输入和解析结果,共反转两次就够了 🌝(不过依然要用到 backRun 😂
这是为什么呢? 因为我们必须先检查参数是否合法,并且取得其中 item arg 部分…… 但如果你的代码没有用到 reverse, 相应
backRun
逻辑是不需要的(只是即便这样 progurad 等工具也不知道它可以 delete 掉 (xGitHub
ParserKt/ArgParser
Simplified argument parser / multiplatform CLI for Kotlin ~500 LoC - ParserKt/ArgParser
duangsuse::Echo
https://github.com/ice1000/jimgui/blob/master/core/test/org/ice1000/jimgui/tests/Demo.java ... 看了以后我对冰封哥的审美有点失望 虽然这只是一个直接的重写,我看出 jimgui 没有比 ImGui 本身更高的封装,它仅以 add container 的方式暴露了 tree ,这不符合之前写 TkGUI 时我的期望。 这里也有一个 initNewFrame + listen keyEvent & StringBuilder…
吃饭的路上(最近有点劳累过度了,思量着 ANSI BadApple 赶紧结束休息几天吧),谈到所谓“优雅性”,想了一下 ParserKt 新 LexerFeed 的问题,感觉很 complicated ,流对象的各种属性真的不好办
首先是说这个给冰封提到底有没有意义的问题(毕竟 PM 冰封是一个比较要心理准备的事情,心理难度比与 Python 红姐、九月姐 谈笑风生不低多少),最后结论是有。
虽然 jimgui 的本意未必是做“定义式”的 GUI 框架,更像是学习 JNI 设计,而且 Kotlin wrapper 很可能会有好的接口,技术交流也是不应有太多压力的。
TkGUI 的代码生成方法利用了 Python 无编译期/运行期,虚拟机相关组件基本可用的动态性,以及动态类型;很难(或者说意义不大)移植到 Java ,但我的本意是 GUI 可以这么写, ImGui 的做法可以说是业界惯例(就我的观察, GTK, Wx 的大部分封装不需要为子控件选择 parent, 但没有一个支持树形代码定义一个视图,即便其语言有足够表现力),Java 的 Swing Frame,Panel 和 Fx Stage,Scene,Group 都必须用 mutate 对象的方法「创建」模板化的视图树(当然这是过程式的自然映照,无可厚非), Qt 和 C#, VB 有 uic 这样的 code generator ;而 TkGUI 的 way 更像是 parser combinator 那样,尽可能少用外部工具,直接在语言里组合。
这个 way 就是一句话,“优美的代码能直观地反映它所处理数据的结构”,程序结构和数据结构相互照应、谐调统一,虽然会有额外开销,但一件事情只有你重视了才能找到各方面的最优解决办法,否则就永远只是传说。
再谈 ParserKt 的问题,其实最初版本相较于一些同类已经可以算是优雅了(当然离我想的还更远)
几个月前的重计划里包含了“削除 Parser 里 Lexer 相关代码”的改动,可以说是解决了我心头一厌(很多 PEG 生成器都逃不开跳空格注释的问题,要么然写文法里,要么然走 lexer/parser 的老路,要么然可配置性不够好,这是比较草的,因为我觉得在 a b c “按顺序”模式里默认插跳空格的逻辑是接近正解的)
具体实现还算好, Lexer/Parser 的区分、 Token 而非 Char 流的存在,核心原因是空格和注释对语法结构是无效的——最好能无视,免得解析器混杂
scannerless parser 很好,但跳空格其实有更容易的解决方法——为 Input stream 添加 filter ,到底还是 java 那一套自由组合的 stream 最好,连 skipped whitespaces 以及 AST element spans 它都可以往
核心思想容易,实现上也有些问题—— Lexer 和 parser 在最近的语言里越来越模糊了,你可以看到 KotlinLexer 里会处理一些嵌套问题(就需要 push/pop state number 了),而且
这么做势必造成计算力的浪费(分词器和解析器对同一份数据做了类似的动作——检查它的嵌套结构),以及编程的冗余、重复代码,是应该努力避免的。
解析器与“分词器”之间的交流,显然是 parser combinator 的优势——它们的结构对程序员是完全透明的,可以自由定义、随意组合,让 Parser 去驱动其输入流上的 Lexer ,告诉分词器现在是什么状态,需不需要跳空格(例如 "" 里就不能跳);分词器是一个针对
有的观众就会问了:这么好的方法,比你高到不知哪里去的聪明人可多了,怎么就你想出来?
首先,不能说是没人想,要看编程实践怎么用、怎么组合这些技巧,不是说你去做了,效果就真的能像想象的那样好
其次,如果你没把代码重写 9遍,也容易被 Lexer/parser 和 scannerless 的那群既有实践误导,以为必须有 tokenizer ,或者流只能是一层,不能有“滤过”操作的
如果被动性[2](非阻塞,要不然无法共享 string 等词法的定义)以及 Parser 对其的主动性(传递在解析词条类型号)不能被保证, 许多人对输入字符序列的抽象不够灵活(万恶之源),使得他们不能够发现这一点。 (所以你在编程的时候,记得重复的少写一点、稀奇的功能特性多写一点,说不定还能帮助你对程序模型整体的理解)
(这种设计也很好的发扬了 ParserKt 的 one-pass 设计,而 C 系语言 // /* 注释与除号的区分早有给
但这个封装有很大问题—— ParserKt 最初只有
尽管这是根基(SliceFeed, Iterator/ReaderFeed 子类),它也是不切实际的,所以很快有了
而那些接收 Input 的 Input ,就只能用一个代理(delegate)类
如果说你组织流嵌套的方法是手工的,应该不需要滥用多态去做“动态类型”,又或者是自动的——真的到那种“可组合”的地步吗?
最后我觉得,还是做则不能打破 Lexer 需求 Input (SourceLocated) 的类型, 还是取消这样的限制吧…… 真不知该怎样解决这问题 #parser #parsing #learn #Kotlin #project #suggest
[^1] 现在我更倾向
isCompleteRead 是重新建模的(结果存逆波兰栈的)算符链解析器需要的,在非 complete read 时,可以像 Lua 一样直接进行简单的常量折叠,否则不仅不能折叠,还要存语法元素行号、前部空格等(重现原文所需的)信息
[^2] 其实我理解错了,这也是因为 LexerFeed 最开始是能自动识别底层输入的状态机,上级请求字符时肯定是要 blocking consume 直到非空格字符的,所谓非阻塞是因为对非空格单个字符它照样要处理状态转移;现在我倾向把它做成“能暂时屏蔽的自动 ws skip”一些,因为这才能真正统一复用文法/词法规则 ,虽然那样就没有花里胡哨的
首先是说这个给冰封提到底有没有意义的问题(毕竟 PM 冰封是一个比较要心理准备的事情,心理难度比与 Python 红姐、九月姐 谈笑风生不低多少),最后结论是有。
虽然 jimgui 的本意未必是做“定义式”的 GUI 框架,更像是学习 JNI 设计,而且 Kotlin wrapper 很可能会有好的接口,技术交流也是不应有太多压力的。
TkGUI 的代码生成方法利用了 Python 无编译期/运行期,虚拟机相关组件基本可用的动态性,以及动态类型;很难(或者说意义不大)移植到 Java ,但我的本意是 GUI 可以这么写, ImGui 的做法可以说是业界惯例(就我的观察, GTK, Wx 的大部分封装不需要为子控件选择 parent, 但没有一个支持树形代码定义一个视图,即便其语言有足够表现力),Java 的 Swing Frame,Panel 和 Fx Stage,Scene,Group 都必须用 mutate 对象的方法「创建」模板化的视图树(当然这是过程式的自然映照,无可厚非), Qt 和 C#, VB 有 uic 这样的 code generator ;而 TkGUI 的 way 更像是 parser combinator 那样,尽可能少用外部工具,直接在语言里组合。
这个 way 就是一句话,“优美的代码能直观地反映它所处理数据的结构”,程序结构和数据结构相互照应、谐调统一,虽然会有额外开销,但一件事情只有你重视了才能找到各方面的最优解决办法,否则就永远只是传说。
再谈 ParserKt 的问题,其实最初版本相较于一些同类已经可以算是优雅了(当然离我想的还更远)
几个月前的重计划里包含了“削除 Parser 里 Lexer 相关代码”的改动,可以说是解决了我心头一厌(很多 PEG 生成器都逃不开跳空格注释的问题,要么然写文法里,要么然走 lexer/parser 的老路,要么然可配置性不够好,这是比较草的,因为我觉得在 a b c “按顺序”模式里默认插跳空格的逻辑是接近正解的)
具体实现还算好, Lexer/Parser 的区分、 Token 而非 Char 流的存在,核心原因是空格和注释对语法结构是无效的——最好能无视,免得解析器混杂
scannerless parser 很好,但跳空格其实有更容易的解决方法——为 Input stream 添加 filter ,到底还是 java 那一套自由组合的 stream 最好,连 skipped whitespaces 以及 AST element spans 它都可以往
Map<K,V>
存储好了,这就同时解决了 AST data class 不好写的问题,在不必使用这些信息时,也提升了性能,就从根源上解决了许多联带(代码复用、类型冗余和构造器隐式参数、分词解析器如何相互协调的)问题。核心思想容易,实现上也有些问题—— Lexer 和 parser 在最近的语言里越来越模糊了,你可以看到 KotlinLexer 里会处理一些嵌套问题(就需要 push/pop state number 了),而且
>=
与 fun():P<T>=
的区分也使得它必须识别一些本该由文法处理的模式——在过去这是不可想象的,C 的词法规则相当简单这么做势必造成计算力的浪费(分词器和解析器对同一份数据做了类似的动作——检查它的嵌套结构),以及编程的冗余、重复代码,是应该努力避免的。
解析器与“分词器”之间的交流,显然是 parser combinator 的优势——它们的结构对程序员是完全透明的,可以自由定义、随意组合,让 Parser 去驱动其输入流上的 Lexer ,告诉分词器现在是什么状态,需不需要跳空格(例如 "" 里就不能跳);分词器是一个针对
Feed
流的状态机,本身也是一个 Feed
,而 onChar
的时候被动进行状态转移,就可以 filter 掉那些解析器不想看的字符,同时也能选择性地保留(如语法高亮) 的数据,一举多得。有的观众就会问了:这么好的方法,比你高到不知哪里去的聪明人可多了,怎么就你想出来?
首先,不能说是没人想,要看编程实践怎么用、怎么组合这些技巧,不是说你去做了,效果就真的能像想象的那样好
其次,如果你没把代码重写 9遍,也容易被 Lexer/parser 和 scannerless 的那群既有实践误导,以为必须有 tokenizer ,或者流只能是一层,不能有“滤过”操作的
如果
LexerFeed
的(这种设计也很好的发扬了 ParserKt 的 one-pass 设计,而 C 系语言 // /* 注释与除号的区分早有给
InfixPattern
扫描操作符的 TriePattern
专定子类可轻易完成,PKT 的组合性不加盖的)但这个封装有很大问题—— ParserKt 最初只有
Feed { val peek; fun consume() }
,不像一些 nextChar()
或 curChar()
数据视口不一致、命名迷惑的框架,它的流模型只允许程序员着眼一项(最本质的问题),结束时抛 Feed.End
异常尽管这是根基(SliceFeed, Iterator/ReaderFeed 子类),它也是不切实际的,所以很快有了
Input(s: Feed): Feed, SourceLocated, ErrorHandler
[1],以及一大堆 Feed
上试着 (this as Input)
的扩展函数,允许解析器带行号,尽量减小开销(统计行号信息是要在 Char 输入上,而一些输入根本无需 Input 的一些成员)而那些接收 Input 的 Input ,就只能用一个代理(delegate)类
Input.By
去 proxy 这 underlying stream 实现的一些特性,这种问题严重后有点像“责任链”的字面含义——不断尝试 unwrap 一个 (可能是Input的)Feed ,寻找某个 trait 的实现者。如果说你组织流嵌套的方法是手工的,应该不需要滥用多态去做“动态类型”,又或者是自动的——真的到那种“可组合”的地步吗?
最后我觉得,还是做
LexerInput(s:Input): Input.By
比较好,这样 LexerInput(Input(s=SliceFeed(Slice("wtf") )))
这样的二层就会成为必要的组合法,如果需要其他层,[^1] 现在我更倾向
Input: Feed, FeedControl, SourceLocated { val states:Map<String,Any>; val onError; val isCompleteRead:Boolean }
isCompleteRead 是重新建模的(结果存逆波兰栈的)算符链解析器需要的,在非 complete read 时,可以像 Lua 一样直接进行简单的常量折叠,否则不仅不能折叠,还要存语法元素行号、前部空格等(重现原文所需的)信息
[^2] 其实我理解错了,这也是因为 LexerFeed 最开始是能自动识别底层输入的状态机,上级请求字符时肯定是要 blocking consume 直到非空格字符的,所谓非阻塞是因为对非空格单个字符它照样要处理状态转移;现在我倾向把它做成“能暂时屏蔽的自动 ws skip”一些,因为这才能真正统一复用文法/词法规则 ,虽然那样就没有花里胡哨的
List<Triple<Char,Int,Int>>
了(毕竟有效性在那)GitHub
ParserKt/ParserKt
Naive one-pass recursive descent, scannerless parser framework for Kotlin - ParserKt/ParserKt
Forwarded from mivik::channels::tech
#gist #string #combinatorics_of_strings #project
计算所有长度为 n 的字符串的自相关位向量(Autocorrelation)
https://gist.github.com/Mivik/6e0459afe6691bce2659e1eaa5141390
没有注释的话只有短短 60 行,并且没有刻意压行,比 某些人 写的 1000 多行版本好多了(写那个的貌似是个学院派,代码里充斥着完全没法编译的怪异头文件以及鬼畜的码风...)
灵感来自于 这篇论文
计算所有长度为 n 的字符串的自相关位向量(Autocorrelation)
https://gist.github.com/Mivik/6e0459afe6691bce2659e1eaa5141390
没有注释的话只有短短 60 行,并且没有刻意压行,比 某些人 写的 1000 多行版本好多了(写那个的貌似是个学院派,代码里充斥着完全没法编译的怪异头文件以及鬼畜的码风...)
灵感来自于 这篇论文
Gist
Enumeration of autocorrelations of length n
Enumeration of autocorrelations of length n. GitHub Gist: instantly share code, notes, and snippets.
mivik::channels::tech
#gist #string #combinatorics_of_strings #project 计算所有长度为 n 的字符串的自相关位向量(Autocorrelation) https://gist.github.com/Mivik/6e0459afe6691bce2659e1eaa5141390 没有注释的话只有短短 60 行,并且没有刻意压行,比 某些人 写的 1000 多行版本好多了(写那个的貌似是个学院派,代码里充斥着完全没法编译的怪异头文件以及鬼畜的码风...) 灵感来自于 这篇论文
https://tttttt.me/mivik_channel_tech/28 #algorithm #math 后续
OEIS 即在线数列维基, string combination
Mivik 是第一次提交页面,出了一点小插曲,估计会 approve (一说已收但又改 editing 了)。今早的事 表示观望👌。
OEIS 即在线数列维基, string combination
Mivik 是第一次提交页面,出了一点小插曲,估计会 approve (一说已收但又改 editing 了)。今早的事 表示观望👌。
Telegram
mivik::channels::tech
#gist #string #combinatorics_of_string #project
计算所有长度为 n 的二进制字符串(实际上字符集大小可以任意)的本质不同子串(非空)个数之和,n <= 60 时可以在大概五分钟内出结果(主要是需要高精度计算,只求模意义下的值的话会块很多)
https://gist.github.com/Mivik/15fd4b903007fc25a9cd866e27337ca3
顺便提交了人生第一份 OEIS 条目:https://oeis.org/draft/A340885
计算所有长度为 n 的二进制字符串(实际上字符集大小可以任意)的本质不同子串(非空)个数之和,n <= 60 时可以在大概五分钟内出结果(主要是需要高精度计算,只求模意义下的值的话会块很多)
https://gist.github.com/Mivik/15fd4b903007fc25a9cd866e27337ca3
顺便提交了人生第一份 OEIS 条目:https://oeis.org/draft/A340885
作为本领域的频道主动苏当然也会作总结。#plt 😋
当然,我现在非常重视实践能力以及同代码量应用范畴的最大化,可能会希望编译器不只能做单纯/直白的一种结构转换,而能带有更多边角信息(行号 等)的复用,从这点来说也必须向大佬学习(开发了 ImGui binding)。
「当我们谈编程语言,实际是在讨论很多门相对独立的语言」
谈语言除了好看与否、红火与否、高大上与否,当然离不开『语言工具』,如构筑并管理『语法树』图结构的『解析器』(其亦可同时实现代码高亮)、做代码生成转化的『编译器』,以及提供(sizeof 等)信息和静态断言的类型检查器,不然就虚无缥缈了。
一般编程语言构造除了(可能的)解决领域应用痛点,模块化(易用于解决大型问题)、类型安全(尽早地保证正确性和性能)、表达式(用于描述计算) 是它的必须;举了个例子, #Kotlin 的
他提到,『宏(macro)』作为编译期能展开 减少冗余代码量的特性,以及「类型与表达式语言更亲近」的事实(Kotlin 对执行中断类型
「相同类型的表达式互换不影响 well-typedness」
“程序可以有无限个、类型在大多数系统下也是有无限种。
数学上讨论无限大的对象(如无穷数列)的时候往往会涉及对这个对象的结构找有限的、被重复的规律,所以我们也对程序找了规律。
我们『构造』程序和类型的手段是有限的——比如在 C 语言里面,那些值类型就是几个单独的类型,然后我们能用结构体(struct)、union、数组(T[])、指针(T*)等功能从已有的类型构造新类型。(enum 本质类似 int 的 typealias 、数组 T[] 类似能以相似语法 new 的 T*)
编程者仅有这些手段——可以说所有的类型都是由这些「基础构造」方法互相缝合构造出来的,手段是有限的,正如语法的 BNF(形式化文法 即规范) 是有限的。”
类型理论上,构造值被称为 introduction ,利用它们去计算称为 elimination (这名字像问题的出现和消逝),这些都要定规则:
数值『字面量(literal)』都是 int 类型的实例(int 值)
指针类型 T*,若有
我们可以对 int 值施用数值运算的运算符、判等(及大小)、按位且或非 交并补(A - B,
指针类型 T* 的实例 a,可以解引用 (*a) 得到型为 T 的结果,或者说
类型上的信息编码:如果我们能用 T 类型及其 intro/elim 去实现出 T1 类型的 intro/elim,那可以说 T 是一个比 T1 更 general(概括性) 的类型,实现其操作(即 from/into) 的过程我们称之为『编码(encode)』,也听有说法表示 T1与T 是等价(equivalent) 的。
上篇感觉有点意思的是,提到了「操作语义」「指称(指代?)语义」「范畴语义」,也就是编程范式了,表述式(即过程式)、定义式、关系式(逻辑),这些要素在语言中各有取舍。 Java 就是 OOP 表述式化(
我们可以说『语义』是程序的「执行方式」,比如函数调用的语义就是把函数体的语义拿出来,把里面的形参(formal parameters)引用(reference),换(substitute)成实参(arguments),然后这个函数体的语义就是这个函数调用的语义。
我们也可以说这个编程语言实际上是某个更基础的语言的『高级形式』,比如可以用「翻译出汇编的方式」来讨论 C 程序的语义。
比如我有调用
事实上,这分别就对应着解释型(interpreted)语言和编译型(compiled)语言!是不是感觉和常见的编译原理知识联系到一起了?
相关资料:
https://tttttt.me/dsuse/14926
https://tttttt.me/dsuse/14705
在本苏的频道搜
表达式(中缀算符链、结合优先级、前缀算符和后缀
语句和控制流(
函数也即子程序调用与作用域(call/return, scoping, inline...) 、
类型转换与数值宽度提升、
这四点是要注意的,此外镇静解析(即部分解析)策略与良好的错误报告、基于编译单元/函数体的增量解析、常量折叠、评估损益自动内联,以及 基础的组合(struct,T[])/分支(union,A|B)数据结构 是必不可少的。
中篇和结尾的学术性内容就不说了,睡大觉喽。😝
另外冰封竟然用中文了,第一眼看莫名觉得有点突兀,久违的中文博客。😊
我做不了总结的是,比较 Haskell/Scala 的部分以及 Coq (实际的逻辑关系编程…… 但其目的就是过类型检查 而不是写普通应用了,当然蛤丝科不带副作用能不能编程,当然也是可以的,因为计算机就有按顺序执行的能力)
当然,我现在非常重视实践能力以及同代码量应用范畴的最大化,可能会希望编译器不只能做单纯/直白的一种结构转换,而能带有更多边角信息(行号 等)的复用,从这点来说也必须向大佬学习(开发了 ImGui binding)。
「当我们谈编程语言,实际是在讨论很多门相对独立的语言」
谈语言除了好看与否、红火与否、高大上与否,当然离不开『语言工具』,如构筑并管理『语法树』图结构的『解析器』(其亦可同时实现代码高亮)、做代码生成转化的『编译器』,以及提供(sizeof 等)信息和静态断言的类型检查器,不然就虚无缥缈了。
一般编程语言构造除了(可能的)解决领域应用痛点,模块化(易用于解决大型问题)、类型安全(尽早地保证正确性和性能)、表达式(用于描述计算) 是它的必须;举了个例子, #Kotlin 的
package
/import
和 #Rust 的 mod
/use
可以说是一种东西,不少语言带有的特性是跨语言的(替换并不影响语言的表现力)。他提到,『宏(macro)』作为编译期能展开 减少冗余代码量的特性,以及「类型与表达式语言更亲近」的事实(Kotlin 对执行中断类型
Nothing
的处理印证了这点)「相同类型的表达式互换不影响 well-typedness」
“程序可以有无限个、类型在大多数系统下也是有无限种。
数学上讨论无限大的对象(如无穷数列)的时候往往会涉及对这个对象的结构找有限的、被重复的规律,所以我们也对程序找了规律。
我们『构造』程序和类型的手段是有限的——比如在 C 语言里面,那些值类型就是几个单独的类型,然后我们能用结构体(struct)、union、数组(T[])、指针(T*)等功能从已有的类型构造新类型。(enum 本质类似 int 的 typealias 、数组 T[] 类似能以相似语法 new 的 T*)
编程者仅有这些手段——可以说所有的类型都是由这些「基础构造」方法互相缝合构造出来的,手段是有限的,正如语法的 BNF(形式化文法 即规范) 是有限的。”
类型理论上,构造值被称为 introduction ,利用它们去计算称为 elimination (这名字像问题的出现和消逝),这些都要定规则:
数值『字面量(literal)』都是 int 类型的实例(int 值)
指针类型 T*,若有
((T)expr)
那么 (&expr)
的类型就是 T*我们可以对 int 值施用数值运算的运算符、判等(及大小)、按位且或非 交并补(A - B,
a&~b
)运算指针类型 T* 的实例 a,可以解引用 (*a) 得到型为 T 的结果,或者说
*((T*)a).item
实际代表 a->item
,要以这种读内存、解指向的方式参与计算类型上的信息编码:如果我们能用 T 类型及其 intro/elim 去实现出 T1 类型的 intro/elim,那可以说 T 是一个比 T1 更 general(概括性) 的类型,实现其操作(即 from/into) 的过程我们称之为『编码(encode)』,也听有说法表示 T1与T 是等价(equivalent) 的。
上篇感觉有点意思的是,提到了「操作语义」「指称(指代?)语义」「范畴语义」,也就是编程范式了,表述式(即过程式)、定义式、关系式(逻辑),这些要素在语言中各有取舍。 Java 就是 OOP 表述式化(
switch, new List
等强调很重)、 Kotlin 则定义式化(if
有表达式型更有多分支 when
,提倡 map/reduce/associate
等列表处理函数,连 break
也是表达式),范式没有绝对的归类,每个语言都是独一无二的。我们可以说『语义』是程序的「执行方式」,比如函数调用的语义就是把函数体的语义拿出来,把里面的形参(formal parameters)引用(reference),换(substitute)成实参(arguments),然后这个函数体的语义就是这个函数调用的语义。
我们也可以说这个编程语言实际上是某个更基础的语言的『高级形式』,比如可以用「翻译出汇编的方式」来讨论 C 程序的语义。
比如我有调用
f(a)
,那么它的语义就是『f 的函数体』中『所有对参数的引用』全部换成 a 的语义后得到的一坨,同样是表达式的东西的语义。(当然调用前 f 得被声名为只能有一个参数、或不定长参数的函数,而且能找到函数体,这个参数的类型和表达式 a 的类型相同,或者兼容)事实上,这分别就对应着解释型(interpreted)语言和编译型(compiled)语言!是不是感觉和常见的编译原理知识联系到一起了?
相关资料:
https://tttttt.me/dsuse/14926
https://tttttt.me/dsuse/14705
在本苏的频道搜
UpValue
可以得到很多相关知识。说句题外话,本苏觉得语言实现的重点在于规范化程序结构和数据模型,表达式(中缀算符链、结合优先级、前缀算符和后缀
e.item
, e[idx]
等)、语句和控制流(
if when while do for, break continue
)、函数也即子程序调用与作用域(call/return, scoping, inline...) 、
类型转换与数值宽度提升、
这四点是要注意的,此外镇静解析(即部分解析)策略与良好的错误报告、基于编译单元/函数体的增量解析、常量折叠、评估损益自动内联,以及 基础的组合(struct,T[])/分支(union,A|B)数据结构 是必不可少的。
中篇和结尾的学术性内容就不说了,睡大觉喽。😝
另外冰封竟然用中文了,第一眼看莫名觉得有点突兀,久违的中文博客。😊
我做不了总结的是,比较 Haskell/Scala 的部分以及 Coq (实际的逻辑关系编程…… 但其目的就是过类型检查 而不是写普通应用了,当然蛤丝科不带副作用能不能编程,当然也是可以的,因为计算机就有按顺序执行的能力)
Telegram
duangsuse::Echo
#cs #project #tools 经历了好事多磨后,我的第一个脚本语言实践终于成功啦~ 而且支持 lexical scoping ,看这里。 (上图 LexicalScope 的定义,真古怪呢)
duangsuse::Echo
不用 class 封装游戏对象还是有局限性吧…… 为了性能不能检查 func 返回值来看是否中断,也不能每次 requestAnimationFrame 去 try-catch 一个,我看只有整体做大一点,key handler 放外面,才能避免为一个 Esc 键退出弄额外开销 目前的设计还是站在 inline 优化可信的基础上,可这毕竟是循环引用(updateFunc),func 参数不可能被内联的 不过,requestAnimationFrame 要自体再调用本身就不可以内联吧…… 关键是这个 next…
https://duangsuse-valid-projects.github.io/Share/HTMLs/renju_spaceship/spaceship.html
大家可以在这里试玩 #web #js #code #project
按 1 增加一盘, 2 增加彩球(我在干什么我,为什么要用五子棋盘当靶子…… 🤪 )
asteroids 方向键控制、空格射击、B 键刷新,其他参考 www.websiteasteroids.com
大家可以在这里试玩 #web #js #code #project
按 1 增加一盘, 2 增加彩球(我在干什么我,为什么要用五子棋盘当靶子…… 🤪 )
asteroids 方向键控制、空格射击、B 键刷新,其他参考 www.websiteasteroids.com
Forwarded from mivik::channels::tech
#project #music #abeat
简单的音乐图形化,初学 OpenGL/信号处理 的试作品,部分参考 https://github.com/hannesha/GLMViz (目前仅支持在 PulseAudio 环境下运行):
https://github.com/Mivik/abeat
简单的音乐图形化,初学 OpenGL/信号处理 的试作品,部分参考 https://github.com/hannesha/GLMViz (目前仅支持在 PulseAudio 环境下运行):
https://github.com/Mivik/abeat
#Python #project #cplusplus 克服艰难困坚的 C++ decl/defn member function 默认 inline 无 linkage 之后,总算弄出一个…… 🌚
明明几乎没有重构,却花掉一天时间
还想移植到 WASM 甚至用 WebGL? 做梦
https://GitHub.com/duangsuse/abeat-pm
(当然得先
所以说写这个 mkhpp.py (不是 mkhappy🌝) 其实就是没有找准定义分离模块化的根本矛盾和对立
最后试了
所以说写工程不仅在于要自动化,关键在于要解决国内网速慢的问题…… 把 gl.xml 都缓存了🌝
明明几乎没有重构,却花掉一天时间
还想移植到 WASM 甚至用 WebGL? 做梦
https://GitHub.com/duangsuse/abeat-pm
(当然得先
pip install glad
我忘写了所以说写这个 mkhpp.py (不是 mkhappy🌝) 其实就是没有找准定义分离模块化的根本矛盾和对立
最后试了
[[gnu::noinline]]
和 extern static 什么的没用,勉强通过允许在 hpp 里让小部分函数先带定义体做到了所以说写工程不仅在于要自动化,关键在于要解决国内网速慢的问题…… 把 gl.xml 都缓存了🌝
GitHub
duangsuse/abeat-pm
Mivik/abeat with enhanced project management. Contribute to duangsuse/abeat-pm development by creating an account on GitHub.
#project #drawing #web 这个大概更新了一次,支持配置参数(调时序和事件入口弄了好久😅
现在实质算法与动画、位图坐标系套板完全分离了。
看看这个
此外旧版我也留了
https://duangsuse-valid-projects.github.io/Share/HTMLs/lrud/old.html
#js bookmarklet 半成品见下方。
现在实质算法与动画、位图坐标系套板完全分离了。
看看这个
此外旧版我也留了
https://duangsuse-valid-projects.github.io/Share/HTMLs/lrud/old.html
#js bookmarklet 半成品见下方。
Telegram
duangsuse::Echo
本来说做个绘制工具可以研究下这个的(当然不是那种泛向的框架 只支持一个队列式算法),最后勉强是用毅力实现了一下,妄想的不用递归也能实现最后成了泡泡,太烧脑了最后选择了 Dijkstra 式 Map+backtrace... 😭 不过好在安排的特性都完成了
关于为什么不能做成框架,是因为我的动画方式是 await/async... 本身 setTimeout fillRect 已经够简洁了,而且我不会其它的算法。 如果说是递归算法又不方便移植到这个示例来,栈深有限。
https://duangsuse…
关于为什么不能做成框架,是因为我的动画方式是 await/async... 本身 setTimeout fillRect 已经够简洁了,而且我不会其它的算法。 如果说是递归算法又不方便移植到这个示例来,栈深有限。
https://duangsuse…
#日常精神分裂 #旧事重提 #Java #JS #PLT #cplusplus #project
A: 啊真的很头疼呢, JPlayer 的 fix 和 depth.html 附赠的 Myson 数据描述语言……
B: 像往常一样,我们一起想想吧。
A: 首先说 JPlayer ,这个原先是作为重写 Yuuta 大佬项目的东西,变的蛮多的,后来也有完全的 C++ 重写。
这个东西最后也是长期熬夜 timedout ,失败点是为优化性能加的 Ringbuffer 队列缓冲区利用有瑕疵,导致最后一次缓冲的内容没放完退出
B: 你还记得它的大体数据流程吗。
A: 当时怀疑 Java 计算速度慢所以用的缓冲器预计算一定内容,整体是 while(frame=next()) 呃不,是 while (escape=que[incPtr()]) if(samePtr()) genChunk() 。
B: 对了,你缓冲的帧是什么数据类型啊,二维数组吗?
A: 基于 frame pix diff 的 ANSI escape string ,这个当然是在 chunk 计算的
B: 生成新缓冲帧的程序你大概是没隔离吧,按当时的设计,应该是 genChunk 收到 VideoIO throw NPE 就跳出绘制loop 了,即便最后一块刚刚准备好。我建议 catch 住NPE ,如果 !samePtr(p,p1) 即还有余帧就继续播放,否则才真的退出。
(接下来一段被证明是误会)
A: 这大概是不利于性能的吧,最后一块的每帧都要 catch ,而且还要局部 landingpad ,函数级有一个了。
B: 你也说了是 jacoco 解码器 API 的问题? throw 是不可避免的,只能说或许可以把输出帧的做成子程序,最后一块的 catch 里直接消耗完队列,或者加个 bool ,未结末时先 if 一下避免重复。
A: 我总结一下流结末的情况: genChunk() 生成某帧时 catch 到一次,但是缓冲区没放完,继续放完这一块,再 catch (输入终末)了发现缓冲区没了,就停止播放。
A: 挺简单啊。那么 Myson 该怎么办,这个语言挺不常规的,既有缩进语义又只支持对象?
B: 首先我们先明确下,既有 heading tree 是怎么解析出的。
显然是每个DOM元素都有「深度」,然后非 h1~h6 的元素默认上一次深度或0 的 +1,所以说是「以能解析 Python 的算法解析标题嵌套深」对吧。
A: 可 Myson 就不是直接分开的,觉得要写 RegExp Lexer ,不敢写,挺麻烦的。
B: 看了语法设计,是不支持 array 什么的,只能 key-JSONValue 吗?
A: 是的,只支持一种嵌套,就是更深=子对象
B: 这么说没有行尾冒号也没问题喽?
A: 按理说是这样的……没问题吧?
B: 我能理解,反正你打算完全用缩进深度吧。你又没有支持 optional 多行的语法,唯一的不优雅在于有冒号没用,没冒号的话已有 value 的行后尾随缩进增,就不易看出冲突了。
A: 那具体如何实现呢。
B: 只需要 split lines+trim count 就可以了,之后 line 实际上就是 k-v ,遇到更深的就视为上一行的 v ,递归展开成 JSON.parse object 的形式,检查下不冲突就行了。当然,缩进莫名上升这种就检查不出来。
比如:
A: 听你这么一说我都有把这个 publish 到 npm 骗 star 的欲望了(
B: 我觉得这个挺浪费的,当然 JSON 也一样,key 重复了那么多次,不方便写也不方便传输
A: 有什么办法呢,下一层是 csv 基于 row 存储,那个是 efficient 但是只能存 object array ,而且也不能有嵌套对象
B: 我觉得你加上内联 CSV 的特性,就真的可以骗 star 了。 噢对你还应该把 JSON2Myson 写出来,就是带 indent: string 字段的 TreeWalker 是吧。相信你会写,这对工具化很有用,毕竟 JSON 不好看
A: (若有所思)
B: 你还可以把这个做一个 DOM Tree 的后端,甚至直接变成一个模板语言
B: 对了, JSON2Myson 用于带缩进输出的递归子程序还可以对 k-v 里的 v 立即处理而不必再下层递归,反正顶层又不支持单个值,就当是优化了。
A: 打住打住…… 这当然可以,其实就是翻译 {} 吧。区分 Attr 和 childs 对复用性有些挑战,但我相信能行。
A: 对了,我还有两个小点子:
(1)infsw 可以增加 timedline MM:ss ; 此外还有 exec 与 statics 子命令,以及 event name 的自定义和自动修正 failed watch 的 argv filter ,因为 watchdog py 的 watch medo/exec 和 inotify-tools 的 cli 都太麻烦,就自己写。
(2)之前的 OGL 频谱透明动画可以加一个纵反向的功能,利用 xdo 跟踪到窗口顶端什么的,像 supertuxkart 这样的游戏就可以当音游玩了(迫真)
A: 说起来卓依婷是谁啊,写的歌好熟悉呢
A: 啊真的很头疼呢, JPlayer 的 fix 和 depth.html 附赠的 Myson 数据描述语言……
B: 像往常一样,我们一起想想吧。
A: 首先说 JPlayer ,这个原先是作为重写 Yuuta 大佬项目的东西,变的蛮多的,后来也有完全的 C++ 重写。
这个东西最后也是长期熬夜 timedout ,失败点是为优化性能加的 Ringbuffer 队列缓冲区利用有瑕疵,导致最后一次缓冲的内容没放完退出
B: 你还记得它的大体数据流程吗。
A: 当时怀疑 Java 计算速度慢所以用的缓冲器预计算一定内容,整体是 while(frame=next()) 呃不,是 while (escape=que[incPtr()]) if(samePtr()) genChunk() 。
B: 对了,你缓冲的帧是什么数据类型啊,二维数组吗?
A: 基于 frame pix diff 的 ANSI escape string ,这个当然是在 chunk 计算的
B: 生成新缓冲帧的程序你大概是没隔离吧,按当时的设计,应该是 genChunk 收到 VideoIO throw NPE 就跳出绘制loop 了,即便最后一块刚刚准备好。我建议 catch 住NPE ,如果 !samePtr(p,p1) 即还有余帧就继续播放,否则才真的退出。
(接下来一段被证明是误会)
A: 这大概是不利于性能的吧,最后一块的每帧都要 catch ,而且还要局部 landingpad ,函数级有一个了。
B: 你也说了是 jacoco 解码器 API 的问题? throw 是不可避免的,只能说或许可以把输出帧的做成子程序,最后一块的 catch 里直接消耗完队列,或者加个 bool ,未结末时先 if 一下避免重复。
A: 我总结一下流结末的情况: genChunk() 生成某帧时 catch 到一次,但是缓冲区没放完,继续放完这一块,再 catch (输入终末)了发现缓冲区没了,就停止播放。
A: 挺简单啊。那么 Myson 该怎么办,这个语言挺不常规的,既有缩进语义又只支持对象?
B: 首先我们先明确下,既有 heading tree 是怎么解析出的。
显然是每个DOM元素都有「深度」,然后非 h1~h6 的元素默认上一次深度或0 的 +1,所以说是「以能解析 Python 的算法解析标题嵌套深」对吧。
A: 可 Myson 就不是直接分开的,觉得要写 RegExp Lexer ,不敢写,挺麻烦的。
B: 看了语法设计,是不支持 array 什么的,只能 key-JSONValue 吗?
A: 是的,只支持一种嵌套,就是更深=子对象
B: 这么说没有行尾冒号也没问题喽?
A: 按理说是这样的……没问题吧?
B: 我能理解,反正你打算完全用缩进深度吧。你又没有支持 optional 多行的语法,唯一的不优雅在于有冒号没用,没冒号的话已有 value 的行后尾随缩进增,就不易看出冲突了。
A: 那具体如何实现呢。
B: 只需要 split lines+trim count 就可以了,之后 line 实际上就是 k-v ,遇到更深的就视为上一行的 v ,递归展开成 JSON.parse object 的形式,检查下不冲突就行了。当然,缩进莫名上升这种就检查不出来。
比如:
小明
名字 "明天白"
年龄 14
朋友 ["小张", "小红"]
小张
名字 "张大奇"
年龄 15
最爱
世界 "你好世界"
伍六七 "excited"
突然想到可以这样.. Object.assign
某人 {"id": 1}
姓名 "小白"
朋友 "小黑"
A: 听你这么一说我都有把这个 publish 到 npm 骗 star 的欲望了(
B: 我觉得这个挺浪费的,当然 JSON 也一样,key 重复了那么多次,不方便写也不方便传输
A: 有什么办法呢,下一层是 csv 基于 row 存储,那个是 efficient 但是只能存 object array ,而且也不能有嵌套对象
B: 我觉得你加上内联 CSV 的特性,就真的可以骗 star 了。 噢对你还应该把 JSON2Myson 写出来,就是带 indent: string 字段的 TreeWalker 是吧。相信你会写,这对工具化很有用,毕竟 JSON 不好看
A: (若有所思)
B: 你还可以把这个做一个 DOM Tree 的后端,甚至直接变成一个模板语言
html
head
meta {charset: "UTF-8"}
body
a {onclick: "alert()"}
_text "你好。世界"
B: 对了, JSON2Myson 用于带缩进输出的递归子程序还可以对 k-v 里的 v 立即处理而不必再下层递归,反正顶层又不支持单个值,就当是优化了。
A: 打住打住…… 这当然可以,其实就是翻译 {} 吧。区分 Attr 和 childs 对复用性有些挑战,但我相信能行。
A: 对了,我还有两个小点子:
(1)infsw 可以增加 timedline MM:ss ; 此外还有 exec 与 statics 子命令,以及 event name 的自定义和自动修正 failed watch 的 argv filter ,因为 watchdog py 的 watch medo/exec 和 inotify-tools 的 cli 都太麻烦,就自己写。
(2)之前的 OGL 频谱透明动画可以加一个纵反向的功能,利用 xdo 跟踪到窗口顶端什么的,像 supertuxkart 这样的游戏就可以当音游玩了(迫真)
A: 说起来卓依婷是谁啊,写的歌好熟悉呢
#project https://tttttt.me/dsuse/16954
https://tttttt.me/dsuse/16970 https://tttttt.me/dsuse/16975 elm-lang.org
🤔咱先去写个关系式 state ,再去从 infsw 写起吧…… 不对,可以先去写个 line,insert,百叶窗的文本动画
https://tttttt.me/dsuse/16970 https://tttttt.me/dsuse/16975 elm-lang.org
🤔咱先去写个关系式 state ,再去从 infsw 写起吧…… 不对,可以先去写个 line,insert,百叶窗的文本动画
Telegram
duangsuse::Echo
#日常精神分裂 #DOM #game #js
A: 你看到了吗,那个从视口顶部丢球球下来,像俄罗斯方块一样的球碰撞游戏,是叫合成大西瓜来着
B: 那是个逻辑相当简单的游戏,也看见有三四个人做了翻版(奥利给等),如果按环节重复、更新规则、动画细节三项而言,细节不超过六个
A: 如果我们利用 canvas 做碰撞检测复刻一个,你觉得怎么样?整个绘制只有 Ball(p,r) 一种类型两个参数!简直和只有 fillRect 的贪吃蛇一样简单
B: 和 web asteroids 的 doc.elementFromPoint…
A: 你看到了吗,那个从视口顶部丢球球下来,像俄罗斯方块一样的球碰撞游戏,是叫合成大西瓜来着
B: 那是个逻辑相当简单的游戏,也看见有三四个人做了翻版(奥利给等),如果按环节重复、更新规则、动画细节三项而言,细节不超过六个
A: 如果我们利用 canvas 做碰撞检测复刻一个,你觉得怎么样?整个绘制只有 Ball(p,r) 一种类型两个参数!简直和只有 fillRect 的贪吃蛇一样简单
B: 和 web asteroids 的 doc.elementFromPoint…
Forwarded from mivik::channels::tech
This media is not supported in your browser
VIEW IN TELEGRAM
#share #oi #project
自动造数据机,支持多线程数据生成和 洛谷/UOJ 地等多格式导出(不过因为需要视觉效果所以只有 unix 终端可以用):https://github.com/Mivik/mic
自动造数据机,支持多线程数据生成和 洛谷/UOJ 地等多格式导出(不过因为需要视觉效果所以只有 unix 终端可以用):https://github.com/Mivik/mic
这几天也没啥可干🌚 队头就是二进制绑定、kd树等探索和..绝句编译器前的验收 这个我不急 #project
这样并不泛泛的实例,或许也有助于我提升web前端水平
请大家有空时了解下这个科普项目吧 ..虽然现在还在讨论
我这次的文章是 OOP 结合 awt.Graphics 绘制印花,扩充是UI参数化 支持 px,% 单位,以及 Android Painter 移植
形式是带canvas TIY编辑(只有JS伪码部分)
教学目的: 区间迭代、边界情况、子类继承、数据分类型
碎碎念:请看下节!列表处理可以批量转化和过滤出需要的信息,对与排序和字段过滤Excel很在行,Java里可没那么直观,但更强大!它需要咱对程序的流程和流程的复用先有了解-动手做好准备吧
补角:i++或++i 问题、ret/tmp 变量必要性、?:三元表达式、声明与赋值-最右出现原则
可能不会教 for(item:a)list.add(f(item)) 等过时写法,固化 for(=0;<N;+=1) 区间迭代写法(应该会是我入 #fp 以来最克制的教程了)
这样并不泛泛的实例,或许也有助于我提升web前端水平
请大家有空时了解下这个科普项目吧 ..虽然现在还在讨论
我这次的文章是 OOP 结合 awt.Graphics 绘制印花,扩充是UI参数化 支持 px,% 单位,以及 Android Painter 移植
形式是带canvas TIY编辑(只有JS伪码部分)
教学目的: 区间迭代、边界情况、子类继承、数据分类型
碎碎念:请看下节!列表处理可以批量转化和过滤出需要的信息,对与排序和字段过滤Excel很在行,Java里可没那么直观,但更强大!它需要咱对程序的流程和流程的复用先有了解-动手做好准备吧
补角:i++或++i 问题、ret/tmp 变量必要性、?:三元表达式、声明与赋值-最右出现原则
可能不会教 for(item:a)list.add(f(item)) 等过时写法,固化 for(=0;<N;+=1) 区间迭代写法(应该会是我入 #fp 以来最克制的教程了)
duangsuse::Echo
本来说可以移植 SDL 甚至支持 WebAudio 和 改写 sharder 渲染支持 stereo 的 (哪怕只是预求和一下 可大佬 size 计算变量貌似没弄全)。 但这个原版代码本身有一点冗余(其实有 sync locks 的一大堆尚无应用意义代码)、试用语言特性的意图, C++ 的简洁性很难(就连 flat 文件树都得拿自写预处理工具去保证),如果用 Py/JS 的话性能又不好,我觉得还是算了( 代码链接后 400k 也算小了 这个是 Mivik 版。 https://tttttt.me/dsuse/16598…
更实际的GLfw/FFTw示例看这里
https://tttttt.me/dsuse/16598
这里我们是要纯GL绘制一个柱状图,首先得按宽度比率切出vert,然后用geomerty(图形由顶点构成) 从points EmitVertex~EndPrimitive连出图形,最后frag只填平色就行
float y = mix(-1., 1., clamp(y_in, 0, 1)), x=mix(-1.,1., (float(gl_VertexID) + 0.5) / u_count);
gl_Pos = vec4(x, y, 0, 1)
//geom
layout (points) in;
layout (points, max_vertices = 1) out;
glPos=gl_in[0]; Emit //顶点0直接输出
layout (triangle_strip, max_vertices = 5) out;
P(l,-1) (r,-1) (l,y) (r,y)
就能生成一个□+\ 的几何
每个顶点都可以带颜色等附加信息,geom也能设置out fColor
bar vert的重力计算在这些之后每帧应用,绘制 y=texture(fftBuf,vertIdx),就能实现一个缓动的频谱图了。
glClear(00wh)
use(shader)
glBindVArray(vao)
glDrawArray(POINTS,0,N)
动苏第一次完全不知道 shader 除了着色贴图还能处理几何,后来觉得 geom 一定是先于 vert 运行(当成点和边了 😂),然后发现geometry shader 画矩形有四个点,vert 却只有2个,于是认为 vert 能决定宽高,或者有重复计算 🤣其实不懂绘图
https://blog.csdn.net/q1398284020/article/details/80181803 着色器变量
https://tttttt.me/dsuse/16598
这里我们是要纯GL绘制一个柱状图,首先得按宽度比率切出vert,然后用geomerty(图形由顶点构成) 从points EmitVertex~EndPrimitive连出图形,最后frag只填平色就行
float y = mix(-1., 1., clamp(y_in, 0, 1)), x=mix(-1.,1., (float(gl_VertexID) + 0.5) / u_count);
gl_Pos = vec4(x, y, 0, 1)
//geom
layout (points) in;
layout (points, max_vertices = 1) out;
glPos=gl_in[0]; Emit //顶点0直接输出
layout (triangle_strip, max_vertices = 5) out;
P(l,-1) (r,-1) (l,y) (r,y)
就能生成一个□+\ 的几何
每个顶点都可以带颜色等附加信息,geom也能设置out fColor
bar vert的重力计算在这些之后每帧应用,绘制 y=texture(fftBuf,vertIdx),就能实现一个缓动的频谱图了。
glClear(00wh)
use(shader)
glBindVArray(vao)
glDrawArray(POINTS,0,N)
动苏第一次完全不知道 shader 除了着色贴图还能处理几何,后来觉得 geom 一定是先于 vert 运行(当成点和边了 😂),然后发现geometry shader 画矩形有四个点,vert 却只有2个,于是认为 vert 能决定宽高,或者有重复计算 🤣其实不懂绘图
https://blog.csdn.net/q1398284020/article/details/80181803 着色器变量
Telegram
duangsuse::Echo
#project #music #abeat
简单的音乐图形化,初学 OpenGL/信号处理 的试作品,部分参考 https://github.com/hannesha/GLMViz (目前仅支持在 PulseAudio 环境下运行):
https://github.com/Mivik/abeat
简单的音乐图形化,初学 OpenGL/信号处理 的试作品,部分参考 https://github.com/hannesha/GLMViz (目前仅支持在 PulseAudio 环境下运行):
https://github.com/Mivik/abeat