Files
TempleOS-Rijn/LT/Compiler/CmpMain.CPZ
T
2018-09-08 21:45:20 +02:00

423 lines
10 KiB
Plaintext

void CatchAll()
{
I8 i;
if (Fs->except_argc>0) {
if (Fs->except_argv[0]<SysTextSubCount("ST_EXCEPT_TYPES")) {
PrintF("Exception Type :%Z\r\n",Fs->except_argv[0],"ST_EXCEPT_TYPES");
if (Fs->except_argv[0]==EXCEPT_UNDEF_SYSTEXT)
PrintF("Name:'%s'\r\n",Fs->except_argv[1]);
else if (Fs->except_argv[0]==EXCEPT_ARITHMETIC)
PrintF("Address:%P\r\n",Fs->except_argv[1]);
else if (Fs->except_argv[0]==EXCEPT_FLOATING)
PrintF("Address:%P\r\n",Fs->except_argv[1]);
else {
for (i=1;i<Fs->except_argc;i++)
cout Fs->except_argv[i]," ";
CrLf;
}
} else {
cout "Exception:";
for (i=1;i<Fs->except_argc;i++)
cout Fs->except_argv[i]," ";
CrLf;
}
} else
coutln "Generic Exception";
Fs->catch_except=TRUE;
}
void ExePutS(I1 *st)
//Inserts text into the stream of
//characters being compiled. Called
//from withing $FG,2$#exe{}$FG$ block.
{
LexStruct *lx=Fs->last_lex;
ExeBlkStruct *tempe=lx->last_exe_blk;
if (tempe!=&lx->next_exe_blk)
tempe->body=Add2Str(tempe->body,st);
else
PrintFErr("No exe{} blk\r\n");
}
void ExePrintF(I1 *src,...)
//Inserts text into the stream of
//characters being compiled. Called
//from withing $FG,2$#exe{}$FG$ block.
{
I1 *buf=SPrintFJoin(NULL,src,argc,argv);
ExePutS(buf);
Free(buf);
}
U1 *CompileStatement(LexStruct *lx,U8 *type=NULL)
{
U8 *result=INVALID_PTR;
AsmCtrlStruct *a=lx->a;
U8 size,i,j,k;
DbgInfo *dbg=NULL;
IntermediateCode *tempi;
if (type) *type=IT_I8;
Btr(&lx->flags,LFf_OPT_TRACE_PRESENT);
CbInitOutPtrs(&lx->cb);
CbAddIc(lx,EC_RETURN_START,0,sys_internal_types[IT_I8]);
tempi=lx->cb.cb_last_out_ptr;
if (!CmpParseStatement(lx,NULL)) {
if (tempi!=lx->cb.cb_last_out_ptr) {
CbAddIc(lx,EC_RETURN_END,0,sys_internal_types[IT_I8]);
CbAddIc(lx,EC_RET,0,0);
CbAddIc(lx,EC_NULL,0,0);
if (result=CbCompile(lx,NULL,&size,&dbg,type)) {
if (a) {
j=a->ip;
k=(size+7)>>3;
for (i=0;i<k;i++)
AsmStoreCodeU8(lx,result[i]);
Free(result);
result=j;
}
}
} else
DelLinkedList(lx->cb.cb_out_first);
} else
DelLinkedList(lx->cb.cb_out_first);
Free(dbg);
return result;
}
ExeStruct *CompileBuf(U1 *buf,I1 *map_name=NULL,
I8 *error_cnt=NULL, I8 *warning_cnt=NULL,I1 mapfile_drive=0)
{
BoolU4 okay=TRUE;
LexStruct *lx;
AsmCtrlStruct *a;
U8 i,j;
ExeStruct *result=NULL;
AsmCodeBlk *tempc;
ExeImportExportStruct *tempe,*tempe1;
if (!is_first_compiler)
coutln "$$FG PURPLE$$**** Not First Compiler ****$$FG$$";
result=MAllocZ(sizeof(ExeStruct));
lx=LexNew(buf,LF_DONT_FREE_BUFFER,NULL);
InsQue(lx,Fs->last_lex);
a=MAllocZ(sizeof(AsmCtrlStruct));
a->code=MAllocZ(sizeof(AsmCodeBlk));
a->local_hash=NewHashTable(16);
a->glbl_hash=NewHashTable(2048);
a->glbl_hash->next=asm_hash;
a->local_hash->next=a->glbl_hash;
lx->a=a;
lx->hash_table_list=a->local_hash;
lx->define_hash_table=a->glbl_hash;
lx->local_hash_table=a->local_hash;
lx->glbl_hash_table=a->glbl_hash;
Lex(lx);
try {
while (lx->token!=TK_EOF) {
i=CompileStatement(lx);
if (i!=INVALID_PTR) {
tempe=MAlloc(sizeof(ExeImportExportStruct));
tempe->type=EIE_MAIN;
tempe->ip=i;
tempe->str=NULL;
tempe->next=NULL;
tempe1=&result->ie;
while (tempe1->next) //TODO:This could be optimized
tempe1=tempe1->next;
tempe1->next=tempe;
}
}
ResolveGlbls(lx,result);
} catch {
if (Fs->except_argc>0)
if (Fs->except_argv[0]==EXCEPT_COMPILER)
Fs->catch_except=TRUE;
okay=FALSE;
}
RemQue(lx);
if (error_cnt) *error_cnt=lx->error_cnt;
if (warning_cnt) *warning_cnt=lx->warning_cnt;
if (!okay) {
//TODO free debug info and possibly classes
if (error_cnt)
if (*error_cnt<1) *error_cnt=1;
result=NULL;
} else {
if (map_name)
CallExtStr("HashRep",a->glbl_hash,HTT_ALL,map_name,"-r-p",mapfile_drive,NULL,NULL);
LexDel(lx);
DelHashTable(a->local_hash);
DelHashTable(a->glbl_hash);
if (!a->num_code_U1s)
result->code=NULL;
else {
result->code=MAlloc(a->num_code_U1s);
result->code_U1s=a->num_code_U1s;
tempc=a->code;
j=0;
lx=a->num_code_U1s;
while (tempc) {
i=lx;
if (i>ASM_CODE_BLK_SIZE)
i=ASM_CODE_BLK_SIZE;
MemCpy(result->code+j,tempc->body,i);
j+=i;
lx-=i;
tempc=tempc->next;
}
}
DelLinkedList(a->code);
result->absolutes=a->absolutes;
Free(a);
}
return result;
}
I8 CompileFile(I1 *filename,I1 *map_name=NULL,I1 *out_name=NULL,I1 mapfile_drive=0)
{
I1 *fbuf=NULL,*fbuf2=NULL,*fbuf3=NULL;
ExeStruct *e;
U4 *dd;
U8 size=0;
U1 *header=MAlloc(0x20000),*ptr;
BinFileHeaderStruct *bfh;
U8 i,cnt=0,error_cnt=0,warning_cnt=0;
ExeImportExportStruct *tempe,*tempe1;
ExeAbsoluteAddressStruct *tempa,*tempa1;
fbuf=DefaultExtension(filename,"SPZ");
fbuf2=MSPrintF("#include \"%s\"",fbuf);
if (map_name)
fbuf3=DefaultExtension(map_name,"MPZ");
e=CompileBuf(fbuf2,fbuf3,&error_cnt,&warning_cnt,mapfile_drive);
if (e) {
ptr=header;
tempa=e->absolutes;
while (tempa) {
cnt++;
tempa=tempa->next;
}
if (cnt) {
*ptr++=EIE_ABSOLUTE_ADDRESS;
dd=ptr;
*dd=cnt;
ptr+=sizeof(U4);
*ptr++=0;
tempa=e->absolutes;
while (tempa) {
tempa1=tempa->next;
dd=ptr;
*dd=tempa->ip;
ptr+=sizeof(U4);
Free(tempa);
tempa=tempa1;
}
}
tempe=e->ie;
while (tempe) {
tempe1=tempe->next;
*ptr++=tempe->type;
dd=ptr;
*dd=tempe->ip;
ptr+=sizeof(U4);
if (tempe->str) {
i=StrLen(tempe->str);
MemCpy(ptr,tempe->str,i+1);
Free(tempe->str);
ptr+=i+1;
} else
*ptr++=0;
Free(tempe);
tempe=tempe1;
}
*ptr++=EIE_END;
i=(ptr-header+15) & -0x10;
size=i+e->code_U1s+sizeof(BinFileHeaderStruct);
bfh=MAlloc(size);
MemCpy(bfh+e->code_U1s+sizeof(BinFileHeaderStruct),header,i);
MemCpy(bfh+sizeof(BinFileHeaderStruct),e->code,e->code_U1s);
bfh->jmp=0xE9+256*(16-3);
bfh->type=0;
bfh->header_offset=e->code_U1s+sizeof(BinFileHeaderStruct);
bfh->file_size=size;
bfh->xsum=LT_XSUM;
bfh->xsum=ArcCheckSum(bfh,size);
Free(fbuf2);
if (out_name)
fbuf2=DefaultExtension(out_name,"BIZ");
else
fbuf2=ChangeExtension(fbuf,"BIZ");
if (!cmp_do_not_write_to_disk)
WriteFile(fbuf2,bfh,size);
Free(bfh);
Free(e->code);
Free(e);
}
Free(header);
Free(fbuf);
Free(fbuf2);
Free(fbuf3);
PrintF(SysText("ST_ERRORS_WARNINGS"),error_cnt,warning_cnt,size);
return error_cnt;
}
I8 ExecuteCmdLine(LexStruct *lx)
{
I8 result=0,i,type;
I1 *ptr,*ptr2,*ptr3;
U1 *code;
LtfEntry *cl;
Ltf *l;
while (lx->token &&
(lx->token!='}' || !(lx->flags & LF_EXE_BLK)) ) {
if (!Bt(&Fs->task_flags,TSSf_DONT_CHANGE_DESC)) {
ptr2=&Fs->task_descriptor;
ptr3=ptr2+TSS_DESC_LENGTH;
if (lx->cur_lfn->flags & LFSF_IS_LTF) {
cl=lx->cur_lfn->line_start;
l=lx->cur_lfn->l;
while (cl!=l && ptr2<ptr3) {
switch (cl->btype && ptr2<ptr3) {
case LTFT_TEXT:
ptr=cl->display;
while (*ptr && ptr2<ptr3)
*ptr2++=*ptr++;
break;
case LTFT_TAB:
case LTFT_CR:
*ptr2++='.';
break;
}
cl=cl->next;
}
} else
if (ptr=lx->cur_lfn->line_start)
MemCpy(ptr2,ptr,TSS_DESC_LENGTH);
}
code=CompileStatement(lx,&type);
if (code!=INVALID_PTR) {
result=Call(code);
for (i=6;i>=0;i--) {
Fs->answers[i+1]=Fs->answers[i];
Fs->double_answers[i+1]=Fs->double_answers[i];
Fs->answers_types[i+1]=Fs->answers_types[i];
}
Fs->answers[0]=result;
Fs->double_answers[0]=result><(double);
Fs->answers_types[0]=type;
Free(code);
}
}
return result;
}
void ContinueUserTask()
{
LexStruct *lx;
while (TRUE) {
lx=LexNew(NULL,LF_PROMPT,NULL);
InsQue(lx,Fs->last_lex);
try {
Lex(lx);
ExecuteCmdLine(lx);
RemQue(lx);
LexDel(lx); //TODO: Sometimes crashes on BREAK
} catch
CatchAll;
}
}
I1 *CmpMGetS()
{
I1 buf[512];
GetS(buf,512,FALSE);
return NewStr(buf);
}
void CmpDebugger()
{
LBts(&sys_semas[SYS_SEMA_IN_DEBUGGER],0);
Fs->task_flags&=~(1<<TSSf_AWAITING_MSG);
InitUserTask;
sys_cur_focus_task=Fs;
sys_cur_scan_code=0;
ext[EXT_MGETS]=&CmpMGetS;
ContinueUserTask;
}
I8 ExecuteStr(I1 *buf,I1 *filename=NULL)
{
I8 result;
BoolU4 okay=TRUE;
LexStruct *lx;
if (!filename)
filename=sys_temp_filename;
lx=LexNew(buf,LF_DONT_FREE_BUFFER,AbsoluteFileName(filename));
InsQue(lx,Fs->last_lex);
try {
Lex(lx);
result=ExecuteCmdLine(lx);
} catch {
if (Fs->except_argc>0) {
if (Fs->except_argv[0]==EXCEPT_COMPILER ||
Fs->except_argv[0]==EXCEPT_BREAK) {
Fs->catch_except=TRUE;
okay=FALSE;
result=0;
}
}
}
RemQue(lx);
if (okay)
LexDel(lx); //TODO: can crash
return result;
}
I8 ExecuteFile(I1 *name)
{
I8 result;
I1 *name2=DefaultExtension(name,"CPZ");
I1 *st=MSPrintF("#include \"%s\";",name2);
result=ExecuteStr(st,name);
Free(st);
Free(name2);
return result;
}
#define ADAM_STARTUP_NAME "/LT/OSMain/AdamK.APZ"
void AdamStartUpFile()
{
BoolU4 okay=TRUE;
LexStruct *lx=LexNew(ReadTextFile(ADAM_STARTUP_NAME),0,
NewStr(ADAM_STARTUP_NAME));
InsQue(lx,Fs->last_lex);
ext[EXT_SPRINTF_JOIN]=&SPrintFJoin2;
ext[EXT_GETF_JOIN]=&GetFJoin2;
ext[EXT_EXECUTE_FILE]=&ExecuteFile;
ext[EXT_EXECUTE_STR]=&ExecuteStr;
ext[EXT_DEBUGGER]=&CmpDebugger;
InitCompiler(TRUE);
Bts(&lx->flags,LF_ECHO);
//Continues Here $LK,"/LT/OSMain/AdamK.APZ","FL:/LT/OSMain/AdamK.APZ,1"$
try {
Lex(lx);
ExecuteCmdLine(lx);
RemQue(lx);
LexDel(lx); //TODO
} catch {
CatchAll;
okay=FALSE;
}
if (!okay)
Debugger;
}