srccs.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 308 行
C
308 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <setjmp.h>
#include "vi.h"
#include "source.h"
static cs_entry *TOS;
#define FreeLabel( a ) MemFree( a )
/*
* oopsBob - fatal block nesting error
*/
#ifndef __AXP__
#pragma aux oopsBob aborts;
#endif
static void oopsBob( char *current, char *start )
{
extern jmp_buf GenExit;
Error( "'%s' has no %s", current, start );
longjmp( GenExit, DO_NOT_CLEAR_MESSAGE_WINDOW );
} /* oopsBob */
/*
* Push - put a entry on the top of the control stack
*/
static void Push( cstype type )
{
cs_entry *new;
if( EditFlags.ScriptIsCompiled ) {
return;
}
new = MemAlloc( sizeof( cs_entry ) );
new->next = TOS;
TOS = new;
TOS->end = NewLabel();
TOS->top = NewLabel();
TOS->type = type;
TOS->srcline = CurrentSrcLine;
} /* Push */
/*
* Pop - remove top entry off the control stack
*/
static void Pop( void )
{
cs_entry *crap;
if( EditFlags.ScriptIsCompiled ) {
return;
}
crap = TOS;
TOS = TOS->next;
FreeLabel( crap->end );
FreeLabel( crap->top );
MemFree( crap );
} /* Pop */
/*
* CSInit - prepare control stack
*/
void CSInit( void )
{
TOS = NULL;
Push( CS_EOS );
} /* CSInit */
/*
* Purge control stack
*/
int CSFini( void )
{
bool iserr=FALSE;
if( !EditFlags.ScriptIsCompiled ) {
while( TOS->type != CS_EOS ) {
iserr = TRUE;
Error( "unfinished c.s. at line %d", TOS->srcline );
Pop();
}
if( iserr ) {
return( DO_NOT_CLEAR_MESSAGE_WINDOW );
}
Pop();
} else {
if( TOS ){
// why the heck shouldn't I pop it!
cs_entry *crap;
crap = TOS;
TOS = TOS->next;
FreeLabel( crap->end );
FreeLabel( crap->top );
MemFree( crap );
}
}
return( ERR_NO_ERR );
} /* CSFini */
/*
* CSIf - if {elseif {elseif {...}} {else} endif
*/
void CSIf( void )
{
Push( CS_IF );
GenTestCond();
GenJmpIf( FALSE, TOS->top );
} /* if */
/*
* CSElseIf - emit elseif labels/branches
*/
void CSElseIf( void )
{
if( TOS->type != CS_IF ) {
oopsBob( "elseif", "if" );
}
GenJmp( TOS->end );
GenLabel( TOS->top );
FreeLabel( TOS->top );
TOS->top = NewLabel();
GenTestCond();
GenJmpIf( FALSE, TOS->top );
} /* CSElseIf */
/*
* CSElse - else labels/branches
*/
void CSElse( void )
{
if( TOS->type != CS_IF ) {
oopsBob( "else", "if" );
}
TOS->type = CS_ELSE;
GenJmp( TOS->end );
GenLabel( TOS->top );
TOS->top = NewLabel();
} /* CSElse */
/*
* CSEndIf - endif labels/branches
*/
void CSEndif( void )
{
if( TOS->type != CS_IF && TOS->type != CS_ELSE ) {
oopsBob( "endif", "if" );
}
GenLabel( TOS->end );
GenLabel( TOS->top );
Pop();
} /* CSEndIf */
/*
* CSWhile - loop/endloop - while/endloop - loop/until - while/until
*/
void CSWhile( void )
{
Push( CS_LOOP );
GenLabel( TOS->top );
GenTestCond();
GenJmpIf( FALSE, TOS->end );
} /* CSWhile */
/*
* CSLoop - looping labels/branches
*/
void CSLoop( void )
{
Push( CS_LOOP );
GenLabel( TOS->top );
} /* CSLoop */
static char _strlw[] = "loop/while";
/*
* CSEndLoop - endloop labels/branches
*/
void CSEndLoop( void )
{
if( TOS->type != CS_LOOP ) {
oopsBob( "endloop", _strlw );
}
GenJmp( TOS->top );
GenLabel( TOS->end );
Pop();
} /* CSEndLoop */
/*
* CSUntil - until labels/branches
*/
void CSUntil( void )
{
if( TOS->type != CS_LOOP ) {
oopsBob( "until", _strlw );
}
GenTestCond();
GenJmpIf( FALSE, TOS->top );
GenLabel( TOS->end );
Pop();
} /* CSUntil */
/*
* FindLoop - find first loop on control stack
*/
static cs_entry *FindLoop( void )
{
cs_entry *s;
s = TOS;
for( s = TOS; s->type != CS_EOS; s = s->next ) {
if( s->type == CS_LOOP ) {
return( s );
}
}
// prevent compiler from giving dead code warning because oopsBob is
// defined as an aborting function
if( s->type == CS_EOS ) {
oopsBob( "break/quif", _strlw );
}
return 0;
} /* FindLoop */
/*
* CSContinue - continue branches
*/
void CSContinue( void )
{
GenJmp( (FindLoop())->top );
} /* CSContinue */
/*
* CSBreak - break labels/branches
*/
void CSBreak( void )
{
GenJmp( (FindLoop())->end );
} /* CSBreak */
/*
* CSQuif - quit if labels/branches
*/
void CSQuif( void )
{
GenTestCond();
GenJmpIf( TRUE, (FindLoop())->end );
} /* CSQuif */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?