Posted: Tue Mar 07, 2006 9:00 pm
I managed to get it down to 150 on this comp by removing your function handling code
http://www.purebasic.com
https://www.purebasic.fr/english/
A real compiler is much easier than a JIT compiler since you don't have to check whether something is already compiled or not, you simply compile everything and pass it on to the assembler for assembly. In a JIT compiler you need to compile directly to assembled code or bundle an assembler and God knows what you don't have to do.Nik wrote:Then it's not a scripting language anymore and it's alot harder, but you could combine mashine with scripting code, only using compiled stuff for mathematic functions, and JITC are really cool I think
Neither can mine.dracflamloc wrote:Anyway, Xombie I found a bug in your code. It can't handle "-10" as an input!
No, it returns zero always. This fixed version can also handle it correctly if the contents of a parenthesis is -something, so you can do funky stuff like "100*(-(-(-1)))". It also has improved error handling so it aborts on stuff like "100~garbagefasd" (at some speed expense, this should though be countered almost completely by a speed increase caused by the fix of the -x bug).dracflamloc wrote:Really? Because I've been using it and it works for me?
Code: Select all
OpenConsole()
Global Look.s
Look.s = " " ; Yes, that space is IMPORTANT!!!! Remove and DIE!!!
Global Stream.s
Global StreamPos.l ; Read position in stream
Procedure.s VisibleToken(s.s)
Select s.s
Case #CR$
s.s = "newline"
Case #LF$
s.s = "newline"
Case ""
s.s = "nothing"
EndSelect
ProcedureReturn s.s
EndProcedure
;Cleanup then end
Procedure Finish()
PrintN("Ending.")
Input()
End
EndProcedure
;Report an error
Procedure Error(s.s)
PrintN("Error: " + s + ".")
EndProcedure
;Report an error and abort
Procedure Abort(s.s)
Error(s.s)
Finish()
EndProcedure
;Report what was expected
Procedure Expected(expected.s)
Abort("Expected: " + expected + ", got '" + VisibleToken(Look) + "'")
EndProcedure
;Read a character into Look
Goto GetChar_End
GetChar:
PokeB(@Look, PeekB(@Stream + StreamPos))
StreamPos + 1
Return
GetChar_End:
;Match a specific input character
Procedure Match(*s.s)
If Look <> *s.s
Expected("'"+*s.s+"'")
Else
!CALL l_getchar
EndIf
EndProcedure
;Get a number
Procedure.f GetNum()
Protected Temp.s
If (PeekB(@Look) < 48 And PeekB(@Look) > 57)
Expected("Integer")
EndIf
; While (PeekB(@Look) > 47 And PeekB(@Look) < 58 Or PeekB(@Look) = '.') ; Works not
While ((PeekB(@Look) > 47 And PeekB(@Look) < 58) Or PeekB(@Look) = '.') ; Works
Temp + Look
!CALL l_getchar
Wend
ProcedureReturn ValF(Temp)
EndProcedure
;-----
Declare.f Expression()
Procedure.f Factor()
Protected Value.f
If (PeekB(@Look) > 47 And PeekB(@Look) < 58)
ProcedureReturn GetNum()
Else
Match("(")
Value = Expression()
Match(")")
EndIf
ProcedureReturn Value
EndProcedure
Procedure.f Term()
Protected Value.f
Value = Factor()
While (Look = "*" Or Look = "/")
If Look = "*"
!CALL l_getchar
Value * Factor()
Else
!CALL l_getchar
Value / Factor()
EndIf
Wend
ProcedureReturn Value
EndProcedure
Procedure.f Expression()
Protected Value.f
If (Look = "-")
!CALL l_getchar
Value = -Term()
Else
Value = Term()
EndIf
While (Look = "+" Or Look = "-")
If Look = "+"
!CALL l_getchar
Value + Term()
Else
!CALL l_getchar
Value - Term()
EndIf
Wend
ProcedureReturn Value
EndProcedure
Procedure.f Solve(*s.s)
Stream = ReplaceString(*s.s, " ", "")
StreamPos = 0
!CALL l_getchar
Temp.f = Expression()
If StreamPos < Len(Stream) ; Error check, you
Expected("nothing") ; can remove them if you don't
EndIf ; need the check
ProcedureReturn Temp.f
EndProcedure
#Tries = 100000
time = GetTickCount_()
For I = 0 To #Tries
Solve("100+1")
Next
MessageRequester("", Str(GetTickCount_()-time))
PrintN(StrF( Solve("100*(5+3)+1") ))
Input()
Yes, there was logic with where I placed the error check. It's fixed now.dracflamloc wrote:Hm. Must have been in a change I made that made it sometimes work... But thanks for the fix. Thats awesome =)
BUg I found:
When the Stream = "100*(5+3)+1"
It spits out the error:
Expected: nothing, got ')'
Code: Select all
Declare.f Expression()
Global *expr.BYTE
Procedure Expected(string.s)
MessageRequester("Error","Expected : "+string+", Got : "+Chr(*expr\b))
End
EndProcedure
Procedure Match(b.b)
If *expr\b = b
*expr + 1
Else
Expected(Chr(b))
EndIf
EndProcedure
Procedure.f GetNum()
Protected Temp.s
If (*expr\b < '0') And (*expr\b > '9')
Expected("Integer")
EndIf
While ((*expr\b >= '0' And *expr\b <= '9') Or *expr\b = '.')
Temp + Chr(*expr\b)
*expr + 1
Wend
ProcedureReturn ValF(Temp)
EndProcedure
Procedure.f Factor()
Protected Value.f
If (*expr\b >= '0' And *expr\b <= '9')
ProcedureReturn GetNum()
Else
Match('(')
Value = Expression()
Match(')')
EndIf
ProcedureReturn Value
EndProcedure
Procedure.f Term()
Protected Value.f
Value = Factor()
While (*expr\b = '*' Or *expr\b = '/')
If *expr\b = '*'
*expr + 1
Value * Factor()
Else
*expr + 1
Value / Factor()
EndIf
Wend
ProcedureReturn Value
EndProcedure
Procedure.f Expression()
Protected Value.f
If *expr\b = '-'
*expr + 1
Value = -Term()
Else
Value = Term()
EndIf
While (*expr\b = '+' Or *expr\b = '-')
If *expr\b = '+'
*expr + 1
Value + Term()
Else
*expr + 1
Value - Term()
EndIf
Wend
ProcedureReturn Value
EndProcedure
Procedure.f Solve(input.s)
*expr = @input
ProcedureReturn Expression()
EndProcedure
;=================================
time.l = ElapsedMilliseconds()
For i = 0 To 100000
result.f = Solve("100*(5+3)+1")
Next
MessageRequester(Str(ElapsedMilliseconds()-time),StrF(result))