소스 검색

Fixed bitwise ops with consts. Fixes #550.

Brucey 4 년 전
부모
커밋
98a510da16
3개의 변경된 파일459개의 추가작업 그리고 2개의 파일을 삭제
  1. 43 0
      config.bmx
  2. 141 2
      expr.bmx
  3. 275 0
      math.c

+ 43 - 0
config.bmx

@@ -34,6 +34,9 @@ Import "base.stringhelper.bmx"
 Import "base64.bmx"
 Import "enums.c"
 Import "hash.c"
+?Not bmxng
+Import "math.c"
+?
 
 ' debugging help
 Const DEBUG:Int = False
@@ -717,6 +720,37 @@ Function CalculateFileHash:String(path:String)
 	Return Null
 End Function
 
+?Not bmxng
+Const OP_MUL:Int = 0
+Const OP_DIV:Int = 1
+Const OP_MOD:Int = 2
+Const OP_SHL:Int = 3
+Const OP_SHR:Int = 4
+Const OP_SAR:Int = 5
+Const OP_ADD:Int = 6
+Const OP_SUB:Int = 7
+Const OP_AND:Int = 8
+Const OP_XOR:Int = 9
+Const OP_OR:Int = 10
+
+Function OpToInt:Int(op:String)
+	Select op
+		Case "*" Return OP_MUL
+		Case "/" Return OP_DIV
+		Case "mod" Return OP_MOD
+		Case "shl" Return OP_SHL
+		Case "shr" Return OP_SHR
+		Case "sar" Return OP_SAR
+		Case "+" Return OP_ADD
+		Case "-" Return OP_SUB
+		Case "&" Return OP_AND
+		Case "~~" Return OP_XOR
+		Case "|" Return OP_OR
+	End Select
+	InternalErr "TBinaryMathExpr.Eval.OpToInt : " + op
+End Function
+?
+
 Extern
 	Function strlen_:Int(s:Byte Ptr)="strlen"
 	Function bmx_enum_next_power(char:Int, val:Long Var, ret:Long Var)
@@ -725,4 +759,13 @@ Extern
 	Function bmx_hash_reset(state:Byte Ptr)
 	Function bmx_hash_update(state:Byte Ptr, data:Byte Ptr, length:Int)
 	Function bmx_hash_digest:String(state:Byte Ptr)
+
+?Not bmxng
+	Function bmx_bitwise_not_uint:String(value:String)
+	Function bmx_bitwise_not_sizet:String(value:String)
+	Function bmx_bitwise_not_ulong:String(value:String)
+	Function bmx_binarymathexpr_sizet:String(op:Int, lhs:String, rhs:String)
+	Function bmx_binarymathexpr_uint:String(op:Int, lhs:String, rhs:String)
+	Function bmx_binarymathexpr_ulong:String(op:Int, lhs:String, rhs:String)
+?
 End Extern

+ 141 - 2
expr.bmx

@@ -1798,7 +1798,17 @@ Type TUnaryExpr Extends TExpr
 		Local val$=expr.Eval()
 		Select op
 		Case "~~"
-			Return ~Int( val )
+			If TIntType(exprType) Return ~Int( val )
+			If TLongType(exprType) Return ~Long( val )
+?Not bmxng
+			If TUIntType(exprType) Return bmx_bitwise_not_uint( val )
+			If TSizeTType(exprType) Return bmx_bitwise_not_sizet( val )
+			If TULongType(exprType) Return bmx_bitwise_not_ulong( val )
+?bmxng
+			If TUIntType(exprType) Return ~UInt( val )
+			If TSizeTType(exprType) Return ~Size_T( val )
+			If TULongType(exprType) Return ~ULong( val )
+?		
 		Case "+"
 			Return val
 		Case "-"
@@ -1983,7 +1993,7 @@ Type TBinaryMathExpr Extends TBinaryExpr
 			Case "~~" Return x ~ y
 			Case "|" Return x | y
 			End Select
-		Else If TLongType( exprType ) Or TSizeTType(exprType) Or TUIntType(exprType) Or TULongType(exprType) Or TInt128Type(exprType) Or TWParamType(exprType) Or TLParamType(exprType) 
+		Else If TLongType( exprType ) Or TInt128Type(exprType) Or TWParamType(exprType) Or TLParamType(exprType) 
 			Local x:Long=Long(lhs),y:Long=Long(rhs)
 			Select op
 			Case "^" Return Double(lhs)^Double(rhs)
@@ -2007,6 +2017,135 @@ Type TBinaryMathExpr Extends TBinaryExpr
 			Case "~~" Return x ~ y
 			Case "|" Return x | y
 			End Select
+		Else If TSizeTType(exprType)
+?bmxng
+			Local x:Size_T=Size_T(lhs),y:Size_T=Size_T(rhs)
+			Select op
+			Case "^" Return Double(lhs)^Double(rhs)
+			Case "*" Return x*y
+			Case "/"
+				If Not y Then
+					Err "Integer division by zero"
+				End If
+				Return x/y
+			Case "mod"
+				If Not y Then
+					Err "Integer division by zero"
+				End If
+				Return x Mod y
+			Case "shl" Return x Shl y
+			Case "shr" Return x Shr y
+			Case "sar" Return x Sar y
+			Case "+" Return x + y
+			Case "-" Return x - y
+			Case "&" Return x & y
+			Case "~~" Return x ~ y
+			Case "|" Return x | y
+			End Select
+?Not bmxng
+		Local opInt:Int = OpToInt(op)
+		Select op
+			Case "^" Return Double(lhs)^Double(rhs)
+			Case "/"
+				If Not Long(rhs) Then
+					Err "Integer division by zero"
+				End If
+				Return bmx_binarymathexpr_sizet(opInt, lhs, rhs)
+			Case "mod"
+				If Not Long(rhs) Then
+					Err "Integer division by zero"
+				End If
+				Return bmx_binarymathexpr_sizet(opInt, lhs, rhs)
+			Default
+				Return bmx_binarymathexpr_sizet(opInt, lhs, rhs)
+		End Select
+?
+		Else If TUIntType(exprType)
+?bmxng
+			Local x:UInt=UInt(lhs),y:UInt=UInt(rhs)
+			Select op
+			Case "^" Return Double(lhs)^Double(rhs)
+			Case "*" Return x*y
+			Case "/"
+				If Not y Then
+					Err "Integer division by zero"
+				End If
+				Return x/y
+			Case "mod"
+				If Not y Then
+					Err "Integer division by zero"
+				End If
+				Return x Mod y
+			Case "shl" Return x Shl y
+			Case "shr" Return x Shr y
+			Case "sar" Return x Sar y
+			Case "+" Return x + y
+			Case "-" Return x - y
+			Case "&" Return x & y
+			Case "~~" Return x ~ y
+			Case "|" Return x | y
+			End Select
+?Not bmxng
+		Local opInt:Int = OpToInt(op)
+		Select op
+			Case "^" Return Double(lhs)^Double(rhs)
+			Case "/"
+				If Not Long(rhs) Then
+					Err "Integer division by zero"
+				End If
+				Return bmx_binarymathexpr_uint(opInt, lhs, rhs)
+			Case "mod"
+				If Not Long(rhs) Then
+					Err "Integer division by zero"
+				End If
+				Return bmx_binarymathexpr_uint(opInt, lhs, rhs)
+			Default
+				Return bmx_binarymathexpr_uint(opInt, lhs, rhs)
+		End Select
+?
+		Else If TULongType(exprType)
+?bmxng
+			Local x:ULong=ULong(lhs),y:ULong=ULong(rhs)
+			Select op
+			Case "^" Return Double(lhs)^Double(rhs)
+			Case "*" Return x*y
+			Case "/"
+				If Not y Then
+					Err "Integer division by zero"
+				End If
+				Return x/y
+			Case "mod"
+				If Not y Then
+					Err "Integer division by zero"
+				End If
+				Return x Mod y
+			Case "shl" Return x Shl y
+			Case "shr" Return x Shr y
+			Case "sar" Return x Sar y
+			Case "+" Return x + y
+			Case "-" Return x - y
+			Case "&" Return x & y
+			Case "~~" Return x ~ y
+			Case "|" Return x | y
+			End Select
+?Not bmxng
+		Local opInt:Int = OpToInt(op)
+		Select op
+			Case "^" Return Double(lhs)^Double(rhs)
+			Case "/"
+				If Not Long(rhs) Then
+					Err "Integer division by zero"
+				End If
+				Return bmx_binarymathexpr_ulong(opInt, lhs, rhs)
+			Case "mod"
+				If Not Long(rhs) Then
+					Err "Integer division by zero"
+				End If
+				Return bmx_binarymathexpr_ulong(opInt, lhs, rhs)
+			Default
+				Return bmx_binarymathexpr_ulong(opInt, lhs, rhs)
+		End Select
+?
 		Else If TFloatType( exprType )
 			Local x:Double=Double(lhs),y:Double=Double(rhs)
 			Select op

+ 275 - 0
math.c

@@ -0,0 +1,275 @@
+
+#include <brl.mod/blitz.mod/blitz.h>
+
+enum binaryOps {
+	OP_MUL,
+	OP_DIV,
+	OP_MOD,
+	OP_SHL,
+	OP_SHR,
+	OP_SAR,
+	OP_ADD,
+	OP_SUB,
+	OP_AND,
+	OP_XOR,
+	OP_OR
+};
+
+unsigned int bmx_string_to_uint( BBString *t ){
+	int i=0,neg=0;
+	unsigned n=0;
+	
+	while( i<t->length && isspace(t->buf[i]) ) ++i;
+	if( i==t->length ) return 0;
+	
+	if( t->buf[i]=='+' ) ++i;
+	else if( (neg = t->buf[i]=='-') ) ++i;
+	if( i==t->length ) return 0;
+
+	if( t->buf[i]=='%' ){
+		for( ++i;i<t->length;++i ){
+			int c=t->buf[i];
+			if( c!='0' && c!='1' ) break;
+			n=n*2+(c-'0');
+		}
+	}else if( t->buf[i]=='$' ){
+		for( ++i;i<t->length;++i ){
+			int c=toupper(t->buf[i]);
+			if( !isxdigit(c) ) break;
+			if( c>='A' ) c-=('A'-'0'-10);
+			n=n*16+(c-'0');
+		}
+	}else{
+		for( ;i<t->length;++i ){
+			int c=t->buf[i];
+			if( !isdigit(c) ) break;
+			n=n*10+(c-'0');
+		}
+	}
+	return neg ? -n : n;
+}
+
+unsigned long long bmx_string_to_ulong( BBString *t ){
+	int i=0,neg=0;
+	unsigned long long n=0;
+	
+	while( i<t->length && isspace(t->buf[i]) ) ++i;
+	if( i==t->length ){ return 0; }
+	
+	if( t->buf[i]=='+' ) ++i;
+	else if( (neg = t->buf[i]=='-') ) ++i;
+	if( i==t->length ){ return 0; }
+	
+	if( t->buf[i]=='%' ){
+		for( ++i;i<t->length;++i ){
+			int c=t->buf[i];
+			if( c!='0' && c!='1' ) break;
+			n=n*2+(c-'0');
+		}
+	}else if( t->buf[i]=='$' ){
+		for( ++i;i<t->length;++i ){
+			int c=toupper(t->buf[i]);
+			if( !isxdigit(c) ) break;
+			if( c>='A' ) c-=('A'-'0'-10);
+			n=n*16+(c-'0');
+		}
+	}else{
+		for( ;i<t->length;++i ){
+			int c=t->buf[i];
+			if( !isdigit(c) ) break;
+			n=n*10+(c-'0');
+		}
+	}
+	return neg ? -n : n;
+}
+
+size_t bmx_string_to_size_t( BBString *t ){
+	int i=0,neg=0;
+	size_t n=0;
+	
+	while( i<t->length && isspace(t->buf[i]) ) ++i;
+	if( i==t->length ){ return 0; }
+	
+	if( t->buf[i]=='+' ) ++i;
+	else if( (neg=(t->buf[i]=='-')) ) ++i;
+	if( i==t->length ){ return 0; }
+	
+	if( t->buf[i]=='%' ){
+		for( ++i;i<t->length;++i ){
+			int c=t->buf[i];
+			if( c!='0' && c!='1' ) break;
+			n=n*2+(c-'0');
+		}
+	}else if( t->buf[i]=='$' ){
+		for( ++i;i<t->length;++i ){
+			int c=toupper(t->buf[i]);
+			if( !isxdigit(c) ) break;
+			if( c>='A' ) c-=('A'-'0'-10);
+			n=n*16+(c-'0');
+		}
+	}else{
+		for( ;i<t->length;++i ){
+			int c=t->buf[i];
+			if( !isdigit(c) ) break;
+			n=n*10+(c-'0');
+		}
+	}
+	return neg ? -n : n;
+}
+
+BBString *bmx_string_from_uint( unsigned int n ){
+	char buf[64];
+	sprintf(buf, "%u", n);
+	return bbStringFromBytes( (unsigned char*)buf, strlen(buf) );
+}
+
+BBString *bmx_string_from_ulong( unsigned long long n ){
+	char buf[64];
+	sprintf(buf, "%llu", n);
+	return bbStringFromBytes( (unsigned char*)buf, strlen(buf) );
+}
+
+BBString *bmx_string_from_size_t( size_t n ){
+	char buf[64];
+#if UINTPTR_MAX == 0xffffffff
+	sprintf(buf, "%u", n);
+#else
+	sprintf(buf, "%llu", n);
+#endif
+	return bbStringFromBytes( (unsigned char*)buf, strlen(buf) );
+}
+
+BBString * bmx_bitwise_not_uint(BBString * value) {
+	unsigned int v = bmx_string_to_uint(value);
+	return bmx_string_from_uint(~v);
+}
+
+BBString * bmx_bitwise_not_sizet(BBString * value) {
+	size_t v = bmx_string_to_size_t(value);
+	return bmx_string_from_size_t(~v);
+}
+
+BBString * bmx_bitwise_not_ulong(BBString * value) {
+	unsigned long long v = bmx_string_to_ulong(value);
+	return bmx_string_from_ulong(~v);
+}
+
+BBString * bmx_binarymathexpr_sizet(enum binaryOps op, BBString * slhs, BBString * srhs) {
+	size_t lhs = bmx_string_to_size_t(slhs);
+	size_t rhs = bmx_string_to_size_t(srhs);
+	size_t res = 0;
+	switch (op) {
+		case OP_MUL:
+			res = lhs * rhs;
+			break;
+		case OP_DIV:
+			res = lhs / rhs;
+			break;
+		case OP_MOD:
+			res = lhs % rhs;
+			break;
+		case OP_SHL:
+			res = lhs << rhs;
+			break;
+		case OP_SHR:
+		case OP_SAR:
+			res = lhs >> rhs;
+			break;
+		case OP_ADD:
+			res = lhs + rhs;
+			break;
+		case OP_SUB:
+			res = lhs - rhs;
+			break;
+		case OP_AND:
+			res = lhs & rhs;
+			break;
+		case OP_XOR:
+			res = lhs ^ rhs;
+			break;
+		case OP_OR:
+			res = lhs | rhs;
+			break;
+	}
+	return bmx_string_from_size_t(res);
+}
+
+BBString * bmx_binarymathexpr_uint(enum binaryOps op, BBString * slhs, BBString * srhs) {
+	unsigned int lhs = bmx_string_to_uint(slhs);
+	unsigned int rhs = bmx_string_to_uint(srhs);
+	unsigned int res = 0;
+	switch (op) {
+		case OP_MUL:
+			res = lhs * rhs;
+			break;
+		case OP_DIV:
+			res = lhs / rhs;
+			break;
+		case OP_MOD:
+			res = lhs % rhs;
+			break;
+		case OP_SHL:
+			res = lhs << rhs;
+			break;
+		case OP_SHR:
+		case OP_SAR:
+			res = lhs >> rhs;
+			break;
+		case OP_ADD:
+			res = lhs + rhs;
+			break;
+		case OP_SUB:
+			res = lhs - rhs;
+			break;
+		case OP_AND:
+			res = lhs & rhs;
+			break;
+		case OP_XOR:
+			res = lhs ^ rhs;
+			break;
+		case OP_OR:
+			res = lhs | rhs;
+			break;
+	}
+	return bmx_string_from_uint(res);
+}
+
+BBString * bmx_binarymathexpr_ulong(enum binaryOps op, BBString * slhs, BBString * srhs) {
+	unsigned long long lhs = bmx_string_to_ulong(slhs);
+	unsigned long long rhs = bmx_string_to_ulong(srhs);
+	unsigned long long res = 0;
+	switch (op) {
+		case OP_MUL:
+			res = lhs * rhs;
+			break;
+		case OP_DIV:
+			res = lhs / rhs;
+			break;
+		case OP_MOD:
+			res = lhs % rhs;
+			break;
+		case OP_SHL:
+			res = lhs << rhs;
+			break;
+		case OP_SHR:
+		case OP_SAR:
+			res = lhs >> rhs;
+			break;
+		case OP_ADD:
+			res = lhs + rhs;
+			break;
+		case OP_SUB:
+			res = lhs - rhs;
+			break;
+		case OP_AND:
+			res = lhs & rhs;
+			break;
+		case OP_XOR:
+			res = lhs ^ rhs;
+			break;
+		case OP_OR:
+			res = lhs | rhs;
+			break;
+	}
+	return bmx_string_from_ulong(res);
+}