📄 cexpr2.c
字号:
break;
case T___OW_IMAGINARY_UNIT:
{
FLOATVAL *flt;
tree = LeafNode( OPR_PUSHFLOAT );
tree->op.const_type = TYPE_DIMAGINARY;
flt = CMemAlloc( sizeof(FLOATVAL) + 3 );
flt->string[0] = '+';
strcpy( &flt->string[1], "1.0" );
flt->len = 3 + 1;
flt->type = TYPE_DIMAGINARY;
flt->next = NULL;
tree->op.float_value = flt;
tree->op.opr = OPR_PUSHFLOAT;
tree->expr_type = GetType( tree->op.const_type );
}
NextToken();
break;
default:
if( CompFlags.pre_processing && /* 07-mar-92 */
CurToken >= FIRST_KEYWORD && CurToken < T_MACRO_PARM ) {
tree = ExprId();
} else {
CErr1( ERR_MISSING_OPERAND );
tree = ErrorNode( NULL );
}
}
break;
}
--Level;
return( tree );
}
local TREEPTR ExprId()
{
TREEPTR tree;
int value;
int count;
if( CompFlags.pre_processing ) {
if( strcmp( Buffer, "defined" ) == 0 ) {
CompFlags.pre_processing = 2; /* don't want macro expanded */
NextToken();
if( CurToken == T_LEFT_PAREN ) {
NextToken();
value = IsMacroDefined();
NextToken();
MustRecog( T_RIGHT_PAREN );
CompFlags.pre_processing = 1;
} else {
value = IsMacroDefined();
CompFlags.pre_processing = 1;
NextToken();
}
} else {
// if( SizeOfCount == 0 ) { /* 17-jul-94 */
// CWarn( WARN_UNDECLARED_PP_SYM, ERR_UNDECLARED_PP_SYM, Buffer);
// }
NextToken();
if( CurToken == T_LEFT_PAREN ) { /* 26-may-89 */
count = 0;
for(;;) { /* flush to ')' or end of line */
NextToken();
if( CurToken == T_NULL ) break;
if( CurToken == T_LEFT_PAREN ) ++count;
if( CurToken == T_RIGHT_PAREN ) {
if( count == 0 ) {
NextToken();
break;
}
--count;
}
}
}
value = 0;
}
tree = IntLeaf( value );
} else {
tree = SymLeaf();
}
return( tree );
}
local int IsMacroDefined()
{
MEPTR mentry;
if( CurToken != T_ID ) {
ExpectIdentifier();
} else {
mentry = MacroLookup( Buffer );
if( mentry != NULL ) {
mentry->macro_flags |= MACRO_REFERENCED; /* 04-apr-94 */
return( 1 );
}
}
return( 0 );
}
#if 0
local int LValueArray( TREEPTR tree )
{
TYPEPTR typ;
if( tree->op.opr == OPR_PUSHSTRING ) {
return( 1 );
} else if( IsLValue( tree ) ) {
return( 1 );
} else {
typ = tree->expr_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_POINTER ) {
return( 1 );
}
}
return( 0 );
}
#endif
local TREEPTR GenIndex( TREEPTR tree, TREEPTR index_expr )
{
TYPEPTR typ;
type_modifiers tree_flags;
// if( ! LValueArray( tree ) ) {
// CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
// FreeExprTree( index_expr );
// return( ErrorNode( tree ) );
// }
index_expr = RValue( index_expr );
if( DataTypeOf( TypeOf(index_expr)->decl_type ) > TYPE_ULONG64 ) {
CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
FreeExprTree( tree );
return( ErrorNode( index_expr ) );
}
typ = tree->expr_type;
while( typ->decl_type == TYPE_TYPEDEF ) {
typ = typ->object;
}
if( typ->decl_type == TYPE_ARRAY ){
tree_flags = tree->op.flags; // get modifiers of array obj
}else if( typ->decl_type == TYPE_POINTER ){
// We will indirect so get modifiers of indirected obj
tree_flags = OpFlags( typ->u.p.decl_flags );
}else{
CErr2p(ERR_FATAL_ERROR, "Bad array index tree" );
}
typ = typ->object;
while( typ->decl_type == TYPE_TYPEDEF ) {
typ = typ->object;
}
// Some crappy little optimization that probably does nothing
if( index_expr->op.opr == OPR_PUSHINT &&
tree->expr_type->decl_type == TYPE_ARRAY ) {
index_expr->op.long_value *= SizeOfArg( typ );
tree = ExprNode( tree, OPR_DOT, index_expr );
#if _CPU == 8086
if( index_expr->op.long_value > 0x7FFF ) {
index_expr->op.const_type = TYPE_LONG;
index_expr->expr_type = GetType( TYPE_LONG );
}
#endif
} else {
#if _CPU == 8086
if( DataTypeOf( TypeOf(index_expr)->decl_type ) == TYPE_UINT ) {
if(( tree_flags & OPFLAG_HUGEPTR ) ||
((TargetSwitches & (BIG_DATA|CHEAP_POINTER))==BIG_DATA &&
(tree_flags & (OPFLAG_NEARPTR | OPFLAG_FARPTR))==0)) {
index_expr = CnvOp( index_expr, GetType( TYPE_LONG ), 0 );
}
}
#endif
tree = ExprNode( tree, OPR_INDEX, index_expr );
}
tree->expr_type = typ;
tree->op.result_type = typ;
tree->op.flags = tree_flags;
return( tree );
}
local TREEPTR ArrayIndex( TREEPTR tree, TREEPTR index_expr )
{
tree = GenIndex( tree, index_expr );
return( tree );
}
local TREEPTR IndexOp( TREEPTR tree, TREEPTR index_expr )
{
TYPEPTR typ;
if( tree->op.opr == OPR_ERROR ) return( tree );
typ = tree->expr_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_ARRAY ) {
tree = ArrayIndex( tree, index_expr );
} else if( typ->decl_type == TYPE_POINTER ) {
tree = GenIndex( RValue(tree), index_expr );
} else { /* try index[array] */
typ = index_expr->expr_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_ARRAY ) {
tree = ArrayIndex( index_expr, tree );
} else if( typ->decl_type == TYPE_POINTER ) {
tree = GenIndex( RValue(index_expr), tree );
} else {
CErr1( ERR_EXPR_MUST_BE_ARRAY );
FreeExprTree( index_expr );
tree = ErrorNode( tree );
}
}
MustRecog( T_RIGHT_BRACKET );
return( tree );
}
local void AddCallNode( TREEPTR tree ){
// if a function call has no proto type wait till end
// to check it out
call_list *new;
if( tree->left != NULL ){ // could be errors
new = CMemAlloc( sizeof( call_list ) );
new->next = NULL;
new->callnode = tree;
new->source_fno = SrcFno;
new->srclinenum = SrcLineNum;
*LastCallLnk = new;
LastCallLnk = &new->next;
}
}
void ChkCallNode( TREEPTR tree ){
call_list **lnk;
call_list *curr;
lnk = FirstCallLnk;
while( (curr = *lnk) != NULL ){
if( curr->callnode == tree ){
curr->callnode = NULL;
break;
}
lnk = &curr->next;
}
}
static int ParmNum( void ){
// get current parm num
int parm_count,n;
parm_count = 1;
n = Level;
while( Token[ n ] != T_LEFT_PAREN ) {
--n;
++parm_count;
}
return( parm_count );
}
local TREEPTR GenNextParm( TREEPTR tree, TYPEPTR **plistptr )
{
TYPEPTR *plist;
TYPEPTR typ;
TYPEPTR typ2;
TYPEPTR parm_typ;
tree = RValue( tree );
if( tree->op.opr == OPR_ERROR ) return( tree );
typ = SkipTypeFluff( tree->expr_type );
plist = *plistptr;
if( plist != NULL ) {
if( *plist == NULL || (*plist)->decl_type == TYPE_VOID ){ // To many parm trees
#if _CPU == 386
/* can allow wrong number of parms with -3s option; 06-dec-91 */
if( ! CompFlags.register_conventions ) {
CWarn1( WARN_PARM_COUNT_MISMATCH, ERR_PARM_COUNT_WARNING );
}else{
CErr1( ERR_PARM_COUNT_MISMATCH ); /* 18-feb-90 */
}
#else
CErr1( ERR_PARM_COUNT_MISMATCH ); /* 18-feb-90 */
#endif
*plist = GetType( TYPE_DOT_DOT_DOT ); //shut up message
plist = NULL;
} else if( (*plist)->decl_type == TYPE_DOT_DOT_DOT ) {
plist = NULL;
}
}
if( plist != NULL ) { //do conversion from tree to parm type
parm_typ = *plist;
ParmAsgnCheck( parm_typ, tree, ParmNum() );
if( parm_typ != NULL ) {
parm_typ = SkipTypeFluff( parm_typ );
if( parm_typ != typ ) {
if( parm_typ->decl_type == TYPE_POINTER && /* 08-jun-89 */
typ->decl_type != TYPE_POINTER ) {
if( tree->op.opr == OPR_PUSHINT ) {
if( tree->op.long_value == 0 ) { /* 22-sep-89 */
typ = parm_typ;
tree = ParmAss( tree, typ );
}
}
} else if( typ->decl_type != TYPE_POINTER ||/* 26-may-89 */
parm_typ->decl_type == TYPE_POINTER ) { /* 04-jun-89 */
typ = parm_typ;
switch( typ->decl_type ) { /* 25-may-91 */
case TYPE_STRUCT:
case TYPE_UNION:
break;
default:
tree = ParmAss( tree, typ );
break;
}
}
}
++*plistptr;
}
} else {
if( typ->decl_type == TYPE_FLOAT ) { // default conversions
typ = GetType( TYPE_DOUBLE );
tree = ParmAss( tree, typ );
} else if( typ->decl_type == TYPE_POINTER ) { /* 17-nov-88 */
typ2 = typ->object;
while( typ2->decl_type == TYPE_TYPEDEF ) typ2 = typ2->object;
if( typ2->decl_type != TYPE_FUNCTION ) {
if( typ->u.p.decl_flags & FLAG_NEAR ) {
if( DataPtrSize == TARGET_FAR_POINTER ) {
typ = PtrNode( typ2, FLAG_NONE, SEG_DATA );
tree = ParmAss( tree, typ );
}
}
}
}
}
if( typ->decl_type == TYPE_POINTER ) typ = typ->object;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_DOUBLE ||
typ->decl_type == TYPE_FLOAT ) {
CompFlags.float_used = 1;
}
return( tree );
}
local int IntrinsicMathFunc( SYM_NAMEPTR sym_name, int i, int n, SYMPTR sym )
{
auto char func_name[6];
if( far_strcmp( sym_name, MathFuncs[i].name, n ) == 0 ) return( 1 );
if( sym->flags & SYM_INTRINSIC ) {
strcpy( func_name, &MathFuncs[i].name[2] );/* copy name without __ */
strlwr( func_name );
if( far_strcmp( sym_name, func_name, n ) == 0 ) return( 1 );
}
return( 0 ); /* indicate not a math intrinsic function */
}
#if _MACHINE == _ALPHA || _MACHINE == _PPC
local TREEPTR GenVaStartNode( TREEPTR last_parm )
{
// there should be 3 parms __builtin_va_start( list, parm_name, stdarg )
// - first parm should be name of va_list
// - second parm should be name of the parameter before the ...
// - last_parm should be an integer 0 or 1 (0=>varargs, 1=>stdarg)
SYMPTR sym;
SYM_HANDLE parm_list;
int offset;
TREEPTR parmsym;
TREEPTR tree;
tree = NULL;
if( Level >= 2 &&
Token[Level] != T_LEFT_PAREN &&
Token[Level-1] != T_LEFT_PAREN &&
Token[Level-2] == T_LEFT_PAREN ) {
offset = 0;
if( last_parm->op.opr == OPR_PUSHINT &&
last_parm->op.long_value == 0 ) { // varargs.h
offset = -8;
}
parmsym = ValueStack[Level]; // get name of parameter
parm_list = 0;
if( parmsym->op.opr == OPR_PUSHSYM ) {
parm_list = CurFunc->u.func.parms;
while( parm_list != 0 ) {
sym = SymGetPtr( parm_list );
offset += (SizeOfArg( sym->sym_type ) + 7) & -8;
if( parm_list == parmsym->op.sym_handle ) break;
parm_list = sym->handle;
}
}
if( offset == 0 || parm_list == 0 ) {
// error: name not found in parm list
sym = SymGetPtr( parmsym->op.sym_handle );
CErr2p( ERR_SYM_NOT_IN_PARM_LIST,
SymName( sym, parmsym->op.sym_handle ) );
}
FreeExprNode( parmsym );
tree = ValueStack[ Level - 1 ];
if( tree->op.opr == OPR_PUSHSYM ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -