Author Topic: Expression evaluator  (Read 19465 times)

0 Members and 1 Guest are viewing this topic.

Aurel

  • Guest
Re: Expression evaluator
« Reply #30 on: December 08, 2013, 04:46:36 AM »
Hi Charles...
So you look in interpreter source code and try i think.
I hope that you find same memory leak connected with expression evaluation like me.
Because it is really strange that loop without calculation don't produce
mem leak ,when loop with calc inside loop produce mem leak proprtional with number
of iteration... ::)

Charles Pegge

  • Guest
Re: Expression evaluator
« Reply #31 on: December 08, 2013, 03:28:13 PM »
Hi Aurel,

I have not had time to test your code. I've plugged the 2 identified memory leaks. If it still leaks, then perhaps you can isolate the line where this occurs.

http://www.oxygenbasic.org/forum/index.php?topic=749

Aurel

  • Guest
Re: Expression evaluator
« Reply #32 on: December 08, 2013, 03:57:47 PM »
Ok Charles...
I will try ;)

Aurel

  • Guest
Re: Expression evaluator
« Reply #33 on: December 15, 2013, 10:48:47 AM »
Hi Charles
After two days of hunt and fight with mem leak i think that i found what is problem.
There is no difference with last version of oxygen and one i used before.
Problem i have found in local string array which is not released after RETURN is executed.
Your expression evaluator work perfect and very fast in my case also as few others
without producing any mem leak...which is good i think.
so ..here is code where memory growe...

Code: [Select]
SUB exec_SET
'STRING arg[20]  'after RETURN this LOCAL string array is NOT released
INT n=1
'count
'arg[n]=arg1[PC]
'If arg[n]=""
' Return
     'Else
   if n=1   
       ParseExpr(arg1[PC])
          ' true if is not empty
           ' because is true RETURN must work ?
    End If
' do i must use EXIT SUB ? why is next line executed after RETURN?
If arg2[PC] = "" then Return

this string array is constantly invoked inside loop and that is my mistake
because i think that should be relesed after exiting subroutine but is not...
is this normal ? ...i don't know  ::)
( i will also remove some similar parts in interpreter too)

Another thing which i often see is that print(messagebox) ignore RETURN command and is
executed ...
Is EXIT SUB same as RETURN ?
I mean is EXIT SUB return execution to position from where is called specific subroutine?

thanks Aurel ;)

JRS

  • Guest
Re: Expression evaluator
« Reply #34 on: December 15, 2013, 11:40:42 AM »
Quote
Is EXIT SUB same as RETURN ?

Aurel,

My understanding is that EXIT SUB is a way to prematurely exit a SUBroutine (function with no return value). Same as the EXIT FUNCTION related directive. Keep in mind the GOSUB/RETURN must respect the scope it's within. You can't jump out of a FUNCTION/SUB with a GOTO/GOSUB directive. You can do a GOTO/GOSUB within the scope of a FUNCTION/SUB. (or MAIN)

Hope this helps.

John

Peter

  • Guest
Re: Expression evaluator
« Reply #35 on: December 15, 2013, 11:51:47 AM »
Is EXIT SUB same as RETURN ?

Yes.

Aurel

  • Guest
Re: Expression evaluator
« Reply #36 on: December 15, 2013, 11:53:36 AM »
John
This is not the point of my question for Charles.
I want to know if EXIT SUB work as RETURN or in another words
RETURN must work as EXIT SUB ...right?
without executing any code after RETURN is executed..ok...
There are some quirks but it is not problem for me at all
i use in many places EXIT DO ,EXIT FOR,EXIT WHILE etc..etc

Aurel

  • Guest
Re: Expression evaluator
« Reply #37 on: December 15, 2013, 11:54:53 AM »
Quote
Is EXIT SUB same as RETURN ?
Yes.

hi Peter ..thanks  ;)

Peter

  • Guest
Re: Expression evaluator
« Reply #38 on: December 15, 2013, 12:15:46 PM »
Hi Aurel,
Code: [Select]
include "sw.inc"
window 320,240,1

Sub MyExitSub()
    static sys count
    iF count >=100
       Cls RGB(Rnd(128,255),Rnd(128,255),Rnd(128,255))
       Return
    End iF
    Text 50,50,"Wait.. " + count,0
    count +=1
End Sub   
   
while Key(27)=0
  Cls sw_white
  MyExitSub
  Sync
  SetFps (24)
wend
CloseWindow
   

Charles Pegge

  • Guest
Re: Expression evaluator
« Reply #39 on: December 16, 2013, 03:36:26 AM »
Hi Aurel,

In a sub, return produces the same machine code as exit sub. local and temporary strings are always cleared before the routine terminates.

Could you try this code and see what memory consumption you get:

Code: [Select]
string arg[100]


sub f()
  sys n=2
  arg[16]=space 1000
  arg[n]=arg[16]
  if arg[n]="" then return
  return
end sub


function g(sys a)
  for i=1 to a
    f
  next
end function


print "" 'check for mem in task manager
g 10000
print "" 'check for mem in task manager: max increase: ~16k (Vista PC)

Aurel

  • Guest
Re: Expression evaluator
« Reply #40 on: December 16, 2013, 04:08:51 AM »
Ok Charles..
I try and after first message i get 1.928 K
after second ........................... 1.956 K

is your  result same ?
It looks that is some increase of memory..right ?
just after 2 turn 

Peter

  • Guest
Re: Expression evaluator
« Reply #41 on: December 16, 2013, 05:20:44 AM »
I got this here:  2 empty messageboxes



.
« Last Edit: December 16, 2013, 06:35:11 AM by peter »

Charles Pegge

  • Guest
Re: Expression evaluator
« Reply #42 on: December 16, 2013, 08:53:36 AM »
Okay, that looks like OS working-memory. No leaks.

Turn arg[] into a bstring, and you will get a memory accumulation of about 18 meg. (g 10000)

Aurel

  • Guest
Re: Expression evaluator
« Reply #43 on: December 18, 2013, 01:56:53 PM »
Hi Charles...
I try replace string arg[] with bstring arg[] and
there is no any change in memory consumption but maybe i'm wrong.

However ...
After long fight with memory leaks in expr parser (by joske)
i figured that i can free string with frees s
and i also replace all input strings (inside function definition) with local strings
like this:
Code: [Select]
FUNCTION Eval_Expr(string in) as FLOAT

STRING expr,op
frees expr

expr = in


and it looks that memory leak gone probably because this function is used many times
inside loops and string expr accumulate lot of space...right?
thanks again on suggestions... ;)

Aurel

  • Guest
Re: Expression evaluator
« Reply #44 on: February 18, 2015, 01:37:47 AM »
and this is crazy evaluator... ;D

Code: [Select]
Function VisibleToken(STRING s) as string
  Select s
    Case CR
'      s = "newline"
    Case LF
    '  s = "newline"
    Case ""
    '  s = "nothing"
  End Select
  Return s
End Function

';Cleanup then end
Function Finish()
  perr=1
Return 0
End Function

';Report an error
Function Error(string s)
  print "Error: " + s + "."
End Function

';Report an error and abort
Function Abort(STRING s)
  Error(s)
  Finish()
End Function

';Report what was expected
Function Expected(STRING expect)
  Abort("Expected: " + expect + ", got '" + VisibleToken(Look) + "'")
Return 0
End Function

';Read a character into Look
Goto GetChar_End
sub GetChar
'print "SUB->GETCHAR"
  Look = Mid (Stream ,StreamPos,1)
  'print "LOOK:" + Look
  StreamPos =  StreamPos + 1
  Return
end sub
GetChar_End:


';Match a specific input character
Function Match(STRING s)
'print "MATCH<s>" + s
  If Look <> s
'print "MATCH<Look>" + Look
    Expected("'"+ s +"'")
  Else
'print "MATCH<else>"
    Gosub getchar
  End If
End Function

';Get a number-----------------------------------------------------
Function GetNum() As Float

  STRING Temp
 
    If Asc(look) > 47 and Asc(look) < 58  ' read chars as numbers
       'print "need number"
    End if

While (Asc(Look) > 47 And Asc(Look) < 58) Or Asc(Look) = 46' dec.point
Temp = Temp + Look
Gosub getchar
         
Wend
       
  Return Val(Temp)
End Function

';Get variable ----------------------------------------------------------
Function GetVar() as float
'print "SUB->GETVAR"
  STRING Temp,func,expr
  FLOAT tempv
 
    'If Asc(look) < 96 and Asc(look) > 123  ' read chars as variable
      ' print ("need variable")
    'end if

While (Asc(Look) > 64 And Asc(Look) < 95) OR  (Asc(Look) > 96 And Asc(Look) < 123) OR  (Asc(Look) > 47 And Asc(Look) < 58)                             '; Works
Temp = Temp + Look
Gosub getchar
         'print "GetVar-TEMP:" + Temp 
        'IF         
Wend
'test variable value .........GetIntValue (byref vName as string) As FLOAT
'print "LOOK:" + Look
 IF Look <> "("
    If instr(Temp,"[") = 0
tempv = GetIntValue(Temp) 'not Array
    Else  ' is array
    ' print "TEMP:is array:" + Temp
     tempv = GetArrayValue(Temp)
    End if
'Return tempv
 END IF

'expected function..................
IF Look = "("
 'temp = sin(90)
'print "fTemp:" + temp   ' sin
 Gosub getchar  'skip bracket (  Look +1
While Look <> ""  ' ->...)
  expr = expr + Look
  Gosub getchar
Wend
'print "F->TEMP:" + expr  ' 90
 tempv=GetFunc(temp,expr)
 'Return tempv
 Gosub getchar
END IF
'...................................

Return tempv
 
End Function

Declare function Expression() as float
'==============================================================
Function Factor() as float

'print "SUB->FACTOR"
  FLOAT Value
'get number ----------------------------
  If Asc(Look) > 47 And Asc(Look) < 58
    Return GetNum()
  End if
'get variable -------------------------- 
  If Asc(look) > 96 and asc(look) < 123 OR (Asc(Look) > 64 And Asc(Look) < 91)
     return GetVar()
  End if
'get parens ---------------------------
If look <> ""
    Match("(")
  Value = Expression()
    Match(")")
End If

  Return Value
End Function
'==============================================================
Function Term() as float
  FLOAT Value
  Value = Factor()
  While (Look = "*" Or Look = "/")
    If Look = "*"
      Gosub getchar
      Value = Value * Factor()
    Else
      Gosub getchar
      Value = Value / Factor()
    End If
  Wend
  Return Value
End Function

Function Expression() as float
 FLOAT Value
  If (Look = "-")
    Gosub getchar
    Value = -(Term())
  Else
    Value = Term()
  End If

  While (Look = "+") Or (Look = "-")
    If Look = "+"
      Gosub getchar
      Value = Value + Term()
    Else
      Gosub getchar
      Value = Value - Term()
    End If
  Wend

  Return Value
End Function

Function EvaLLine(byval s as string) as float
  Stream = Replace(s, " ", "")
  StreamPos = 1
  Gosub getchar
'string out
Float Tempv
  Tempv = Expression()
  'If StreamPos < Len(Stream) '; Error check, you
    'Expected("nothing")      '; can remove them if you don't
  'EndIf
  'out=str(Temp)                   '; need the check
  Return Tempv
End Function