Computer Toy: Fibonacci Computer: Ruby
因为计算机科学导论里面要做一个模拟计算机CPU执行
大概20次类似汇编指令的事情, 并且还要给出每一步的计算机状态,
这个就让我很悲哀了. 我一个超过九九乘法表的运算都十分无力的菜狗,
做这种事分需要耐心的事情简直就是超级大危机.
于是, 为了发扬计算机的任劳任怨, 又超级细心的特色.
所以我决定自己做一个模拟CPU, 用来执行计科导里面出现的奇怪指令集.
(好吧, 做到最后我发现计科导课程里面的指令集和寄存器设定比较坑,
因为虽然限制了位宽度, 但是没有运算溢出的特性,
导致位宽度的设定有点鸡肋. 然后寄存器和内存有点不适合用来模拟实际的栈.
不过总体上来说还是能够成的. )
[2022/7/3] 拓展了一下, 重新写了一个解释器(Ruby)版本的. (虽然还有一些小小的问题), 目前可以实现大部分的Lisp功能了, (宏还在写… ). 参考的资料是SICP的第四章以及mal. 见下
最简单的版本
嗯, 就是课上的模式.
这个的大概思路是将代码读入一个@code
数组, 然后将内存放在@memory
数组中,
将@register
看作一个哈希表, 因为类似汇编语言的语法非常简单,
所以可以用简单的匹配方式来进行运算和执行.
我将指令用 lambda 的方式储存起来, 这样就可以执行了.
这里省略代码了.
我膨胀了
因为能够实现最简单的运行, 所以我就想着能不能实现更加牛一点的效果,
比如说能够变得更加稍微像真实的计算机一样, 于是我根据一点点朴素的想法,
实现了一个比较水的简单汇编CPU的模拟.
核心代码, 因为太年轻了, 写的不是很适合扔到Github上,
所以就这样展开看看吧.
网页和网页设计的代码
CSS样式设计
(没准以后可以写一个编译器. 然后把简单的代码编译成我实现的这个汇编,
嗯, 有点搞头. 我觉得也不是不行嘛. )
简单的一个想法:
# MOV M[SP + INDEX1], AX # 载入变量
# ADD M[SP + INDEX2], AX # 加法
# MOV AX, M[SP + INDEX1] # var_1 += var_2
# 减法, 乘法, 除法同理 #
# 故四则运算实现完毕 #
# #
# 条件控制流 #
# CMP 0, AX # AX 为表达式中的演算结果
# JE [tag] # if AX == 0
# #
# 循环的实现 # while true
# ADD ... // WHILE # while内部的代码
# CMP 0, AX # 计算条件判断
# JE WHILE # 跳转
# 然后把 for 语句包装为 # i = 0; while i < 10; i++
# #
# 函数调用的参数传递 # 用栈来传递
网页设计
这是我第一次接触网页设计, 写的很是丑陋. QAQ
不过感觉这样试过一次之后感觉还行, 估计之后可以试试.
又: 我用的是opal作为javascript的一个代替,
现在可以直接通过ruby代码来生成javascript来控制页面. 真棒.
何必要用javascript呢.
虽然只能说现在还差得远呢.
一个简单的demo
上面的demo加入不知道有什么可以试的话, 不妨看看这里的一些例子:
MOV 0, R1
MOV R1, M[R0]
MOV 1, R1
MOV R1, M[R0 + 1]
MOV 2, R2
MOV 0, R1 // LOOP
ADD M[R0 + R2 - 2], R1
ADD M[R0 + R2 - 1], R1
MOV R1, M[R0 + R2 - 0]
INC R2
CMP 10, R2
JL LOOP
HALT
(计算兔子级数)
MOV 1, R1
MOV 1, R2
INC R2 // LOOP
MUL R2, R1
CMP 5, R2
JL LOOP
HALT
(计算阶乘)
又: 这个demo我应该不会再更新了. 作为历史性质的东西来用吧.
(为什么不上传针对上课的版本呢? 因为那个写得太草了. )
接下去去实现编译器… 希望可以成功.
三月的最后一天更新
没错, 为了防止我明天更新显得像是在骗人一样,
我决定今天牺牲机动警察的时间来更新我的作品.
(其实是恰好搞完这件事… 一开始还夸下海口,
认为自己可以在一天时间里面把那个编译器给搞好, 没想到,
年轻人不讲武德, 不识抬举, 愣是给我搞了快一个星期才完成作品.
太惨了. 期间我发现了一个更加悲催的事情, 上课版本的那个,
我好像不小心把源码给覆盖了. QAQ. 啊, 好像有点没什么关系的样子. )
先看结果:
现在的这个版本我个人认为完成度还是比较高了,
可惜因为偷懒没有实现类似数组的list实现, 这个我认为比较遗憾了.
至于这个语言的一些特性还有来历, 请看看我的网页demo吧.
一些注记:
因为我没有实现输出和输入, 所以原则上来说,
用户的交互做得是真的没什么了. 所以假如你想要看到输入的话,
就到AX
里面看看吧. 因为所有表达式的返回值都是设定放在AX
里面来传递的.
关于源代码的事情, 因为我不觉得我的代码比较好,
效率比较低. 所以一开始是不摆明放出来的,
但是有了上面说的源代码被覆盖的案例, 所以为了保险,
还是说一说吧. 以后也好翻查. (假如不嫌弃的话, 可以到我博客的仓库
_img/computer-toys/machine
文件夹里面查看代码. )
假如你不知道写些什么的话, 除了图片里面的demo代码,
这里再提供一些无聊的小代码, 供你乐乐啦.
(def (sum x y)
(if (greater x 0)
(y)
(sum (sub x 1) (add x y))))
(sum 10 0)
一个无聊的累加器.
N久之后的一个更新
最终的目标是希望能够实现一个能够在网页中插入的代码执行器, 并且可以利用代码来和网页进行互动等等. 可以用做教学或者快速验证代码的功能. 但是目前还有很多的问题, 只是一个demo阶段. (并且外观也都没有很好的设计就是了… )