大一 PROJECT REPORT#1 设计一个基于C的简单语言,并为其写编译器,汇编器,虚拟机

本文记录了作者在大一第二学期设计并改进名为SIMP-C的简单C语言的过程,旨在通过编写编译器来深入理解C语言、汇编和底层架构。SIMP-C的语法包括英文和中文版,还有待添加的语法部分,并已给出了SIMP-C的汇编语法。
摘要由CSDN通过智能技术生成

SIMP-C语言

        现在是大一第二学期,跟着学校的进度,这学期用Scheme写了一个新的编程语言,叫SIMP,取义Simple Imperative Programming Language。觉得过程非常爽,同时也了解了机器底层的数据架构。

        现在这个学期快结束了,我想把这个SIMP语言改进一下,使之更贴近C语言,改名Simple C Language(SIMP-C),目的是在为其写编译器(Compiler)的过程中,能够对C语言、汇编及机器底层架构有更深入的理解。


SIMP-C语法(目前)

        先说我想写的这个新语言的语法,如下:
英文版
program =   (main [(id init) ...] stmt)

     id =   l_id                          ; id is bound to a memory address, ie. id is a pointer
        |   r_id                          ; id is bound to a r_val

  value =   l_val                         ; a memory address
        |   r_val                         ; an expression value
  r_val =   number
        |   boolean
        |   char
        |   exp
  l_val =   addr

   init =   value
        |   id
        |   (array exp ...)               ; as in int id[] = {1,2,3};
        |   (make-array nature exp)       ; as in int id[nat];

   stmt =   (print exp)                   ; print("%d", id);
        |   (= exp exp)                   ; value assignment
        |   (seq stmt ...)                ; as a pair of sqare brackets
        |   (iif exp stmt)                ; if (condition) {when ture};
        |   (iif exp stmt else stmt)      ; if (condition) {when true}; else {when false};
        |   (while exp stmt)              ; while (condition) {program};
        |   (array-ref l_id exp)          ; as the a[3] in printf("%c",a[3]);
        |   (array-set l_id exp exp)      ; a[1+2] = 0;

    exp =   (> exp exp)
        |   (>= exp exp)
        |   (< exp exp)
        |   (<= exp exp)
        |   (== exp exp)
        |   (!= exp exp)
        |   (&& exp exp)
        |   (|| exp exp)
        |   (+ exp exp)
        |   (- exp exp)
        |   (* exp exp)
        |   (/ exp exp)                   ; quotient
        |   (% exp exp)                   ; remainder
        |   value
        |   id
中文版
    声明 =   (main [(id init) ...] stmt)  ; 程序格式为,比如 (main [(a 1) (b 2)] (print (+ a b))), 将会输出"3"。[(a 1) (b 2)]是赋值。相当于 int main() {int a = 1; int b = 2; printf("%d",a+b);}

  变量名 =   l_id                          ; 变量名可以被赋予一个内存地址,换句话说变量名可以是指针。
        |   r_id                          ; 变量名可以是普通变量,比如char, int。

     值 =   l_val                         ; 一个"值", 可以是内存地址(叫做"l_val")。
        |   r_val                         ; 也可以是普通意义的数值(叫做"r_val"),比如char, int。
  r_val =   number
        |   boolean
        |   char
        |   exp         ; exp == expression, “表达式”的缩写。“值”可以是表达式的返回值。
  l_val =   addr        ; addr == address, 内存地址。

  初始值 =   值
        |   变量名
        |   (array exp ...)               ; 创建一个新数组,对应C语言中的,比如 int id[] = {1,2,3};
        |   (make-array nature exp)       ; 创建新数组,对应C语言中的,比如 int id[长度];

  结构句 =   (print exp)                   ; 打印一个id,对应print("%d", id); 为了简化,print也可以直接打印指针
        |   (= exp exp)                   ; 赋值语句
        |   (seq stmt ...)                ; seq的作用对应C语言里的方括号,"{","}",seq里面的语句依次执行
        |   (iif exp stmt)                ; 对应 if (condition) {when ture};
        |   (iif exp stmt else stmt)      ; 对应 if (condition) {when true}; else {when false};
        |   (while exp stmt)              ; 对应 while (condition) {program};
        |   (array-ref l_id exp)          ; 返回数组中的一个值,对应,比如 printf("%c",a[3]);
        |   (array-set l_id exp exp)      ; 给数组的某项赋值,对应,比如 a[1+2] = 0;

  表达式 =   (> exp exp)
        |   (>= exp exp)
        |   (< exp exp)
        |   (<= exp exp)
        |   (== exp exp)
        |   (!= exp exp)
        |   (&& exp exp)
        |   (|| exp exp)
        |   (+ exp exp)
        |   (- exp exp)
        |   (* exp exp)
        |   (/ exp exp)                   ; 求商数
        |   (% exp exp)                 ; 求余数
        |   值
        |   变量名
注: " = " 表示等号左边数据类型可以是右边的其中一个,“ | ” 表示或,比如 初始值可以是 "值,或变量名,或新数组..."

待定添加语法(目前)

函数声明 =      (func [(id init) ...] /* program */) 


SIMP-C汇编语法

        要写编译器,就必须得有汇编语法。虚拟机和汇编器我们这个学期也都已经写好了。现在我想写的这个project主要写的是编译器,把SIMP-C翻译到对应的汇编语言去。将来我也会重写这个汇编语言,到时再改。

        我直接用这学期自己写过的编译器,叫PRIMP(Primitive Imperative Language)。

; program   =   stmt-or-value ...

;汇编语法 =         
;加减乘除  (add nat nat nat)       ; 这里"nat"表示的全都是内存地址,为简化,用自然数代替(Nat == Nature Number)
;     |   (sub nat nat nat)       ; 所有nat nat nat... 都表示,从后面n个地址里分别取出n个值,运算,然后把结果放到第1个nat表示的地址去。
;     |   (mul nat nat nat)       ; 'add, 'sub, 'mul ...等等表示运算方式
;     |   (div nat nat nat)
;     |   (mod nat nat nat)       ; 求余数
;逻辑判断
;     |   (gt nat nat nat)        ; gt == greater than
;     |   (ge nat nat nat)        ; ge == greater than or equal to
;     |   (lt nat nat nat)        ; lt == less than
;     |   (le nat nat nat)        ; le == less than or equal to
;     |   (equal nat nat nat)
;     |   (not-equal nat nat nat)
;     |   (land nat nat nat)      ; land == &&
;     |   (lor nat nat nat)       ; lor == ||
;     |   (lnot nat nat)          ; lnot == !
;其它
;     |   (branch nat nat)        ; 取第一个地址的值,如果值为true,跳转到第二个地址,否则不跳转
;     |   (move nat nat)          ; 取第二个地址的值,复制到第一个地址里去
;     |   (move-imm nat number)   ; 直接取第二个数,复制到第一个地址里去
;     |   (jump-imm nat)          ; goto 内存地址
;     |   (print-imm value)       ; 直接打印一个值
;     |   (print-mem nat)         ; 打印内存地址里存的值
; A-PRIMP:
;   stmt    =   (halt)                                ; 停机,程序终止
;     |   (const psymbol psymbol-or-value)            ; 定义一个汇编语言里的id(psymbol),类型为常量,值为另一个id的值, 或数值,char,bool
;     |   (data psymbol psymbol-or-value ...)         ; 在内存里顺次载入n个(不同的或相同)值,并将psymbol赋值为其中第一个值的内存地址
;     |   (data psymbol (number psymbol-or-value))    ; 同上,不过,是在内存里顺次载入number个相同值。
;     |   (lit psymbol-or-value)                      ; 没用,lit == literal,用来表示PRIMP里的一个值,和Scheme里的值区分开。
;     |   (label psymbol)                             ; 用来标记GOTO(jump-imm)的地址
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值