📄 cexpr2.c
字号:
break;
case BASED_NONE:
break;
case BASED_SELFSEG: //__based( (__segment) __self ) use seg of self
tree->op.flags &= ~OPFLAG_RVALUE;
based_sym = ExprNode( tree, OPR_DUPE, NULL );
based_sym->op.flags |= OPFLAG_RVALUE;
based_sym->op.result_type = tree->op.result_type;
tree = MakeFarOp( based_sym, tree );
tree->right = NULL;
break;
case BASED_VAR: //__based( <var> ) add offset to var pointer
{
TYPEPTR typ;
TYPEPTR old;
old = tree->expr_type;
while( old->decl_type == TYPE_TYPEDEF ) old = old->object;
sym = SymGetPtr( sym_handle );
based_sym = VarLeaf( sym, sym_handle );
based_sym->op.opr = OPR_PUSHSYM;
typ = sym->sym_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->u.p.decl_flags & FLAG_BASED ){
based_sym = BasedPtrNode( typ, based_sym );
typ = based_sym->expr_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
}
old = PtrNode( old->object, typ->u.p.decl_flags, 0 );
tree = ExprNode( based_sym, OPR_ADD, tree );
tree->expr_type = old;
tree->op.result_type = old;
} break;
case BASED_SEGVAR: //__based( <var> ) add offset to seg var
sym = SymGetPtr( sym_handle );
based_sym = VarLeaf( sym, sym_handle );
based_sym->op.opr = OPR_PUSHSYM;
tree = MakeFarOp( based_sym, tree );
break;
case BASED_VARSEG: //__based( (__segment) <var> ) ) use seg of var
sym = SymGetPtr( sym_handle );
based_sym = FarPtrCvt( sym, sym_handle );
tree = MakeFarOp( based_sym, tree );
break;
case BASED_SEGNAME: //__based( __segname( "name" ) use seg of segname
if( sym_handle != 0 ){
sym = SymGetPtr( sym_handle );
based_sym = VarLeaf( sym, sym_handle );
based_sym->op.opr = OPR_PUSHSEG;
}else{ //error I guess
based_sym = LeafNode( OPR_PUSHINT );
based_sym->op.const_type = TYPE_INT;
based_sym->op.long_value = segid;
based_sym->expr_type = GetType( TYPE_USHORT );
}
tree = MakeFarOp( based_sym, tree );
}
return( tree );
}
TREEPTR PtrOp( TREEPTR tree )
{
TYPEPTR ptrtyp;
TYPEPTR typ;
type_modifiers flags;
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_POINTER ) {
CErr1( ERR_EXPR_MUST_BE_POINTER_TO );
return( ErrorNode( tree ) );
}
ptrtyp = typ;
flags = typ->u.p.decl_flags & PTR_FLAGS;
if( flags & FLAG_BASED ) {
tree = BasedPtrNode( typ, tree );
flags &= ~(FLAG_NEAR | FLAG_BASED);
flags |= FLAG_FAR;
}
tree = ExprNode( tree, OPR_POINTS, NULL );
typ = typ->object;
// while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
tree->expr_type = typ;
tree->op.result_type = ptrtyp;
tree->op.flags = OpFlags( flags );
if( SizeOfCount == 0 ) {
if( tree->op.flags & OPFLAG_VOLATILE){
CompFlags.useful_side_effect = 1;
}
}
return( tree );
}
FIELDPTR SearchFields( TYPEPTR *class_typ, unsigned long *field_offset,
char *name )
{
FIELDPTR field;
FIELDPTR subfield;
TYPEPTR typ;
TAGPTR tag;
tag = (*class_typ)->u.tag;
field = tag->u.field_list;
while( field != NULL ) {
typ = field->field_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( field->name[0] == '\0' ) { /* if nameless field: 15-sep-90 */
if( typ->decl_type == TYPE_STRUCT ||
typ->decl_type == TYPE_UNION ) {
subfield = SearchFields( &typ, field_offset, name );
if( subfield != NULL ) {
*field_offset += field->offset;
*class_typ = typ;
return( subfield );
}
}
} else if( strcmp( name, field->name ) == 0 ) {
if( typ->decl_type != TYPE_FUNCTION ) {
*field_offset += field->offset;
}
return( field );
}
field = field->next_field;
}
return( NULL );
}
local TYPEPTR Ptr2Struct( TYPEPTR typ )
{
if( typ->decl_type != TYPE_POINTER ) {
return( NULL );
}
typ = typ->object;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_STRUCT ||
typ->decl_type == TYPE_UNION ) {
return( typ );
}
return( NULL );
}
TREEPTR DotOp( TREEPTR tree )
{
TYPEPTR typ;
TYPEPTR get_typ;
FIELDPTR field;
unsigned long offset;
op_flags opflag;
SYM_ENTRY sym;
if( CurToken != T_ID ) {
CErr1( ERR_EXPECTING_ID );
return( ErrorNode( tree ) );
}
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_STRUCT &&
typ->decl_type != TYPE_UNION ) {
CErr1( ERR_MUST_BE_STRUCT_OR_UNION );
return( ErrorNode( tree ) );
}
get_typ = typ;
offset = 0;
field = SearchFields( &get_typ, &offset, Buffer );
if( field == NULL ) {
CErr( ERR_NAME_NOT_FOUND_IN_STRUCT, Buffer, typ->u.tag->name );
return( ErrorNode( tree ) );
}
typ = field->field_type;
opflag = tree->op.flags | OpFlags( field->attrib );
if( CompFlags.emit_browser_info ) { /* 27-oct-94 */
field->xref->next_xref = NewXref( field->xref->next_xref );
}
if( tree->op.opr == OPR_DOT || tree->op.opr == OPR_ARROW ) {
tree->right->op.ulong_value += offset;
} else {
if( tree->op.opr == OPR_PUSHADDR ) {
SymGet( &sym, tree->op.sym_handle );
if( !(sym.flags & SYM_ASSIGNED) ) {
sym.flags |= SYM_ASSIGNED;
SymReplace( &sym, tree->op.sym_handle );
}
}
tree = ExprNode( tree, OPR_DOT, UIntLeaf( offset ) );
}
tree->expr_type = typ;
tree->op.result_type = typ;
tree->op.flags = opflag;
return( tree );
}
TREEPTR DotOpNamed( TREEPTR tree, char *name )
{
TYPEPTR typ;
TYPEPTR get_typ;
FIELDPTR field;
unsigned long offset;
op_flags opflag;
SYM_ENTRY sym;
typ = tree->expr_type;
get_typ = typ;
offset = 0;
field = SearchFields( &get_typ, &offset, name );
if( field == NULL ) {
CErr( ERR_NAME_NOT_FOUND_IN_STRUCT, name, typ->u.tag->name );
return( ErrorNode( tree ) );
}
typ = field->field_type;
opflag = tree->op.flags | OpFlags( field->attrib );
if( CompFlags.emit_browser_info ) { /* 27-oct-94 */
field->xref->next_xref = NewXref( field->xref->next_xref );
}
if( tree->op.opr == OPR_DOT || tree->op.opr == OPR_ARROW ) {
tree->right->op.ulong_value += offset;
} else {
if( tree->op.opr == OPR_PUSHADDR ) {
SymGet( &sym, tree->op.sym_handle );
if( !(sym.flags & SYM_ASSIGNED) ) {
sym.flags |= SYM_ASSIGNED;
SymReplace( &sym, tree->op.sym_handle );
}
}
tree = ExprNode( tree, OPR_DOT, UIntLeaf( offset ) );
}
tree->expr_type = typ;
tree->op.result_type = typ;
tree->op.flags = opflag;
return( tree );
}
TREEPTR ArrowOp( TREEPTR tree )
{
TYPEPTR typ;
TYPEPTR get_typ;
FIELDPTR field;
unsigned long offset;
type_modifiers flags;
if( CurToken != T_ID ) {
CErr1( ERR_EXPECTING_ID );
return( ErrorNode( tree ) );
}
if( tree->op.opr == OPR_ERROR ) return( tree );
typ = tree->expr_type;
while( typ->decl_type == TYPE_TYPEDEF ) {
typ = typ->object;
}
if( Ptr2Struct( typ ) == NULL ) {
CErr1( ERR_MUST_BE_PTR_TO_STRUCT_OR_UNION );
return( ErrorNode( tree ) );
}
if( tree->op.opr == OPR_PUSHADDR ) {
tree->op.opr = OPR_PUSHSYM;
}
flags = typ->u.p.decl_flags & PTR_FLAGS; // get pointer flags
if( flags & FLAG_BASED ) {
tree = BasedPtrNode( typ, tree );
flags &= ~(FLAG_NEAR | FLAG_BASED);
flags |= FLAG_FAR;
}
typ = typ->object;
while( typ->decl_type == TYPE_TYPEDEF ) {
typ = typ->object;
}
get_typ = typ;
offset = 0;
field = SearchFields( &get_typ, &offset, Buffer );
if( field == NULL ) {
CErr( ERR_NAME_NOT_FOUND_IN_STRUCT, Buffer, typ->u.tag->name );
return( ErrorNode( tree ) );
}
if( CompFlags.emit_browser_info ) { /* 27-oct-94 */
field->xref->next_xref = NewXref( field->xref->next_xref );
}
tree = ExprNode( tree, OPR_ARROW, UIntLeaf( offset ) );
typ = field->field_type;
tree->expr_type = typ;
tree->op.result_type = typ;
flags |= field->attrib;
tree->op.flags |= OpFlags( flags );
return( tree );
}
TREEPTR IncDec( TREEPTR tree, TOKEN opr )
{
op_flags volatile_flag;
volatile_flag = tree->op.flags & OPFLAG_VOLATILE;
ChkConst( tree );
tree = AddOp( tree, opr, IntLeaf( 1 ) );
tree->op.flags |= volatile_flag;
CompFlags.meaningless_stmt = 0;
CompFlags.useful_side_effect = 1;
return( tree );
}
//-----------------------------CEXPR-----------------------------------
bool ConstExprAndType( const_val *val )
{
TREEPTR tree;
call_list **save;
bool ret;
save = FirstCallLnk;
++Level; /* allow for nested expressions */
tree = SingleExpr();
--Level; /* put Level back */
FirstCallLnk = save;
val->type = TYPE_INT;
switch( tree->op.opr ) {
case OPR_PUSHINT:
val->type = tree->op.const_type;
if( tree->op.const_type == TYPE_LONG64
|| tree->op.const_type == TYPE_ULONG64 ){
val->val64 = tree->op.long64_value;
}else{
val->val32 = tree->op.long_value;
}
ret = TRUE;
break;
case OPR_PUSHFLOAT:
CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
val->val32 = (long)atof( tree->op.float_value->string );
ret = FALSE;
break;
default:
if( tree->op.opr != OPR_ERROR ){
CErr1( ERR_NOT_A_CONSTANT_EXPR );
}
val->val32 = 0;
ret = FALSE;
break;
}
FreeExprTree( tree );
return( ret );
}
long int ConstExpr()
{
const_val val;
ConstExprAndType( &val );
return( val.val32 );
}
TREEPTR Expr()
{
Class[ Level ] = TC_START;
return( GetExpr() );
}
TREEPTR CommaExpr()
{
Class[ Level ] = TC_START1;
return( GetExpr() );
}
TREEPTR AddrExpr()
{
return( SingleExpr() );
}
TREEPTR SingleExpr()
{
TREEPTR tree;
Class[ Level ] = TC_START2;
tree = GetExpr();
FoldExprTree( tree );
return( tree );
}
local TREEPTR GetExpr()
{
TREEPTR tree, op1;
TYPEPTR typ;
char curclass;
auto TYPEPTR *plist;
CompFlags.useful_side_effect = 0;
FirstCallLnk = LastCallLnk;
tree = 0;
plist = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -