[system] / trunk / pg / macros / Parser.pl Repository: Repository Listing bbplugincoursesdistsnplrochestersystemwww

# View of /trunk/pg/macros/Parser.pl

Sun Aug 22 00:56:32 2004 UTC (15 years, 5 months ago) by dpvc
File size: 5306 byte(s)
```Formulas can now be compared even if their variables are complex
numbers, or even points or vectors!  This makes it possible to ask
students for complex functions like z^2+i and so on.

You can specify limits for variables either via
Context()->variables->set(x=>{limits=>[0,1]})  (for reals) or
Context()->variables->set(z=>{limits=>[[-2,2],[0,1]]}) (for complexes).
Similarly for points and vectors (where the number of sub arrays
depends on the dimension).  You can also give the limits for a
specific formula by assigning to its ->{limits} field:

\$f = Formula("sqrt(x-10)");
\$f->{limits} = [10,12];

There are now named variable types for 'Point2D', 'Point3D',
'Vector2D' and 'Vector3D', in addition to 'Real' and 'Complex'.
You can also specify a variable type by giving an explicit instance of
a value of the given type.  E.g.

Context()->variables->add(r=>Vector(0,0,0));   # a vector in R^3
Context()->variables->add(X=>'Vector3D');      # a vector in R^3

There still needs to be more error checking in processing
user-supplied limits, but I'm not sure how much overhead is worth it.
```

```    1 ###########################################################################
2 ##
3 ##  Set up the functions needed by the Parser.
4 ##
5
6 if (!\$Parser::installed) {
7   die "\n************************************************************\n" .
8         "* This problem requires the Parser.pm package, which doesn't\n".
10         "* administrator and ask him or her to install it first.\n".
11         "************************************************************\n\n"
12 }
13 if (!\$Value::installed) {
14   die "\n************************************************************\n" .
15         "* This problem requires the Value.pm package, which doesn't\n".
17         "* administrator and ask him or her to install it first.\n".
18         "************************************************************\n\n"
19 }
20
23
24 #
25 #  The main way to get a formula
26 #
27 sub Formula {Value::Formula->new(@_)}
28
29 #
30 #  Parse a formula and evaluate it
31 #
32 sub Compute {
33   my \$formula = Formula(shift);
34   return \$formula->eval(@_);
35 }
36
37 #
38 #  Deal with contexts
39 #
40 sub Context {Parser::Context->current(\%context,@_)}
41 %context = ();  # locally defined contexts, including 'current' context
42 Context();  # Initialize context (for persistent mod_perl)
43
44 ###########################################################################
45 #
46 # stubs for trigonometric functions
47 #
48
49 package Ignore;  ## let PGauxiliaryFunctions.pl do these
50
51 #sub sin {Parser::Function->call('sin',@_)}    # Let overload handle it
52 #sub cos {Parser::Function->call('cos',@_)}    # Let overload handle it
53 sub tan {Parser::Function->call('tan',@_)}
54 sub sec {Parser::Function->call('sec',@_)}
55 sub csc {Parser::Function->call('csc',@_)}
56 sub cot {Parser::Function->call('cot',@_)}
57
58 sub asin {Parser::Function->call('asin',@_)}
59 sub acos {Parser::Function->call('acos',@_)}
60 sub atan {Parser::Function->call('atan',@_)}
61 sub asec {Parser::Function->call('asec',@_)}
62 sub acsc {Parser::Function->call('acsc',@_)}
63 sub acot {Parser::Function->call('acot',@_)}
64
65 sub arcsin {Parser::Function->call('asin',@_)}
66 sub arccos {Parser::Function->call('acos',@_)}
67 sub arctan {Parser::Function->call('atan',@_)}
68 sub arcsec {Parser::Function->call('asec',@_)}
69 sub arccsc {Parser::Function->call('acsc',@_)}
70 sub arccot {Parser::Function->call('acot',@_)}
71
72 ###########################################################################
73 #
74 # stubs for hyperbolic functions
75 #
76
77 sub sinh {Parser::Function->call('sinh',@_)}
78 sub cosh {Parser::Function->call('cosh',@_)}
79 sub tanh {Parser::Function->call('tanh',@_)}
80 sub sech {Parser::Function->call('sech',@_)}
81 sub csch {Parser::Function->call('csch',@_)}
82 sub coth {Parser::Function->call('coth',@_)}
83
84 sub asinh {Parser::Function->call('asinh',@_)}
85 sub acosh {Parser::Function->call('acosh',@_)}
86 sub atanh {Parser::Function->call('atanh',@_)}
87 sub asech {Parser::Function->call('asech',@_)}
88 sub acsch {Parser::Function->call('acsch',@_)}
89 sub acoth {Parser::Function->call('acoth',@_)}
90
91 sub arcsinh {Parser::Function->call('asinh',@_)}
92 sub arccosh {Parser::Function->call('acosh',@_)}
93 sub arctanh {Parser::Function->call('atanh',@_)}
94 sub arcsech {Parser::Function->call('asech',@_)}
95 sub arccsch {Parser::Function->call('acsch',@_)}
96 sub arccoth {Parser::Function->call('acoth',@_)}
97
98 ###########################################################################
99 #
100 # stubs for numeric functions
101 #
102
103 #sub log   {Parser::Function->call('log',@_)}    # Let overload handle it
104 sub log10 {Parser::Function->call('log10',@_)}
105 #sub exp   {Parser::Function->call('exp',@_)}    # Let overload handle it
106 #sub sqrt  {Parser::Function->call('sqrt',@_)}    # Let overload handle it
107 #sub abs   {Parser::Function->call('abs',@_)}    # Let overload handle it
108 sub int   {Parser::Function->call('int',@_)}
109 sub sgn   {Parser::Function->call('sgn',@_)}
110
111 sub ln     {Parser::Function->call('log',@_)}
112 sub logten {Parser::Function->call('log10',@_)}
113
114 package main;  ##  back to main
115
116 sub log10 {Parser::Function->call('log10',@_)}
117 sub Factorial {Parser::UOP::factorial->call(@_)}
118
119 ###########################################################################
120 #
121 # stubs for special functions
122 #
123
124 #sub atan2 {Parser::Function->call('atan2',@_)}    # Let overload handle it
125
126 ###########################################################################
127 #
128 # stubs for numeric functions
129 #
130
131 sub arg  {Parser::Function->call('arg',@_)}
132 sub mod  {Parser::Function->call('mod',@_)}
133 sub Re   {Parser::Function->call('Re',@_)}
134 sub Im   {Parser::Function->call('Im',@_)}
135 sub conj {Parser::Function->call('conj',@_)}
136
137 ###########################################################################
138 #
139 # stubs for vector functions
140 #
141
142 sub norm {Parser::Function->call('norm',@_)}
143 sub unit {Parser::Function->call('unit',@_)}
144
145 #
146 #  These need to be in dangerousMacros.pl for some reason
147 #
148 #sub i () {Compute('i')}
149 #sub j () {Compute('j')}
150 #sub k () {Compute('k')}
151
152 ###########################################################################
153
154 \$_parser_loaded = 1;  #  use this to tell if Parser.pl is loaded
155