duangsues.is_a? SaltedFish
60 subscribers
609 photos
6 videos
91 files
562 links
🌶🐔🐟 duangsuse 的日常
尤其喜欢发些奇奇怪怪的东西
和转载别人的东西
Download Telegram
Forwarded from 可爱 鸭鸭
二分法,O(log(n))
Forwarded from 可爱 鸭鸭
几下就确定哪个提交有问题了
#Java #code
import java.util.function.Function;
import java.lang.reflect.*; //Proxy, InvocationHandler, Method

class Sam {
<FUNC, T, R> FUNC functor(Class<FUNC> fn_type, Function<T, R> impl) {
FUNC fn = (FUNC)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{fn_type}, new InvocationHandler() {
@Override public Object invoke(Object o, Method m, Object[] args) { return impl.apply((T)args[0]); } // self(o) ignored, argc&m unchecked
}); //< or use Proxy.getInvocationHandler(impl) to re-dispatch(require samename)
return fn;
}
interface XXCall { int call(int x); }
static public void main(String... a) {
Function<Integer,Integer> f = (x) -> x+1;
System.out.println(new Sam().functor(XXCall.class, f).call(1));
}
}
#essay #Java 想了下最近的操作
我是想给 JPlayer1 加上 buffer size 参数,再允许负 size 的 multi-thead Queue 渲染,不必手动 RingBuffer
再写一个最简版的 JPlayer3 ,反映无 queue 的绘制逻辑(草生)
想到 ANSI 命令台控制,又想拿 Java 配合下 JNI 去写贪吃蛇,死性不改…… 连怎么取 winsize(w,h) 都想了,JNI 返回 int[] 麻烦,就接收 int[] ,或者干脆变成 long(bitsize=2*int) 甚至 double, 没问题的 ;只需要提供 initScr(); printYX(y,x,s); endScr(); 然后封装个 writeLineN(n, s) 即可刷写屏幕(最开始打算让 initScr 返回行列大小,或者搞 yxprintf, mvprintf 什么的,还好我反应块,迫真;甚至还有想利用 OOP 抽象掉这个,去兼容 Android 上刷新字符帧的……可以在手机上玩但不必重写游戏逻辑 就是不方便)
(吐嘈:写完坏苹果以后我还会做 buffering 了……什么鬼)

现在我终于明白了命令台 REPL 的 Tab 补全是可以 10 行代码以内实现的,看来杂学对 ParserKt 也有用啊,下次就有经验了,复杂的初始化逻辑都倒大霉。

搞完这些又要把之前 耿爽模拟器、傅立叶变换动画 重构了
之前我还以为耿爽模拟器多难写,主要就是想 (1..randInt(10,25)).map { quotes.pick().fmt(noun=cfg[0], verb=cfg[1]) }.joinToString("") ,后来发现是主语选错了, quotes.take(randint(10,25)).shuffle { it.fmt(cfg[0],cfg[1]) }.joinToString("") 多简单(提性能可以拒绝临时 shuffled List<String> 创建 改 indices + joinToString transform)
刚开始不习惯编程 记忆变量关系,老是把 N append iter : 1 [noun,verb] cfg 这种简单逻辑背岔,现在不会了(老智障了 草)
主要是当初想“既然能拼接,能不能再写个函数「学习」这些文本数据”,后来才发现其实一个 String.replace 就能搞定,也就是说这个函数没比 replace 高到哪去,还是要 text 以外的参数,不过现在我觉得是可以统计下词频的,但那就要 NLP 了,目前我会用 Py 的 jieba.cut 分词

傅立叶的那个是真大佬,不知道是否驾驭的住,反正我对 js canvas 是绝对不熟练的

搞完了还有 mohu 的控制台 game 要重构,得把 List<Pair<String,String>List<String>> 的文本切分搞出来(前者是选项目对对联的游戏数据,后者是excited的界面翻译随机pick)
C++ 11 的 coding convert 还真是不习惯,看起来 wcout 在 Wine 没有用,只能是 wstring_convert API 了
想着这个按换行、分号切分的 2维文本数组 可不可以用 ifstream 去读取,答案当然是不可以,如果不以 '\n', ' ' 切分就读不了啦(而且很可能不支持 unicode )
还是要走 C 的 malloc +full read 那种吗,当然 bytes->Unicode int 是必须的,有时候真想念 Python 那奇怪的 encode decode 啊,写完了或许能做 WASM 支持
#essay #Java 想了下最近队列的代码坑 #js #python
duangsues.is_a? SaltedFish
#essay #Java 想了下最近的操作 我是想给 JPlayer1 加上 buffer size 参数,再允许负 size 的 multi-thead Queue 渲染,不必手动 RingBuffer 再写一个最简版的 JPlayer3 ,反映无 queue 的绘制逻辑(草生) 想到 ANSI 命令台控制,又想拿 Java 配合下 JNI 去写贪吃蛇,死性不改…… 连怎么取 winsize(w,h) 都想了,JNI 返回 int[] 麻烦,就接收 int[] ,或者干脆变成 long(bitsize=2*int)…
看了一下我觉得 Java 上的 REPL 最好有个 LineEditReader 这种,需要的 native API 仅 termios tcaget/set attr; struct termios 一个 (Windows 上再实现即可)

像这样:
class X extends Reader {
static native void cbreak(boolean on);
static void hmove(int offset); // 水平移动
static void vmove(int offset); // 可以用来预览求值结果
static void rmchar(int n); // -1 删行
init { cbreak(true); runtime.addShutdownHook(new Thread(() -> cbreak(false))); }
void bind(char ch, Runnable op);
void bindCtrl(char ch, /**/);
void bindAlt(char ch, /**/);
X bindNavigation(History hcfg); // 左右用 ANSI 移光标(stdin 什么的是不能自动移的), 上下翻历史
class History(String history_name, int limit)
//还应该加 String ps1, ps2 ,并且允许覆盖 printPrompt() 才对
//输入换行后没 close() 就显式 ps2
}
就可以 handle Python(标准 readline), Node(求值预览), IRB, pry(执行后带高亮), Chez scheme(闭括号看对应开括), Groovy(辣鸡,KeyboardInterrupt 都不 handle) 这样的 REPL ,而且使用也很方便, wrap 到一个 Reader 然后 bind 一下就可以了
作为读取流还是照样直接用,就很棒 #linux #cli #tui
#QQ #plt #ce #tt #parsing #forwarded
☭ 17:10:13
大家好 我问一个问题
设计一个语法, 其中有几个明确的目标是这样的:
程序中存在各个嵌套定义的命名空间
在表达式中可以对struct/function定义后立即使用
支持在一定范围内 先使用 后定义
例:
type id = struct sp1.sp2.st_id{...} s1(...).id_m + 16 * s2.id_m2;
在 sp1.sp2 这个空间定义st_id结构, 并立即使用它作为type来创建s1 初始化s1 使用s1.id_m参与表达式运算

.用法是想学C#用着方便, 其他是我想自己加的.
卡在这挺久了, 主要是在解决声明依赖上没经验. 希望可以向大家学习.

☭ 17:12:15
我身上的主要问题是不知道做多次扫描的解析器一般是怎么处理问题的.

duangsuse 17:17:59
“嵌套命名空间”是指动态作用域 { int a; for(int b; ;) {} } 这种吧
表达式里是怎么定义 struct/func 🤔
先使用后定义,一般是说编译期可知的数据,会统一处理,行号在后面不代表不可见,这个设计正常都没事

/*ns=namespace*/
type id = struct ns1.ns2.id_st{...} s1(...).id_m1 + 16 * s2.id_m2;

这样吗(话说你受 MS 系影响挺重…… st 都放前面了,一眼看成 struct fstat 的

孤胆硬汉 17:20:59
嵌套命名空间 是Cpp的这样
namespace space_id1{
namespace space_id2{
struct s1{...};
}
}
space_id1.space_id2.s1

孤胆硬汉 17:22:04
[图片]
(...) 初始化 ...省略其中内容

孤胆硬汉 17:25:11
有点艹蛋就艹蛋吧 一切没定下来 慢慢演化会变好的

duangsuse 17:25:22
编译完成前遍历树一次,收集完类型定义信息都可能

表示类型的 (type a=b) 做得到。
(struct nsChain. name) 你可以得写出来

T id1().a + id2.b 有点 C++ 风
如果你这个是算法作业,我对语言设计没话说,但是如果这就是你想要的编程…… 是不是有点谭绍强化了

孤胆硬汉 17:26:20
你觉得哪种写法好点啊 我主要是想写着方便

duangsuse 17:30:31
就你给的例子我觉得挺混乱的,但重命名下乍一看好像没问题一样,有点像 Emmet.io /流汗

如果你是真想简便,这种到处“副作用式定义”估计起不到什么效果,只要程序猿稍微多写点代码、加点 reference,且不说可维护性(go-to-definition 得做)

……相当于不重视如何简化引用处,反向想办法让定义处便于写吧。

duangsuse 17:32:37
很多时候设计上不可能“鱼和熊掌可以得兼”,选择简化定义,就等于给实际算法编写添麻烦

孤胆硬汉 17:34:57
其实我的想法是觉得 写的爽就好 剩下的交给代码整理来做 或者编译时自动整理

duangsuse 17:49:07
我没有什么 typechk 的实践经验,就随便说点:

你给的例子里只需要 type checker 走一遍就够了
(type a=b) 本身是类型的,可以给 visit 函数设返回值,副作用为定义类型。

struct (/*nss*/ns1.ns2).name {} 的 = createNameIn(nss, name, Struct(braceDecl)) ,需对name反向引用换创建用 函数值即可,C++ weak_ptr

id id1()+wtf 的表达式相当生草(只能说它也把语法混乱了,这不是 Type Name InitArg; 的定义了啊)
那么我认为实际是 (id id1()).a + 16*id2.b ,也就是说有一个特殊的中缀“ ”代表 "T type has inst o",而其左部是 Type 而非 AtomExpr ... 还是说你想用更不优雅的 Type Name InitArg InfixChain; 模式?

内存管理问题不知你考不考虑,如果要栈上分配 树遍历也会麻烦点

duangsuse 17:50:05
[图片]

duangsuse 17:56:46
算符链解析器上的问题始终有办法处理,但是如果所需的算法太复杂,只能说是语言设计有问题

int j=(int i) + 1; 总有办法解析(空格中缀什么的真不是问题 或者搞backtrack预判Type|Name|AtomExpr 也没问题 只不过不常规)
但最好不要干这种事情,除非你真的很强,不嫌麻烦不怕写出没意义的东西
button {
background-color: #F5F5F5;
min-width: 4rem;
border-radius: 999px;
border: #48B8D8 2px solid;

box-shadow: #48B8D8 0 4px, #F8F8F8 0 6px 0 4px, #ADADAD 0 10px 0 4px, black 0 8px 0 8px;

margin-left: 12px;
margin-top: 4px;

transition: all .1s ease-in-out;
}

button:focus, button:hover {
transform: translateY(4px);
box-shadow: #48B8D8 0 0, #F8F8F8 0 2px 0 4px, #ADADAD 0 6px 0 4px, black 0 4px 0 8px;
}

button:focus { outline: none; }
#ce #parsing 半夜,想到一些关于分词处理的事,突然人格分裂。 🌝
深夜,关于分词器(Lexer,Tokenizer)数据建模的问题,动苏又开始人格分裂(划掉)进行讨论。

A:CASC 的 Lexer 我看了,除了不常规的 SyntaxFacts 用于数据转换,TokenKind+Token(kind,String) 是挺常见的,不过它当然没有创建对象,是 Lexer-instance 上的 variable ,C 实现一般这么做。
B:我觉得 toplevel disambiguate 的 routine 不该叫 void Lex() ,应该做成 Iterator<Toekn>的形式
A:面向对象、局部化的做法很好也便于组织语法树,但是 return new 会增加内存压力,就为给 String 加 Kind ,很亏
B:其实看看最后返回的 Token 基本都是 (kind=LParen, text="(") 这样的东西,token type 最后只是被 when 了一下没有别的用也不影响 toString()
A:是,我觉得为了严谨也不该弄出 type ,可是具体怎么去掉
B:分词器解析器,二者之间传递的除了序列的拆分,无非是传递关键字种类、String literal、Int 的信息,一般只要一 String 就够,但是会区分不出 "(" 代表 LParen 还是用户输入的 "(" 字符串
B:要区分词条是 kw 还是 lit-text ,可以选择加 Kind 也可以直接将其存返回 String 里,作为固定后缀吧,考虑部分人用 StringBuilder 建立,以及 substr 取前缀速度可能快一些。数据存储没有通用的规范,建立方消耗方都明白即可
A:这样就可以省去 TokenKind 的定义了,而且解析上也少写一大堆无聊的 1:1关系建立代码
B:不仅如此,弄完后你会发现一大堆之前一行行写读取的 token 其实都有类似 Regex 的通用模式,并不需要为它们单独编程 所以可以复用统一大量代码
B:Int、Char 的这些完全可以扫到字符串里再重读,其实完全可以直接把 type char 放到 Iterator 上,没有就代表不是值词条,只是关键词
B:突然想到一个更好的方法:反正关键词是固定的,直接定义成 String 用 ==(而非 equals) 全等判断呗,这样也方便解析器构造,如果没有自然就是值词条,Lua 就是这么弄的。
A:还是觉得建模成 Iterator ,不要全部放 instance var 的建议最有实用价值,kind 怎么定义也是个人喜好啦。
Forwarded from niconiconi