duangsuse::Echo
补充一下我真实的观点:绝句的新特性很多,但核心特性也不过七八个而已,我最看重的就是逗号表示法(囊括了逗句简写和「为」「其中」关键字)、逻辑算符否定、记法和类型推导,此外还有多语种API命名互译之类工具性的东西,所谓「人称文法」更多是一个提纲性、辅助学习者记忆的东西,本身无关键意义。 但是,其实我最看重的缩进语义「逗号表示法」,也是最难被抄走的——目前我自己也还在实验中,要设计的边角情况很多,如果真的有人能写出来,我只能是崇敬大于嫉妒了,虽然我明白自己迟早会实现它。 之前的『文言编程语言』,我是一点都不…
如何评价 duangsuse “酸”人的心态😡
Anonymous Poll
29%
😑玩不起就别玩,怎么可以用这种心态对待同道
29%
🙄这种心态很不好,对他人项目应该支持和积极交流才对
14%
😓即便你创建并喜欢了一个事物,也不可以把它视为私有,尤其是在还没有面世的时候
0%
🐦我不相信你有能力实现你说得那个玩意,实现了又怎能和既有的比?
57%
🍉表示不懂你们在酸的是什么
dnaugsuz
https://github.com/CASC-Lang/CASC/tree/master/src/CASC/CodeParser 还好不是很成熟,可是绝句不能再快了啊
https://github.com/terrajobst/minsk#browsing-the-code #csharp #PLT (其亲项目, inspiration 来源)居然专门注册了 minsk-compiler.net 这个域名,也是够 rich... 不过 C# 程序员到底是很有心
GitHub
GitHub - terrajobst/minsk: This repo contains Minsk, a handwritten compiler in C#. It illustrates basic concepts of compiler construction…
This repo contains Minsk, a handwritten compiler in C#. It illustrates basic concepts of compiler construction and how one can tool the language inside of an IDE by exposing APIs for parsing and ty...
https://github.com/CASC-Lang/CASC我会一如往常在频道里进行项目结构分析,然后用与 C# 相对的 Java (竟然不是 Kotlin... )进行一些并行的重写工作。
之所以用 #Java 写这样富于技巧的 #CE 编译器 程序,是因为我想常常新口味了…… 一些原来 Kotlin 里有的我也用 TypeScript 重写过
原项目是一个“能编译繁简体中文、甚至英语”的编译器,目标是对简体程序员可用。
ChAoS_UnItY (Chaos Unity) 开发,由 C# minisk-compiler.net 起意,后者是一个通俗的基础教程示范,也囊括对 IDE 等语言工具 暴露 parser 、 type checker 等“更远的”工作的示范。 #recommended
程式碼範例
一加二十一是二十二 == True这个没啥,相关知识: 算符链 InfixPattern/«Lua设计与实现» 相关章节; 中文数值 NumUnit/han() #learn
(1 + 9 - 7) 是 (一 加 九 減 七)
1 + 九 減 7
https://github.com/CASC-Lang/CASC/releases/tag/v0.0.1 看了以后我 🤔了很久,发现连 () 都是“运算符”而且还是 "TP"(tech. preview) 后我头疼了(显然我必须改掉这些设计)
而且它的文档表达的 OUA(Operator Unacceptable, 不接受数学形式) 让我也晕了一下
build 没什么好说的, azure CI + dotnet SDK .NET 5.0, publish build artifacts, NUnit tests
其 build.cmd 就是 dotnet build src/+test-proj/
那么看下关键点——词法、语法、计算与类型转换、作用域和函数调用。
Lexer.cs: Whitespace
char.IsWhiteSpace (为 " \t\n\r" 优化), Identifier/Keyword char.IsLetter, 整体是 _position, _kind:SyntaxKind 实现的,有趣的是 identifier text 是靠算 span 再 slice 取的,本身倾向流式
Peek(offset), Current, LookAhead=Peek(1), '\u0000' EOF 但不完全第一个
readonly List<char> 无使用写的是:
加 減 乘 除 點 開 閉 正 負 且 或 反(非,!) 是 不(是,!=) 赋(=) 开闭括号的我感觉有点奇怪。
加正+減負-命名都像
乘*除/
(){}
且 &&
或 ||
反!
!= 不是
是==
賦=
SyntaxKind.BangEqualsToken(!=) .StarToken(*) .SlashToken(/) 这样其中 ==, &&, ||, != 的需消歧义,但没有 lookahead 而是以状态机区分、「不是」「反」「赋」 都是别名
0123456789零一二三四五六七八九
壹貳參肆伍陆柒捌玖拾十百千萬億 靠外置
ReadNumberToken(); 读数另外都做了 ReportBadCharacter 的错误记录工作
以上皆返回
SyntaxToken ,试用 SyntaxFacts.GetText 拿内文,如果则用当前 span 取 substring 。Parser.cs:
CompilationUnit, Stmt, BlockStmt, VariableDeclaration, ExprStmt, VariableDeclaration, Expr, BlockStmt, Stmt, ExprStmt, Expr, Expr, AssignmentExpr, AssignmentExpr, AssignmentExpr, BinaryExpr, BinaryExpr, BinaryExpr, PrimaryExpr, BinaryExpr, PrimaryExpr, ParenthesizedExpr, BooleanExpr, NumberExpr, NameExpr, NumberExpr, ParenthesizedExpr, Expr, BooleanExpr, NameExpr
其中带 Binding(他没解释但估计是作用域上下文,但我很好奇为什么要给每个 Node 键一个 BoundedXXX) 支持的:
BlockStatement, ExpressionStatement, VariableDeclaration
LiteralExpression, VariableExpression, AssignmentExpression, UnaryExpression, BinaryExpression
感觉挺无聊的,还是开始重写吧 🤐
不对,把 Text/Stream, Binding, ChineseParser.cs 上的痛点先说下才能继续
架构的问题太大了,尤其是 Original/WithBinding AST, 这个绝对要想办法削掉
其实 Java 的基础面向对象结构绝对不比 C#,我不用 Lombok 但会争取 Kotlin 移植可能,作为休闲弄几天吧。
GitHub
CASC-Lang/CASC
a handwritten compiler which can compile English or Manderin or even mixed codes! - CASC-Lang/CASC
Forwarded from 可爱 鸭鸭
Qv2ray 主项目 Archive 一小时
以纪念所有参与开源项目开发但未获尊重的开发者
以纪念所有参与开源项目开发但未获尊重的开发者
duangsuse::Echo
https://github.com/CASC-Lang/CASC 我会一如往常在频道里进行项目结构分析,然后用与 C# 相对的 Java (竟然不是 Kotlin... )进行一些并行的重写工作。 之所以用 #Java 写这样富于技巧的 #CE 编译器 程序,是因为我想常常新口味了…… 一些原来 Kotlin 里有的我也用 TypeScript 重写过 原项目是一个“能编译繁简体中文、甚至英语”的编译器,目标是对简体程序员可用。 ChAoS_UnItY (Chaos Unity) 开发,由 C# minisk…
我是这么想的:除了 Binding 的一堆 class 我必须重构,其他代码我尽量保持原义吧
一些设计虽然比较花哨,但也有其可取之处,比如 SourceText,TextLine,TextSpan 那套
而且仿流式&状态机&子程序的 Lexer 与递归下降 Parser ,也算是比较经典的写法
一些设计虽然比较花哨,但也有其可取之处,比如 SourceText,TextLine,TextSpan 那套
而且仿流式&状态机&子程序的 Lexer 与递归下降 Parser ,也算是比较经典的写法
https://github.com/CASC-Lang?type=source
总之,这个还是比较搞大的。感觉作者是一个相当实践派的程序员,甚至有精力维护一个 Rust 版(C++ 版目前只有 CMakeLists) 以及一个(貌似是自动翻译的)TypeScript 版,生产能力很强,但代码质量和抽象/模拟能力必须学习一个,也该注意下不要把 build/ .vscode/ 提交上 VCS 什么的……
总之,这个还是比较搞大的。感觉作者是一个相当实践派的程序员,甚至有精力维护一个 Rust 版(C++ 版目前只有 CMakeLists) 以及一个(貌似是自动翻译的)TypeScript 版,生产能力很强,但代码质量和抽象/模拟能力必须学习一个
GitHub
CASC-Lang
An operation team for casc lang. CASC-Lang has 5 repositories available. Follow their code on GitHub.
羽毛的小白板
https://www.v2ex.com/t/747735#reply28
“TCP 本来是一个流传输协议(数据不分块,保证有序,也就是只保证多次 recv 的数据依顺序拼起来保持原样),偏要把它当成一个消息传输协议(数据分块,保证有序,保证一次 send 对应一次 recv )来用。
不巧的是在环回网络以及短途网络里调试时,这种误用并不会出问题。”
这个回答挺好的,我目前的理解就是,他们要做 WebSocket 这样的 event listen 式协议,但却手动维护了一个 buffer ,要“粘起来”发 TCP ,然后收方再拆了去 dispatch 。
嗯... 说到 socket ,数据的确没 chunked 而只是 bytestream ,这点我对 C API 引入的 buffers 理解错了,我之前隐隐觉得对方肯定收完 buffer 的内容…… 今后就有经验了
不巧的是在环回网络以及短途网络里调试时,这种误用并不会出问题。”
这个回答挺好的,我目前的理解就是,他们要做 WebSocket 这样的 event listen 式协议,但却手动维护了一个 buffer ,要“粘起来”发 TCP ,然后收方再拆了去 dispatch 。
嗯... 说到 socket ,数据的确没 chunked 而只是 bytestream ,这点我对 C API 引入的 buffers 理解错了,我之前隐隐觉得对方肯定收完 buffer 的内容…… 今后就有经验了
看完感觉懵懵的,动苏是 Kotlin 原住民,写过二进制字节流、字符流的框架,习惯 yield generator 和
表示很困惑什么叫「粘包」「拆包」,难道这两个词可以越过 Protobuf, BSON 这样的 data model 来谈吗?数据和其 representation, serialization 本身关系就不大的,为什么要专门写程序去拼包啊
java.util.Stream 的封装模式及利用,我明白,但根本就不看 static size 的那些东西和 buffers表示很困惑什么叫「粘包」「拆包」,难道这两个词可以越过 Protobuf, BSON 这样的 data model 来谈吗?数据和其 representation, serialization 本身关系就不大的,为什么要专门写程序去拼包啊
Forwarded from dnaugsuz
型变是
协变,
逆变,
(其中
子类型即若有
型变性的意义主要是,定义出符合子类型限制的类型约束,比如 PECS(producer-extends; consumer-super) 原则。
假设你的函数需要接受上一为参数
参数列表多几项、少几项都是一样的,只是要满足必须的类型约束而已。
实践上,就是每个 Producer/Consumer/Function<T, R> 的是用处都必须以
Kotlin 有 in/out 的声明处型变,也就是不用 Java 的 "Type wildcard" 了,是符合理论优雅性和实践便利性的:
在类型约束(如函参)处,
类型(限)上/下界即是指
🖕这个玩意非常易混,涉及一些中英文的文化差异和数学抽象概念的移植,建议不要使用
另外,泛型(generics, aka. parameterized polymorphism 参数化多态) 不是范型、上下界(U/Low bound) 不是上下届 ,千万别拼错。
<T> 参数上面的一种性质,其定义为:协变,
P<T1>: P<T> 逆变,
P<T>: P<T1>
不变, P<T>, P<T1> 无子类型关系。(其中
T1: T 、 class P<T> )子类型即若有
T1: T ,或言 (T)(T1)obj 有效(checks),则 op((T)x) 对 op((T1)x) 照样可用。型变性的意义主要是,定义出符合子类型限制的类型约束,比如 PECS(producer-extends; consumer-super) 原则。
interface Producer<R> { R get(); }
interface Consumer<T> { void accept(T value); } 假设你的函数需要接受上一为参数
er,它必须这样定义才能尽可能兼容「真正能兼容的所有」 er:void <R> R recv(Producer<? extends R> er);
void <T> void send(Consumer<? super T> er, T value); 参数列表多几项、少几项都是一样的,只是要满足必须的类型约束而已。
实践上,就是每个 Producer/Consumer/Function<T, R> 的是用处都必须以
Function<?super T, ?extends R> 这样的方法去定义参数的类型约束,不然它会破坏子类型的类型安全、或使本该有效的程序报类型检查错误,但让程序员去写这些 extends/super 的,实际上这是在暴露与业务逻辑不相干的细节。Kotlin 有 in/out 的声明处型变,也就是不用 Java 的 "Type wildcard" 了,是符合理论优雅性和实践便利性的:
interface Function<in T, out R> { fun apply(value: T): R } 在类型约束(如函参)处,
Function<Int, Any> 自动兼容其 Function<Number, Unit/*或 Nothing? = java.lang.Void, 仅 null*/> 类型(限)上/下界即是指
Void...Object (子类型的)extends/super 的约束,Void 是底,没有实例的类型;Object 是顶,所有类型的父类型,这个东西没有区间只能加限制条件。🖕这个玩意非常易混,涉及一些中英文的文化差异和数学抽象概念的移植,建议不要使用
另外,泛型(generics, aka. parameterized polymorphism 参数化多态) 不是范型、上下界(U/Low bound) 不是上下届 ,千万别拼错。
Oracle
Upper Bounded Wildcards (The Java™ Tutorials >
Learning the Java Language > Generics (Updated))
Learning the Java Language > Generics (Updated))
This beginner Java tutorial describes fundamentals of programming in the Java programming language