423 lines
10 KiB
Plaintext
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;
|
|
}
|