📄 code.cpp
字号:
/* pxdscript code.c
*
* history:
* 4/3 - Created with an empty recursion through tree
*/
#include "stdafx.h"
#include "code.h"
#include "memory.h"
#include "tree.h"
#include "error.h"
#include <string.h>
#include <stdlib.h>
/* *************************** UTILITY FUNCTIONS ********************** */
extern FUNCTION *funCinit;
CODE *currentcode;
CODE *currenttail;
LABEL *currentlabels;
void appendCODE(CODE *c)
{ if (currentcode==NULL) {
currentcode = c;
currenttail = c;
} else {
currenttail->next = c;
currenttail = c;
}
}
void code_nop()
{ appendCODE(makeCODEnop(NULL));
}
void code_imul()
{ appendCODE(makeCODEimul(NULL));
}
void code_ineg()
{ appendCODE(makeCODEineg(NULL));
}
void code_irem()
{ appendCODE(makeCODEirem(NULL));
}
void code_isub()
{ appendCODE(makeCODEisub(NULL));
}
void code_idiv()
{ appendCODE(makeCODEidiv(NULL));
}
void code_iadd()
{ appendCODE(makeCODEiadd(NULL));
}
void code_aadd()
{ appendCODE(makeCODEaadd(NULL));
}
CODE *code_label(char *name, int label)
{ currentlabels[label].name = name;
currentlabels[label].sources = 1;
appendCODE(makeCODElabel(label,NULL));
currentlabels[label].position = currenttail;
return currenttail;
}
void code_goto(int label)
{ appendCODE(makeCODEgoto(label,NULL));
}
void code_ifeq(int label)
{ appendCODE(makeCODEifeq(label,NULL));
}
void code_ifne(int label)
{ appendCODE(makeCODEifne(label,NULL));
}
void code_if_acmpeq(int label)
{ appendCODE(makeCODEif_acmpeq(label,NULL));
}
void code_if_acmpne(int label)
{ appendCODE(makeCODEif_acmpne(label,NULL));
}
void code_if_icmpeq(int label)
{ appendCODE(makeCODEif_icmpeq(label,NULL));
}
void code_if_icmpgt(int label)
{ appendCODE(makeCODEif_icmpgt(label,NULL));
}
void code_if_icmplt(int label)
{ appendCODE(makeCODEif_icmplt(label,NULL));
}
void code_if_icmple(int label)
{ appendCODE(makeCODEif_icmple(label,NULL));
}
void code_if_icmpge(int label)
{ appendCODE(makeCODEif_icmpge(label,NULL));
}
void code_if_icmpne(int label)
{ appendCODE(makeCODEif_icmpne(label,NULL));
}
void code_ireturn()
{ appendCODE(makeCODEireturn(NULL));
}
void code_areturn()
{ appendCODE(makeCODEareturn(NULL));
}
void code_return()
{ appendCODE(makeCODEreturn(NULL));
}
void code_aload(int arg)
{ appendCODE(makeCODEaload(arg,NULL));
}
void code_iload(int arg)
{ appendCODE(makeCODEiload(arg,NULL));
}
void code_astore(int arg)
{ appendCODE(makeCODEastore(arg,NULL));
}
void code_istore(int arg)
{ appendCODE(makeCODEistore(arg,NULL));
}
void code_dup()
{ appendCODE(makeCODEdup(NULL));
}
void code_pop()
{ appendCODE(makeCODEpop(NULL));
}
void code_ldc_int(int arg)
{ appendCODE(makeCODEldc_int(arg,NULL));
}
void code_ldc_string(char *arg)
{ appendCODE(makeCODEldc_string(arg,NULL));
}
void code_call(char* arg, char* signature)
{ appendCODE(makeCODEcall(arg,signature,NULL));
}
void code_setint(EntityKind kind)
{ appendCODE(makeCODEsetint(kind, NULL));
}
void code_sleep()
{ appendCODE(makeCODEsleep(NULL));
}
void code_sleepUntilTriggered()
{ appendCODE(makeCODEsleepUntilTriggered(NULL));
}
void code_cast(TYPE *source, TYPE *dest)
{ appendCODE(makeCODEcast(source, dest, NULL));
}
char *strcat2(char *s1, char *s2)
{ char *s;
s = (char *)Malloc(strlen(s1)+strlen(s2)+1);
sprintf(s,"%s%s",s1,s2);
return s;
}
char *strcat3(char *s1, char *s2, char *s3)
{ char *s;
s = (char *)Malloc(strlen(s1)+strlen(s2)+strlen(s3)+1);
sprintf(s,"%s%s%s",s1,s2,s3);
return s;
}
char *strcat4(char *s1, char *s2, char *s3, char *s4)
{ char *s;
s = (char *)Malloc(strlen(s1)+strlen(s2)+strlen(s3)+strlen(s4)+1);
sprintf(s,"%s%s%s%s",s1,s2,s3,s4);
return s;
}
char *strcat5(char *s1, char *s2, char *s3, char *s4, char *s5)
{ char *s;
s = (char *)Malloc(strlen(s1)+strlen(s2)+strlen(s3)+strlen(s4)+strlen(s5)+1);
sprintf(s,"%s%s%s%s%s",s1,s2,s3,s4,s5);
return s;
}
/* JVM style - except for better names ;) */
char *codeType(TYPE *t)
{ switch (t->kind) {
case intK:
return "I";
break;
case boolK:
return "B";
break;
case voidK:
return "V";
break;
case stringK:
return "S";
break;
}
return NULL;
}
char *codeFormals(DECL *f)
{ if (f==NULL) return "";
return strcat2(codeFormals(f->next),codeType(f->type));
}
/* The function signature is used in a later module to calculate the stack change
a call to that function will result in */
char *codeSignature(DECL *f, TYPE *t)
{ return strcat4("(",codeFormals(f),")",codeType(t));
}
/* ************************ TREE RECURSION ************************ */
void codeSCRIPTCOLLECTION(SCRIPTCOLLECTION *s)
{
if(s->toplevels != NULL)
codeTOPLEVEL(s->toplevels);
if(s->toplevels != NULL)
{
currentcode = NULL;
funCinit->labels = (LABEL *) Malloc(funCinit->labelcount*sizeof(LABEL));
currentlabels = funCinit->labels;
codeTOPLEVEL_SIMPLEDECL(s->toplevels);
funCinit->opcodes = currentcode;
}
}
void codeTOPLEVEL(TOPLEVEL *t)
{
switch(t->kind){
case functionK:
codeFUNCTION(t->val.functionT);
break;
case programK:
codePROGRAM( t->val.programT);
break;
}
if(t->next != NULL)
codeTOPLEVEL(t->next);
}
void codeTOPLEVEL_SIMPLEDECL(TOPLEVEL *t)
{
switch(t->kind){
case simpledeclK:
codeSIMPLEDECL(t->val.decl);
break;
}
if(t->next != NULL)
codeTOPLEVEL_SIMPLEDECL(t->next);
}
void codeFUNCTION(FUNCTION *f)
{
// Create signature string first
f->signature = codeSignature(f->formals,f->type);
currentcode = NULL;
f->labels = (LABEL *) Malloc(f->labelcount*sizeof(LABEL));
currentlabels = f->labels;
if(f->stms != NULL)
codeSTM(f->stms);
/* code the implicit return of 'void' functions*/
if (f->type->kind==voidK)
code_return();
else
code_nop();
f->opcodes = currentcode;
}
void codePROGRAM(PROGRAM *s)
{
currentcode = NULL;
s->labels = (LABEL *) Malloc(s->labelcount*sizeof(LABEL));
currentlabels = s->labels;
if(s->stms != NULL)
codeSTM(s->stms);
s->opcodes = currentcode;
}
/* 这里需要修改 */
void codeSIMPLEDECL(DECL *d)
{
if(d->val.simplevarD.initialization != NULL) {
codeEXP(d->val.simplevarD.initialization);
if (d->type->kind==stringK)
code_astore(d->val.simplevarD.offset+ 0x1000);
else
code_istore(d->val.simplevarD.offset + 0x1000);
}
}
/* Build code for a variable declaration. This means build code for any *initialization*
of the variable - the declaration itself does not produce any code!
As mentioned in chapter 7 variableK and simplevarK are treated the same because of
the transformation of the AST that we do in the weeding phase.*/
void codeDECL(DECL *d)
{
int i = 0;
if (d->globel) i = 0x1000;
switch(d->kind){
case formalK:
break;
case variableK:
if(d->val.variableD.initialization != NULL) {
/* Build code for the expression that makes up the initialization */
codeEXP( d->val.variableD.initialization);
/* Build code to store the result in the variables slot on the stack */
if (d->type->kind==stringK)
code_astore(d->val.variableD.offset + i);
else
code_istore(d->val.variableD.offset + i);
}
break;
case simplevarK:
if(d->val.simplevarD.initialization != NULL) {
codeEXP(d->val.simplevarD.initialization);
if (d->type->kind==stringK)
code_astore(d->val.simplevarD.offset + i);
else
code_istore(d->val.simplevarD.offset + i);
}
break;
}
if(d->next != NULL)
codeDECL( d->next);
}
/* Remember what a FORINIT is - it's the first part of the for-loop where the user can
do some initialization of variables before the loop is entered. A for-loop looks like this:
for(a;b;c) {
}
where 'a' is the FORINIT, 'b' and 'c' are the "condition" expression and the "update" expression
There are two possibilities for what 'a' is - it can be a *declaration*:
for (int a=0; a < 5; a=a+1) {
}
or 'a' can be an expression on already existing variables (just like 'b' and 'c'):
int a;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -