ASM Changes in PB 4.40?
Posted: Tue Feb 02, 2010 7:19 pm
hello,
i have a problem with this eval algo. It works with pb4.3 but not in
pb4.4. The problem is on AllocateMemory... HoldSize is 0 ive marked it at
the beginning
i have a problem with this eval algo. It works with pb4.3 but not in
pb4.4. The problem is on AllocateMemory... HoldSize is 0 ive marked it at
the beginning
Code: Select all
Procedure.s DS_XS_Evaluate(Expression.s)
If FindString(Expression.s,"'",0)>0
ProcedureReturn DS_XS_Concatenate(Expression.s)
EndIf
;
;{ Set ASM Equivalents
!r_HoldChar equ Esp+8
!r_HoldBegin equ Esp+12
!r_HoldEnd equ Esp+16
!r_Length equ Esp+96
!r_HoldSize equ Esp+100
!r_MemPosition equ Esp+108
;}
;
;{ Create Local Variables
iLoop.l
;
*HoldChar.Byte = @Expression
;
HoldBegin.l = -1
;
HoldEnd.l = -1
;
Decimal.b
;
LevelMaximum.l
;
Space.b
;
LevelNext.l
;
LevelCurrent.l
;
LevelParanthesis.l
;
DecimalLeft.b : DecimalRight.b
;
ValueLeft.l : ValueRight.l
;
FloatLeft.f : FloatRight.f
;
ValueResult.l : FloatResult.f
;
*HoldLevel.Long : *HoldOperator.Byte : *HoldValue.Long : *HoldFloat.Float : *HoldDecimal.Byte
;
*LevelCurrent.Long
;
length.l = Len(Expression)
;
HoldSize.l
;
!MOV Eax, dword[r_Length]
; Store Length in eax.
!LEA Eax, [Eax*4+Eax]
!ADD Eax, Eax
; Multiplication by 10 trick by El_Choni ( http://www.purebasic.fr/english/viewtopic.php?t=10476 )
!ADD Eax, dword[r_Length]
!ADD Eax, dword[r_Length]
!ADD Eax, dword[r_Length]
!ADD Eax, dword[r_Length]
; Add length back to it to get a multiply times 14
!MOV dword[r_HoldSize], Eax
; Store the allocation size in HoldSize.
*Memory.l = AllocateMemory(HoldSize) ; HERE HoldSize is 0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*MemPosition.l = *Memory
;
;}
;
!MOV Esi, 1
; esi is a 0 based index counter.
For iLoop = 1 To length
;
If *HoldChar\b > 47 And *HoldChar\b < 58 ; 0-9
;
;{ Value Handling
;
If HoldBegin = -1
;
!MOV [r_HoldBegin], Esi
;
Else
;
If Space : FreeMemory(*Memory) : ProcedureReturn "ERR-Missing Operator" : EndIf
;
EndIf
;
!MOV [r_HoldEnd], Esi
;
Space = #False
;
;}
;
ElseIf *HoldChar\b = 43 ; +
;
;{ Handle Addition
*HoldLevel = *MemPosition
*HoldLevel\l = 8 + LevelParanthesis
;
*MemPosition + 4
;
*HoldOperator = *MemPosition
*HoldOperator\b = 43
;
!INC dword[r_MemPosition]
;
If Decimal = 0
;
*HoldValue = *MemPosition
*HoldValue\l = Val(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 8
; Skip the float falue.
Else
;
*MemPosition + 4
;
*HoldFloat = *MemPosition
*HoldFloat\f = ValF(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 4
;
EndIf
;
*HoldDecimal = *MemPosition
*HoldDecimal\b = Decimal
;
!INC dword[r_MemPosition]
;
HoldBegin = -1 : HoldEnd = -1 : Decimal = 0
;
If LevelMaximum < *HoldLevel\l : LevelMaximum = *HoldLevel\l : EndIf
;
Space = #False
;
;}
;
ElseIf *HoldChar\b = 45 ; -
;
;{ Handle Subtraction
If HoldBegin = -1
;
!MOV [r_HoldBegin], Esi
;
Else
;
*HoldLevel = *MemPosition
*HoldLevel\l = 8 + LevelParanthesis
;
*MemPosition + 4
;
*HoldOperator = *MemPosition
*HoldOperator\b = 45
;
!INC dword[r_MemPosition]
;
If Decimal = 0
;
*HoldValue = *MemPosition
*HoldValue\l = Val(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 8
; Skip the float falue.
Else
;
*MemPosition + 4
;
*HoldFloat = *MemPosition
*HoldFloat\f = ValF(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 4
;
EndIf
;
*HoldDecimal = *MemPosition
*HoldDecimal\b = Decimal
;
!INC dword[r_MemPosition]
;
HoldBegin = -1 : HoldEnd = -1 : Decimal = 0
;
If LevelMaximum < *HoldLevel\l : LevelMaximum = *HoldLevel\l : EndIf
;
EndIf
;
Space = #False
;
;}
;
ElseIf *HoldChar\b = 42 ; *
;
;{ Handle Multiplication
*HoldLevel = *MemPosition
*HoldLevel\l = 9 + LevelParanthesis
;
*MemPosition + 4
;
*HoldOperator = *MemPosition
*HoldOperator\b = 42
;
!INC dword[r_MemPosition]
;
If Decimal = 0
;
*HoldValue = *MemPosition
*HoldValue\l = Val(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 8
; Skip the float falue.
Else
;
*MemPosition + 4
;
*HoldFloat = *MemPosition
*HoldFloat\f = ValF(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 4
;
EndIf
;
*HoldDecimal = *MemPosition
*HoldDecimal\b = Decimal
;
!INC dword[r_MemPosition]
;
HoldBegin = -1 : HoldEnd = -1 : Decimal = 0
;
If LevelMaximum < *HoldLevel\l : LevelMaximum = *HoldLevel\l : EndIf
;
Space = #False
;
;}
;
ElseIf *HoldChar\b = 47 ; /
;
;{ Handle Division
*HoldLevel = *MemPosition
*HoldLevel\l = 9 + LevelParanthesis
;
*MemPosition + 4
;
*HoldOperator = *MemPosition
*HoldOperator\b = 47
;
!INC dword[r_MemPosition]
;
If Decimal = 0
;
*HoldValue = *MemPosition
*HoldValue\l = Val(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 8
; Skip the float falue.
Else
;
*MemPosition + 4
;
*HoldFloat = *MemPosition
*HoldFloat\f = ValF(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 4
;
EndIf
;
*HoldDecimal = *MemPosition
*HoldDecimal\b = Decimal
;
!INC dword[r_MemPosition]
;
HoldBegin = -1 : HoldEnd = -1 : Decimal = 0
;
If LevelMaximum < *HoldLevel\l : LevelMaximum = *HoldLevel\l : EndIf
;
Space = #False
;
;}
;
ElseIf *HoldChar\b = 32 ; " "
;
Space = #True
;
ElseIf *HoldChar\b = 40 ; (
;
LevelParanthesis + 100
;
ElseIf *HoldChar\b = 41 ; )
;
LevelParanthesis - 100
;
ElseIf *HoldChar\b = 46 ; .
;
;{ Decimal Handling
If HoldBegin = -1
;
ProcedureReturn "ERR-Invalid Float"
;
!MOV [r_HoldBegin], Esi ; HoldBegin
;
Else
;
If Space : ProcedureReturn "ERR-Missing Operator" : EndIf
;
EndIf
;
!MOV [r_HoldEnd], Esi ; HoldEnd
;
Decimal = #True
;
Space = #False
;}
;
ElseIf *HoldChar\b = 37 ; %
;
;{ Handle Modulo
*HoldLevel = *MemPosition
*HoldLevel\l = 9 + LevelParanthesis
;
*MemPosition + 4
;
*HoldOperator = *MemPosition
*HoldOperator\b = 37
;
!INC dword[r_MemPosition]
;
If Decimal = 0
;
*HoldValue = *MemPosition
*HoldValue\l = Val(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 8
; Skip the float falue.
Else
;
*MemPosition + 4
;
*HoldFloat = *MemPosition
*HoldFloat\f = ValF(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 4
;
EndIf
;
*HoldDecimal = *MemPosition
*HoldDecimal\b = Decimal
;
!INC dword[r_MemPosition]
;
HoldBegin = -1 : HoldEnd = -1 : Decimal = 0
;
If LevelMaximum < *HoldLevel\l : LevelMaximum = *HoldLevel\l : EndIf
;
Space = #False
;
;}
;
ElseIf *HoldChar\b = 94 ; ^
;
;{ Handle Exponents
*HoldLevel = *MemPosition
*HoldLevel\l = 10 + LevelParanthesis
;
*MemPosition + 4
;
*HoldOperator = *MemPosition
*HoldOperator\b = 94
;
!INC dword[r_MemPosition]
;
If Decimal = 0
;
*HoldValue = *MemPosition
*HoldValue\l = Val(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 8
; Skip the float falue.
Else
;
*MemPosition + 4
;
*HoldFloat = *MemPosition
*HoldFloat\f = ValF(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 4
;
EndIf
;
*HoldDecimal = *MemPosition
*HoldDecimal\b = Decimal
;
!INC dword[r_MemPosition]
;
HoldBegin = -1 : HoldEnd = -1 : Decimal = 0
;
If LevelMaximum < *HoldLevel\l : LevelMaximum = *HoldLevel\l : EndIf
;
Space = #False
;
;}
;
EndIf
;
!INC dword[r_HoldChar] ; *HoldChar
; Increment to the next character.
!INC Esi
; Increment the index.
Next iLoop
;
If LevelMaximum = 0 : FreeMemory(*Memory) : ProcedureReturn Expression : EndIf
; The expression has no operators if no maximum level is set.
If HoldBegin = -1 : FreeMemory(*Memory) : ProcedureReturn "ERR-Invalid Operation" : EndIf
;
If LevelParanthesis <> 0 : ProcedureReturn "ERR-Imbalanced Paranthesis" : EndIf
;
;{ Handle EOL
*HoldLevel = *MemPosition
*HoldLevel\l = -1
;
*MemPosition + 4
;
*HoldOperator = *MemPosition
*HoldOperator\b = 0
;
!INC dword[r_MemPosition]
;
If Decimal = 0
;
*HoldValue = *MemPosition
*HoldValue\l = Val(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 8
; Skip the float falue.
Else
;
*MemPosition + 4
;
*HoldFloat = *MemPosition
*HoldFloat\f = ValF(PeekS(@Expression + HoldBegin - 1, HoldEnd - HoldBegin + 1))
;
*MemPosition + 4
;
EndIf
;
*HoldDecimal = *MemPosition
*HoldDecimal\b = Decimal
;
;}
;
Decimal = #False
;
*MemPosition = *Memory
; Reset the position to the first element.
While LevelMaximum
; Repeat until the maximum level is 0.
*LevelCurrent = *MemPosition
; Store the current level for the operator.
If *LevelCurrent\l = LevelMaximum
; The operator level matches the maximum operator.
*MemPosition + 4
; Increment to the operator type.
;
;{ Retrieve Left/Right Hand Value Info
*HoldChar = *MemPosition
; Store the operator type.
!INC dword[r_MemPosition]
; Increment to the beginning of the left hand value.
ValueLeft = PeekL(*MemPosition)
;
*MemPosition + 4
;
FloatLeft = PeekF(*MemPosition)
;
*MemPosition + 4
; Increment to the decimal identifier.
DecimalLeft = PeekB(*MemPosition)
;
!INC dword[r_MemPosition]
; Increment to the level for the right hand value.
*MemPosition + 5
; Skip the level and operator for the right hand value.
ValueRight = PeekL(*MemPosition)
;
*MemPosition + 4
;
FloatRight = PeekF(*MemPosition)
;
*Position = *MemPosition
; Temporarily store the address to the string. This will be used to store the result of the expression.
;
*MemPosition + 4
; Increment to the decimal identifier.
*HoldDecimal = *MemPosition
;
!INC dword[r_MemPosition]
; Increment to the next element.
;
;}
;
;{ Handle Operators
If *HoldChar\b = 43
; Addition
If DecimalLeft And *HoldDecimal\b
FloatResult = FloatLeft + FloatRight
;
ElseIf DecimalLeft
FloatResult = FloatLeft + ValueRight : *HoldDecimal\b = 1
; The result will be a decimal format.
ElseIf *HoldDecimal\b
FloatResult = ValueLeft + FloatRight : *HoldDecimal\b = 1
Else
ValueResult = ValueLeft + ValueRight
EndIf
;
ElseIf *HoldChar\b = 45
; Subtraction
If DecimalLeft And *HoldDecimal\b
FloatResult = FloatLeft - FloatRight
ElseIf DecimalLeft
FloatResult = FloatLeft - ValueRight : *HoldDecimal\b = 1
ElseIf *HoldDecimal\b
FloatResult = ValueLeft - FloatRight : *HoldDecimal\b = 1
Else
ValueResult = ValueLeft - ValueRight
EndIf
;
ElseIf *HoldChar\b = 42
; Multiplication
If DecimalLeft And *HoldDecimal\b
FloatResult = FloatLeft * FloatRight
ElseIf DecimalLeft
FloatResult = FloatLeft * ValueRight : *HoldDecimal\b = 1
ElseIf *HoldDecimal\b
FloatResult = ValueLeft * FloatRight : *HoldDecimal\b = 1
Else
ValueResult = ValueLeft * ValueRight
EndIf
;
ElseIf *HoldChar\b = 47
; Division
If DecimalLeft And *HoldDecimal\b
FloatResult = FloatLeft / FloatRight
ElseIf DecimalLeft
FloatResult = FloatLeft / ValueRight : *HoldDecimal\b = 1
ElseIf *HoldDecimal\b
FloatResult = ValueLeft / FloatRight : *HoldDecimal\b = 1
Else
FloatResult = ValueLeft / ValueRight : *HoldDecimal\b = 1
EndIf
;
ElseIf *HoldChar\b = 37
; Modulo
If DecimalLeft And *HoldDecimal\b
; FloatResult = FloatLeft * FloatRight : Decimal = #True
FreeMemory(*Memory)
ProcedureReturn "ERR-Cannot Use Floats With Modulo"
ElseIf DecimalLeft
; FloatResult = FloatLeft * ValueRight : Decimal = #True
; PokeB(*Position + 4, 1)
FreeMemory(*Memory)
ProcedureReturn "ERR-Cannot Use Floats With Modulo"
ElseIf *HoldDecimal\b
; FloatResult = ValueLeft * FloatRight : Decimal = #True
; PokeB(*Position + 4, 1)
FreeMemory(*Memory)
ProcedureReturn "ERR-Cannot Use Floats With Modulo"
Else
ValueResult = ValueLeft % ValueRight
EndIf
;
ElseIf *HoldChar\b = 94
; Exponents
If DecimalLeft And *HoldDecimal\b
FloatResult = Pow(FloatLeft, FloatRight)
ElseIf DecimalLeft
FloatResult = Pow(FloatLeft, ValueRight) : *HoldDecimal\b = 1
ElseIf *HoldDecimal\b
FloatResult = Pow(ValueLeft, FloatRight) : *HoldDecimal\b = 1
Else
ValueResult = Pow(ValueLeft, ValueRight)
EndIf
;
EndIf
;}
;
If *HoldDecimal\b : PokeF(*MemPosition - 5, FloatResult) : Else : PokeL(*MemPosition - 9, ValueResult) : EndIf
;
CopyMemory(*MemPosition - 14, *MemPosition - 28, HoldSize - ((*MemPosition - 14) - *Memory))
; This will effective remove the left hand value and overwrite with the newly calculated right hand value.
*MemPosition - 28
; Resume from the current position to see if there are any same-level operations.
Else
; The operator level is less than the maximum.
;{
If *LevelCurrent\l = 0
; Only occurs when the last element is reached.
If LevelNext = 0
; No more calculations.
Decimal = PeekB(*Memory + 13)
;
FreeMemory(*Memory)
; Free the memory used to store the elements.
If Decimal
ProcedureReturn StrF(FloatResult)
Else
ProcedureReturn Str(ValueResult)
EndIf
;
EndIf
;
LevelMaximum = LevelNext
; Assign the next maximum level.
*MemPosition = *Memory
; Reset to the beginning of the elements.
LevelNext = 0
; There is no lower level by default.
Else
;
If LevelNext < *LevelCurrent\l : LevelNext = *LevelCurrent\l : EndIf
; Assign the next lowest level.
*MemPosition + 14
;
EndIf
;}
;
EndIf
;
Wend
;
EndProcedure