|
-
Oct 22nd, 2001, 10:18 AM
#1
Thread Starter
Frenzied Member
I need help making a simple algorythm to load an expression like 100/5+(10+(2*4))
Hi, I'm working on a scripting language (in VB) and it worked fine until I tried to add expressions (like 100/5+(10+(2*4)) )
Can anyone help me with this? My idea would be to seperate it into "steps", and then execute them backwards, like this:
(1+3)-((4+5)-6)
would become
Code:
( + )-( - )
1 3 ( + ) 6
4 5
Does anyone have any idea? Fox, Keda, any of the other gurus around?...
-
Oct 22nd, 2001, 02:56 PM
#2
Good Ol' Platypus
Try finding each bracket pair, then making their expressions into a UDT. This UDT could have something like a priority, with #1 being the most nested bracket. Then you could do BEDMAS in these expressions, using whatever math you already have.
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation. 
(Just a heads-up)
-
Oct 22nd, 2001, 05:53 PM
#3
Liek you said, you will have to separate each expression into steps. If you already support something like "10 + 2 - 3", you should be fine. First, loop through your string. At each open paren, increment a counter, and save it's location in an array. At the first close paren, find the location of the last open paren, pull that part of the string out, and find it's value. Save this value. At the next closed paren, use the saved value as a replacement for it's expression. Repeat.
Code:
(1+3)-((4+5)-6);
The loop will look like:
open paren, inc counter
1
+
3
close paren, dec counter, exec expression, 4
-
open paren, inc counter
open paren, inc counter
4
+
6
close paren, dec counter, exec expression, 10
-
6
close paren, dec counter, exec expression, 4
semicolon, finish exec, 4 - 4 = 0
Z.
-
Oct 22nd, 2001, 06:08 PM
#4
FWIW - I posted in C/C++ forum a C interpreter. It has a descending parser. Take a look at how parsers work -- you can implement a simple mathematical processor using one in either VB or C. Or you can just steal the math code part.
http://www.vbforums.com/showthread.p...ht=interpreter
-
Oct 22nd, 2001, 07:07 PM
#5
transcendental analytic
I did a parser in C++ just a few weeks ago for homework. I bet you don't want to learn C++ now Jotaf so I could instead introduce you to something even more usefull for a vb programmer: Vbscript.
Vbscript can evaluate most string expressions containing both mathematical operators as well as many vb functions. you can look up msdn for more details. That's usefull ofcourse but vbscript is rather more usefull as a scripting language since it's "object oriented" and can work with COM objects you pass to it as well as execute compiled blocks of code at runtime. It might take several months to get a scripting language for similar functionality and with vbscript you have everything just made up for you.
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Oct 23rd, 2001, 02:46 PM
#6
Thread Starter
Frenzied Member
-
Oct 23rd, 2001, 02:58 PM
#7
transcendental analytic
That's the whole idea? May I ask why?
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Oct 23rd, 2001, 03:09 PM
#8
Good Ol' Platypus
Americans may know it by PPMDAS -- it's the order of operations.
Brackets
Exponents
Division
Multiplication
Addition
Subtraction
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation. 
(Just a heads-up)
-
Oct 23rd, 2001, 05:56 PM
#9
Thread Starter
Frenzied Member
Sas: well, I'm not american ( ) but I see what you mean, it's how you solve equations. Except that my teacher didn't have to give us something like that so we would remember the correct order (she just gave us the list and we learned to use it) 
Keda: Why would you hack into the Pentagon if you thought you had the skills for that? I'm doing this because I don't have anything else to do; also to prove myself that I can make a powerful scripting engine run at an acceptable speed in a VB game For the same reasones why we make free programs, games and DLLs sometimes. If you're a programmer, you should already know that 
Jim: Thanks for the code, it's a bit too complicated for me (sorry ) but I think it would still be useful if you packed it up in a DLL for use in games 
Anyway, I finally managed to code what I wanted. Open up a new VB project, create a textbox and a command button in the form, and dump this code into it:
VB Code:
Option Base 1
Option Explicit
Private Sub Command1_Click()
Dim i As Long, Str As String, TempStr As String
Dim Stack() As Long, NumStack As Long, Total As Long
Dim k As Long
Str = Text1.Text
For i = 1 To Len(Str)
If i > Len(Str) Then Exit For
TempStr = Mid(Str, i, 1)
If TempStr = "(" Then
NumStack = NumStack + 1
ReDim Preserve Stack(NumStack)
Stack(NumStack) = i
ElseIf TempStr = ")" Then
Total = ExecExpr2(Mid(Str, Stack(NumStack) + 1, i - Stack(NumStack) - 1))
Str = Left(Str, Stack(NumStack) - 1) & Total & Right(Str, Len(Str) - i)
i = Stack(NumStack)
NumStack = NumStack - 1
If NumStack > 0 Then ReDim Preserve Stack(NumStack)
End If
Next i
Total = ExecExpr2(Str, True)
Text1.Text = Total
End Sub
Private Function ExecExpr2(Str As String) As Long
Dim j As Long, TempStr As String
Dim Total As Long, Stack As String, Op As String * 1
Dim k As Long
For j = 1 To Len(Str)
TempStr = Mid(Str, j, 1)
If TempStr = "+" Or TempStr = "-" Or TempStr = "*" Or TempStr = "/" Then
If Op = Chr(0) Then
Op = TempStr
Total = Stack
Stack = ""
Else
If Op = "+" Then
Total = Total + Stack
ElseIf Op = "-" Then
Total = Total - Stack
ElseIf Op = "*" Then
Total = Total * Stack
ElseIf Op = "/" Then
Total = Total / Stack
End If
Stack = ""
Op = TempStr
End If
ElseIf TempStr <> " " Then
Stack = Stack & TempStr
End If
Next j
If Op = "+" Then
Total = Total + Stack
ElseIf Op = "-" Then
Total = Total - Stack
ElseIf Op = "*" Then
Total = Total * Stack
ElseIf Op = "/" Then
Total = Total / Stack
End If
ExecExpr2 = Total
End Function
That's it! Type a simple expression into it and press the button; the textbox now has the result.
It's not commented yet, but if you step trough it with F8 it really helps 
There's only one problem, it doesn't deal well with negative numbers well (like -10*3 or 200/-4 ). Could you please help me on this one? If you're interested, I can comment the code... basically I followed Zaei's steps, with some suggestions from Sas (except for the UDTs ).
My idea is to load the minus signs differently, so instead of 1 - 2 it would be like 1 + (-2). What do you think?
-
Oct 23rd, 2001, 07:12 PM
#10
For negative numbers, preprocess your string. Find any place with a minus sign. If it is followed and preceded by a number, do nothing. if it followed, but not preceded by a number, insert a 0 before the minus sign, and exec as normal. You may want to add parens around the 0-num, so it works right always.
-
Oct 23rd, 2001, 09:20 PM
#11
Good Ol' Platypus
Listen to Zaei; he's already got a scripting language under his belt =)
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation. 
(Just a heads-up)
-
Oct 24th, 2001, 05:40 AM
#12
transcendental analytic
I tell you what Jotaf, If you absolutely don't have anything else to do, and want to test your skills. Learn C++ immediately and you will thank me some day.
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Oct 24th, 2001, 05:42 AM
#13
transcendental analytic
Originally posted by Zaei
For negative numbers, preprocess your string. Find any place with a minus sign. If it is followed and preceded by a number, do nothing. if it followed, but not preceded by a number, insert a 0 before the minus sign, and exec as normal. You may want to add parens around the 0-num, so it works right always.
What are you guys? Amateurs?
(-x) is the unary negate operator, which should not be mistaken for the binary (x-y) substract operator.
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Oct 24th, 2001, 03:05 PM
#14
Thread Starter
Frenzied Member
-
Oct 24th, 2001, 04:17 PM
#15
Thread Starter
Frenzied Member
-
Oct 24th, 2001, 05:59 PM
#16
If you want fast, write a compiled psudo-ASM scripting language. The one i am working with(that i wrote), in a few tests performed better then VB =).
Z.
-
Oct 24th, 2001, 06:01 PM
#17
kedaman, from my tests, 0-x is -x. 0-3 = -3, 0--3 = 3... works for me.
Z.
-
Oct 24th, 2001, 06:17 PM
#18
transcendental analytic
Jotaf, do as you wish 
Zaei, did your language compile blocks of code like vb script does?
0-x will be a waste of preprocessing time, especially as you have to count in all predecessing situations like a*-b and a^-(b+c) to add extra parentesis.
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Oct 24th, 2001, 07:57 PM
#19
It compiles the entire script into bytecode. The only real downside is that it's psudo asm:
Code:
mov aa 10
add aa 10
shl aa 1
push aa
int 0
call hello
end
function hello
mov aa 10
push aa
int 10
ret
And that you can only use variable names aa..zz, but that was a speed consideration =).
Z.
-
Oct 25th, 2001, 07:44 AM
#20
Thread Starter
Frenzied Member
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|