虎书P8问题(2)——直线式程序解释器

《虎书》确实彪悍,绪论里就留给读者实践性这么强的问题,对于中文版第8页上的问题(2),我的答案如下:

p8q2.h:

#ifndef P8Q2_H
#define P8Q2_H

#include "util.h"
#include "slp.h"

typedef struct table* Table_;

struct table{string id; int value; Table_ tail;};

Table_ Table(string id, int value, Table_ tail);

Table_ interpStm(A_stm stm, Table_ t);

struct intAndTable{int value; Table_ t;};

typedef struct intAndTable* IntAndTable_;

IntAndTable_ IntAndTable(int value, Table_ t);

IntAndTable_ interpExp(A_exp exp, Table_ t);

#endif


p8q2.c:

#include "p8q2.h"
#include <stdio.h>
#include <stdlib.h>

Table_ update(string id, int value, Table_ t);
IntAndTable_ interpAndPrintExp(A_exp exp, Table_ t);

Table_ Table(string id, int value, Table_ tail){
Table_ t = checked_malloc(sizeof(t));
t->id = id;
t->value = value;
t->tail = tail;
return t;
}

IntAndTable_ IntAndTable(int value, Table_ t){
IntAndTable_ iat = checked_malloc(sizeof(iat));
iat->value = value;
iat->t = t;
return iat;
}

Table_ interpStm(A_stm stm, Table_ t){
Table_ t1;
IntAndTable_ iat;
if(stm->kind == A_compoundStm){
t1 = interpStm(stm->u.compound.stm1, t);
return interpStm(stm->u.compound.stm2, t1);
}else if(stm->kind == A_assignStm){
IntAndTable_ iat = interpExp(stm->u.assign.exp, t);
return update(stm->u.assign.id, iat->value, iat->t);
}else if(stm->kind == A_printStm){// To support one-by-one print, interprete exp-by-exp
if(stm->u.print.exps->kind == A_lastExpList){
iat = interpAndPrintExp(stm->u.print.exps->u.last, t);
return iat->t;
}else if(stm->u.print.exps->kind == A_pairExpList){
A_expList list = stm->u.print.exps;
while(list->kind == A_pairExpList){
iat = interpAndPrintExp(list->u.pair.head, t);
t = iat->t;
list = list->u.pair.tail;
}
iat = interpAndPrintExp(list->u.last, t);
return iat->t;
}else{
printf("Invalid print exps!\n");
exit(1);
}
}else{
printf("Statement type error!\n");
exit(1);
}
}

IntAndTable_ interpExp(A_exp exp, Table_ t){
int value1;
IntAndTable_ iat1, iat2;
Table_ t1;
if(exp->kind == A_idExp){
value1 = lookUp(exp->u.id, t);
return IntAndTable(value1, t);
}else if(exp->kind == A_numExp){
return IntAndTable(exp->u.num, t);
}else if(exp->kind == A_opExp){
iat1 = interpExp(exp->u.op.left, t);
iat2 = interpExp(exp->u.op.right, iat1->t);
switch(exp->u.op.oper){
case A_plus:
value1 = iat1->value + iat2->value;
break;
case A_minus:
value1 = iat1->value - iat2->value;
break;
case A_times:
value1 = iat1->value * iat2->value;
break;
case A_div:
value1 = iat1->value / iat2->value;
break;
default:
printf("Invalid operator!\n");
exit(1);
}
return IntAndTable(value1, iat2->t);
}else if(exp->kind == A_eseqExp){
t1 = interpStm(exp->u.eseq.stm, t);
return interpExp(exp->u.eseq.exp, t1);
}else{
printf("Invalid operation type!\n");
exit(1);
}
}

Table_ update(string id, int value, Table_ t){
return Table(id, value, t);
}

int lookUp(string key, Table_ t){
while(t){// The initail table was a NULL
if(strcmp(key, t->id) == 0){
return t->value;
}
t = t->tail;
}
return 0;// initial with 0
}

IntAndTable_ interpAndPrintExp(A_exp exp, Table_ t){
IntAndTable_ iat = interpExp(exp, t);
printf("%d ", iat->value);
return iat;
}


main.c:

#include <stdio.h>
#include "util.h"
#include "prog1.h"
#include "slp.h"
#include "p8q1.h"
#include "p8q2.h"

int main(){
interpStm(prog(), NULL);
printf("\n");
return 0;
}


输出结果:
8 7 80
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值