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
Forwarded from dnaugsuz
我字多是因为我明白,想的多一点可以让代码简洁好看点
拿一小篇文字换所有项目里几十文件的质量,值。
拿一小篇文字换所有项目里几十文件的质量,值。
Forwarded from dnaugsuz
有的代码写一行省十行,有的代码所遵循的模式,写了第一行后维护和重读重理解的麻烦不断;即便功能相同,不同的人写出来质量是完全不一样的。
所以我一贯很乐意学习编程之道,可能你觉得我字多些,对真的要学这些内容的人来说,这是我第五次讲相同话题,已经很省字数了。
便宜的就是最贵的,不想付出但想多得回报,很难不为这种心态再付出更大的代价。浪费与节省,大概是这个道理。
所以我一贯很乐意学习编程之道,可能你觉得我字多些,对真的要学这些内容的人来说,这是我第五次讲相同话题,已经很省字数了。
便宜的就是最贵的,不想付出但想多得回报,很难不为这种心态再付出更大的代价。浪费与节省,大概是这个道理。