[system] / trunk / pg / lib / Parser / Context / Variables.pm Repository: Repository Listing bbplugincoursesdistsnplrochestersystemwww # View of /trunk/pg/lib/Parser/Context/Variables.pm

Sun Aug 22 00:56:32 2004 UTC (15 years, 5 months ago) by dpvc
File size: 1928 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 #  Implements the list of known variables and their types
4 #
5 package Parser::Context::Variables;
6 use strict;
7 use vars qw(@ISA %type);
8 @ISA = qw(Value::Context::Data);
9
10 #
11 #  The named types for variables
12 #    (you can use arbitary types by supplying an
13 #     instance of the type rather than a name)
14 #
15 %type = (
16   'Real'    => \$Value::Type{number},
17   'Complex' => \$Value::Type{complex},
18   'Point2D' => Value::Type('Point',2,\$Value::Type{number}),
19   'Point3D' => Value::Type('Point',3,\$Value::Type{number}),
20   'Vector2D' => Value::Type('Vector',2,\$Value::Type{number}),
21   'Vector3D' => Value::Type('Vector',3,\$Value::Type{number}),
22 );
23
24 sub init {
25   my \$self = shift;
26   \$self->{dataName} = 'variables';
27   \$self->{name} = 'variable';
28   \$self->{Name} = 'Variable';
29   \$self->{namePattern} = '[a-zA-Z]';
30   \$self->{pattern} = \$self->{namePattern};
31 }
32
33 #
34 #  Our pattern should match ANY variable name
35 #    (Parser takes care of reporting unknown ones)
36 #
37 sub update {
38   my \$self = shift;
39   \$self->{pattern} = \$self->{namePattern};
40 }
41
42 #
43 #  If the type is one of the names ones, use it's known type
44 #  Otherwise if it is a Value object use its type,
45 #  Otherwise, if it is a signed number, use the Real type
46 #  Otherwise report an error
47 #
48 sub create {
49   my \$self = shift; my \$value = shift;
50   return \$value if ref(\$value) eq 'HASH';
51   if (defined(\$type{\$value})) {
52     \$value = \$type{\$value};
53   } elsif (Value::isValue(\$value)) {
54     \$value = \$value->typeRef;
55   } elsif (\$value =~ m/\$self->{context}{pattern}{signedNumber}/) {
56     \$value = \$type{'Real'};
57   } else {
58     Value::Error("Unrecognized variable type '\$value'");
59   }
60   return {type => \$value};
61 }
62
63 #
64 #  Return a variable's type
65 #
66 sub type {
67   my \$self = shift; my \$x = shift;
68   return \$self->{context}{variables}{\$x}{type};
69 }
70
71 #########################################################################
72
73 1;
74
```