Equation Tool
Home Up

 

I already have a section on the subject of parsing expressions, under the heading of Quick BASIC (because BASIC is freely available and otherwise accessible to many people who don't yet know how to parse expressions but may want to learn.) But I've also developed similar code in the c language.  Here's one incarnation.

An expression tool

I needed a command-line tool for generating computed series' of data that I could then pipe into other programs for processing (piping is the process of passing the output of one program as input to another program.) I needed the ability to generate not just one series, but the ability to produce many hundreds of them in sequence. And I needed to break up each of them with a header and trailer message that could include pertinent information about each group. This page is about the resulting tool I wrote.

Probably the fastest way to get across some of the capabilities and its syntax is to provide some examples.

1.  EQ sin(pi/3)
    0.8660254038

Example 1 simply prints out the sine of PI/3 on one line and then quits. (I've chosen to put the command I typed in one color and the output in another color.) This illustrates that the program can be used as a general purpose calculator. It includes quite a few different transcendentals, including hyperbolic, two different types of random number generations: uniform and gaussian distributed. And some more. It should accept most familiar forms of algebraic expressions and provide reasonable results. The values are displayed to 10 significant digits, by default. (But the default can be changed -- discussed later on, here.)

2.  EQ sin( pi/3 )
    eq: extra characters in expression 'sin('

Example 2 shows a problem. I added a couple of spaces and an error resulted. The problem created here is due to the way that arguments are passed by DOS to EQ and my intent that EQ could support multiple expressions, looping, and statements. DOS uses spaces to separate arguments passed to EQ, so inserting spaces as in example 2 makes it look like three different expressions to EQ instead of just one.  However, here's a way to handle that:

3.  EQ "sin( pi/3 )"
    0.8660254038

Example 3 points out that you can force DOS to include an expression that includes spaces into a single expression or statement if you use double quote marks to surround the text. Just keep that in mind, when using the program.

To continue:

4.  EQ :Hello 5+4 ":Done"
    Hello
    9
    Done

Example 4 prints out three lines. The colon (:) indicates printing a message instead of a calculation result. You can either enclose it in quotes, or not. But quotes are needed if there are special characters like spaces, where DOS needs to know that it all should be included into a single command line argument. The double quotes themselves aren't printed, though.

5.  EQ a=pi/3 sin(a)
    0.8660254038

Example 5 shows that you can use variable names. Assignments statements aren't printed, just executed. So that's why there is only one line of output, the result of computing the sine of 'a'. The program includes only two pre-defined variables: pi and e. Case is not important here, so you can use either upper or lower or mixed cases with the same results.

6.  EQ a=pi/3 r=sin(a) ":The sine of &a is &r"
    The sine of 1.047197551 is 0.8660254038

Example 6 shows that the text output permitted by the colon includes the ability to insert the values of variables, if you prefix them with the ampersand (&) character.

7.  EQ n=10 a=0 {n+1 sin(a) a=a+pi/2/n }
    0
    0.156434465
    0.3090169944
    0.4539904997
    0.5877852523
    0.7071067812
    0.8090169944
    0.8910065242
    0.9510565163
    0.9876883406
    1

Example 7 adds two new elements, needed for looping. An argument starting with an open-set-sign is taken to be the start of a loop and the expression that follows it determines the number of iterations. The loop will continue until the close-set-sign is seen. This allows repeated lines of output, each with a different calculation. In example 5, the output is a series of sine results for angles varying from 0 degrees to 90 degrees. In the above case, the variable 'n' determines how many equal segments to use in that 90-degree angle interval.

8.  EQ {2 4 } {3 5 }
    4
    4
    5
    5
    5

Example 8 just illustrates that these loops can be successive. But they also can be nested, as well. They are fairly general purpose.

9.  EQ n=10 a=0 ":Sines n=&n" {n+1 s=sin(a) ":&a,&s" a=a+pi/2/n } ":End"
    Sines n=10
    0,0
    0.1570796327,0.156434465
    0.3141592654,0.3090169944
    0.471238898,0.4539904997
    0.6283185307,0.5877852523
    0.7853981634,0.7071067812
    0.9424777961,0.8090169944
    1.099557429,0.8910065242
    1.256637061,0.9510565163
    1.413716694,0.9876883406
    1.570796327,1
    End

Example 9 shows a header, a list of data pairs, and a trailer. It illustrates most of the capability of the program.

I've also added the ability to specify the number of significant digits to use, when displaying values:

10. EQ sin(pi/4)#3
    0.707

Example 10 shows how to limit the number of significant places in the output for an expression. This specifier is not allowed in statements, as calculations proceed at double precision significance at all times. However, it is allowed in record outputs.

11. EQ r=sin(pi/4) :&r#4
    0.7071

Example 11 shows how that works. In all cases, the specifier must be provided as simple digits; expressions are not handled. The default is 10 digits and the maximum allowed is 17.

Finally, I've just recently added the ability to copy the output from EQ to the Windows clipboard, using the -c arugment option as the first argument to EQ. You may also get help from it, using -h as the first argument.

EQ, the toolbox

But while the above examples show you what the final program can do, it doesn't really illustrate anything about the expression parser that is included in the source code. That parser not only has the ability to support general expressions and variable assignment statements, but it can also pre-compile these expressions for faster execution. The expression parser can be used in your own c programs with about as much ease as using the standard library function strtod(). And the pre-compiled expressions will execute faster. (The code is an internally designed 'push-pop' code, not actual machine language.)

I'm including a copy of the source code and an executable for this expression parser and compiler, along with the useful harness for it that is illustrated above.

Equation calculator with looping feature
Some instructions for using this program are included in the EQ.C file's header found in the above ZIP file. This package also includes a useful kit for adding expression handling into your own programs and includes a fairly complete set of commentary within the code. The expression handling part of this code is sufficiently portable that it wouldn't be too difficult to use it in other environments and compilers. But the command line harness uses a few special functions from the MSVC library that may not be present on other systems -- routines I use to split the invoked program name from the first argument to main( ). I use that only for error output, so those routines aren't important and the whole thing could be replaced by a stub, if porting the code to non-DOS targets. (Also, since adding clipboard support, the assembly code won't port elsewhere. But that is okay.)

As usual, source code and make files are provided with this program.

If the subject of expression parsing and evaluation is interesting to you, I have some pages on the subject under the Quick BASIC heading. The information is general enough to be useful for programming in other languages or just understanding some of the details.  The starting point page is here.

 

Last updated: Monday, February 13, 2006 14:09