设计思路:https://zhuanlan.zhihu.com/p/28540783
视频演示:https://www.bilibili.com/video/av13294962/
一言以蔽之,本项目涉及的思想包括:
ModuleTask
)、基于管道的进程同步机制的实现(ModuleProc
)、用户进程的实现(ModuleUserBase
意思是可以挂掉而不影响系统)ModuleClass
参照JS的原型链)ModuleFunction
)ModuleLisp
),B站视频链接ModuleStdBase
,参考Vlpp),类似Java 8 Stream链式/流式操作一言以蔽之,本项目涉及的玩法包括:
UserService
RING3级用户服务,实现FORK、管道、互斥。echo a | > b.txt
等,语法层面有Bash接口的实现ModuleClass
),应用有:状态机实例--百度新闻(URNews)、行为树实例-AI(URAI)、状态机实例-歌词动画(URMusic)、图论-路由距离算法-PC(URPC)test badapple
),测试IO性能ModuleNet
),采用netty实现远程命令test philo
、test philo2
)test lisp
)test linq
)test web
)jMiniLang is a simplified compiler/vm framework. Developed by bajdcc. PS. LR Analysis refers to VFS developed by vczh.
本项目是一个LR编译器、虚拟机一体化工程,并且对虚拟机进行了拓展,参考了操作系统设计的思想。
fork
.ModuleUser
.An OS running on jMiniLang compiler and interpreter.
Now has commands:(现在主窗口支持的cmd命令)
Tasks:(使用方法如:@system halt
)
UI:(使用方法如:@ui on clock
)
Toggle UI:
task ui on/off clock
task ui on/off hitokoto
task ui on/off monitor
Implemented IPC, usage:(微服务)
task system now
-> Get system timetask util calc 1+2*3
-> Val = 7task ui print hello world
-> Remote windowtask ui path M 100 100 L 200 200
-> SVGUtility:
task util doc g_func_fold
-> Documenttask util reverse ...
task util toupper ...
task util sum ...
task util product ...
task util palindrome ...
Tests:(测试命令,直接在主窗口cmd输入,Ctrl-C中止)
test philo/philo2
: Multi-processing and synchronizationtest lisp
: LISP languagetest font
: Support Chinese Language(wide font)test fork
: Test forktest class
: Test AOP and Prototype for classtest bash
: Test bash interfacetest try
: Test try/catchtest badapple
: Test ascii output, code in BadAppletest dialog
: Test JOptionPane.showXXXDialogtest linq
: Test LINQtest proc
: Test Ring 3 APItest proc2
: Test Ring 3 code with inputtest web
: HTTP Web ServerImplemented MSG, usage:(远程控制)
msg server PORT | filter pipe
other pipe | msg connect IP:PORT
PC command:
pc add A 10 10 100 100
pc remove A
pc msg A B
LINQ:
from(list)
or from(array)
range(begin, end)
TASK PROC:
USER HANDLE:(用户级进程支持的句柄种类)
Dependencies:(使用的开源库,下面为部分)
Web Server
Front-end: LayUI(前端)
1. Spring Boot API
Front-end: LayUI + Vue.js
API: Json + RestController
Back-end: jMiniLang API Handler (RING 3 Process)
Run on Server
Online Compiler Example V: GUI User Window
import "user.base";
var w = g_window("test window");
var width = 800;
var height = 600;
var border = 10;
w."msg"(0, width, height); // CREATE
w."svg"('M', border, border);
w."svg"('L', width - border, border);
w."svg"('L', width - border, height - border);
w."svg"('L', border, height - border);
w."svg"('L', border, border);
w."svg"('M', border * 2, border * 2);
w."svg"('S', width - border * 4, height - border * 4);
w."str"(1, g_string_rep("Hello world! ", 20));
w."svg"('m', 0, 200);
w."str"(1, g_string_rep("Hello world! ", 20));
w."svg"('m', 0, 200);
w."str"(0, g_string_rep("Hello world! ", 20));
g_sleep_s(1);
w."msg"(2, 0, 0); // WAIT FOR CLOSE
Online Compiler Example IV: Mutex
import "user.base";
var channel = g_pipe("TEST-MUTEX");
var goods = g_share("TEST-MUTEX#GOOD", g_from([]));
var index = g_share("TEST-MUTEX#INDEX", 0);
g_create_dir("/example-mutex");
var new_id = func ~() -> index."set!"(lambda(a) -> a++);
var enqueue = func ~(id) -> goods."get!"(lambda(a) -> a."push"(id));
var dequeue = func ~() -> goods."get!"(lambda(a) -> a."pop"());
var consumer_id = func ~(id) -> "/example-mutex/consumer-" + id;
var producer_id = func ~(id) -> "/example-mutex/producer-" + id;
var consumer = func ~(id) {
var obj;
var now = g_get_timestamp();
channel."writeln"("消费者 #" + id + " 已启动");
foreach (var i : g_range(1, 5)) {
while (g_is_null(obj := dequeue())) {}
channel."writeln"("消费者 #" + id + " 收到:" + obj);
}
channel."writeln"("消费者 #" + id + " 已退出");
var span = g_get_timestamp() - now;
g_write_file(consumer_id(id), "消费者 #" + id + " 用时 " + span + "ms", true, true);
};
var producer = func ~(id) {
var obj;
var now = g_get_timestamp();
channel."writeln"("生产者 #" + id + " 已启动");
foreach (var i : g_range(1, 5)) {
enqueue(obj := new_id());
channel."writeln"("生产者 #" + id + " 发送:" + obj);
}
channel."writeln"("生产者 #" + id + " 已退出");
var span = g_get_timestamp() - now;
g_write_file(producer_id(id), "生产者 #" + id + " 用时 " + span + "ms", true, true);
};
var child = false;
foreach (var i : g_range(1, 5)) {
if (g_fork() == -1) {
consumer(i);
child := true;
break;
}
if (g_fork() == -1) {
producer(i);
child := true;
break;
}
}
if (child) { return; }
if (g_fork() == -1) {
var i = 0;
while (i < 10) {
foreach (var id : g_range(1, 5)) {
if (g_query_file(consumer_id(id)) == 1) {
i++;
channel."writeln"(g_read_file(consumer_id(id)));
g_delete_file(consumer_id(id));
}
if (g_query_file(producer_id(id)) == 1) {
i++;
channel."writeln"(g_read_file(producer_id(id)));
g_delete_file(producer_id(id));
}
}
}
channel."write"(g_noop_true);
g_delete_file("/example-mutex");
return;
}
channel."pipe"(g_system_output());
Output:
运行成功!PID:24
消费者 #1 已启动
生产者 #1 已启动
消费者 #2 已启动
生产者 #2 已启动
消费者 #3 已启动
生产者 #3 已启动
消费者 #4 已启动
生产者 #4 已启动
消费者 #5 已启动
生产者 #5 已启动
生产者 #1 发送:1
消费者 #2 收到:1
生产者 #2 发送:2
消费者 #3 收到:2
生产者 #3 发送:3
...
消费者 #3 已退出
生产者 #4 发送:19
消费者 #4 收到:19
消费者 #4 已退出
生产者 #5 发送:20
消费者 #5 收到:20
消费者 #5 已退出
生产者 #1 发送:21
生产者 #1 已退出
消费者 #1 收到:21
消费者 #1 已退出
生产者 #2 发送:22
生产者 #2 已退出
生产者 #3 发送:23
生产者 #3 已退出
生产者 #4 发送:24
生产者 #4 已退出
生产者 #5 发送:25
生产者 #5 已退出
消费者 #2 收到:22
消费者 #2 收到:23
消费者 #2 收到:24
消费者 #2 收到:25
消费者 #2 已退出
生产者 #1 用时 106ms
消费者 #2 用时 131ms
生产者 #2 用时 107ms
消费者 #3 用时 91ms
生产者 #3 用时 104ms
消费者 #4 用时 88ms
生产者 #4 用时 101ms
消费者 #5 用时 89ms
生产者 #5 用时 100ms
消费者 #1 用时 108ms
正常退出
Online Compiler Example III: Fork
Fork
support yield
import "user.base";
var channel = g_pipe("TEST-FORK");
var pid = g_null;
if ((pid := g_fork()) != -1) { // 父进程读取管道
g_puts("父进程 PID:" + g_pid());
g_puts("父进程 FORK 返回:" + pid);
g_puts(channel, "读取管道:");
channel."pipe"(g_system_output());
} else { // 子进程写入管道
channel."writeln"("子进程 FORK 返回:" + pid);
var range = yield ~() { // 枚举器
for (var i = 0; i < 3; i++) {
yield g_fork(); // 枚举返回值
}
};
foreach (var i : range()) {
var txt = "这是一条测试消息! PID:" + g_pid() + " 编号:" + i;
channel."writeln"(txt);//写管道
g_sleep_s(1);
}
channel."write"(g_noop_true);//发送管道关闭信号
}
Output:
运行成功!PID:24
父进程 PID:24
父进程 FORK 返回:25
class= system::pipe 字符串(system::pipe)
读取管道:
子进程 FORK 返回:-1
这是一条测试消息! PID:25 编号:26
这是一条测试消息! PID:26 编号:-1
这是一条测试消息! PID:32 编号:-1
这是一条测试消息! PID:33 编号:-1
这是一条测试消息! PID:25 编号:32
这是一条测试消息! PID:26 编号:33
这是一条测试消息! PID:32 编号:38
这是一条测试消息! PID:33 编号:39
这是一条测试消息! PID:38 编号:-1
这是一条测试消息! PID:39 编号:-1
这是一条测试消息! PID:40 编号:-1
这是一条测试消息! PID:41 编号:-1
这是一条测试消息! PID:25 编号:40
这是一条测试消息! PID:26 编号:41
正常退出
Online Compiler Example II: Pipe
Reader
import "user.base";
var channel = g_pipe("TEST");
g_puts(channel, "读取管道:");
channel."pipe"(g_system_output());//将管道重定向至输出流
Writer
import "user.base";
var channel = g_pipe("TEST");
g_puts(channel, "写入管道:");
for (var i = 0; i < 10; i++) {
var txt = "这是一条测试消息! 编号:" + i;
channel."write"(txt + g_endl);//写管道
g_puts(txt);
g_sleep_s(1);
}
g_puts();
channel."write"(g_noop_true);//发送管道关闭信号
Online Compiler Example I: Hanoi
import "user.base";
var move = func ~(i, x, y) ->
g_puts(g_to_string(i) + ": " + g_to_string(x) + " -> " + g_to_string(y));
var h = call (func ~(f) ->
call (func [
"实现Y Combinator",
"Y = f -> (x -> f x x) (x -> f x x)",
"相关网页——https://www.cnblogs.com/bajdcc/p/5757410.html"
] ~(h) -> h(h))(
lambda(x) -> lambda(i, a, b, c) ->
call (f(x(x)))(i, a, b, c)))
(lambda(f) -> lambda(i, a, b, c) {
if (i == 1) {
move(i, a, c);
} else {
f(i - 1, a, c, b);
move(i, a, c);
f(i - 1, b, a, c);
}
});
h(3, 'A', 'B', 'C');
Online Documentation
Back-end
2. Java NIO
User mode
LINQ Example
Bash Example
Tail optimization (尾递归优化)
var g_tail_opt = func ["尾递归优化"] ~(fun, args) {
var x = lambda(a) { throw a; };
var fact = fun(x);
for (;;) {
try {
return g_call_apply(fact, args);
} catch (e) {
args := e;
}
}
};
// Usage
g_printn("Factorial(10) = " + g_tail_opt(
lambda(f) -> lambda(n, total) -> n <= 1 ? total : f([n - 1, total * n]),
[10, 1]));
g_printn("Fibonacci(10) = " + g_tail_opt(
lambda(f) -> lambda(n, a, total) -> n <= 1 ? total : f([n - 1, total, a + total]),
[10, 0, 1]));
0. Class (Omitted 省略)
1. Lambda: Y Combinator of Hanoi (见上面的例子)
Hidden, see Online Compiler Example I: Hanoi above.
2. Lambda: Trampoline (Omitted 省略)
3. List: LinkedList (Omitted 省略)
4. Multi-Process: Pipe (Omitted 省略)
5. Multi-Process: Consumer-Producer Model (生产者-消费者模型)
See online compiler example above. 见上面的例子。
6. Multi-Process: PC and Router (多进程,Omitted 省略)
7. Functional programming (函数式编程)
以上省略的内容可见此README的历史版本。
Screenshot 1 - Code
Screenshot 2 - Results
Screenshot 3 - Y-Combinator
Screenshot 4 - OS Virtual Machine with GUI
Screenshot 5 - Remote window
Screenshot 6 - Functional programming
Screenshot 7 - 哲学家就餐
专栏:https://zhuanlan.zhihu.com/p/29008180
Screenshot 8 - LISP
专栏:https://zhuanlan.zhihu.com/p/29243574
Screenshot 9 - 网络流