comp.lang.ada
 help / color / mirror / Atom feed
* Using a string as a binary operator
@ 2008-10-14 15:35 Joe
  2008-10-14 17:05 ` Dmitry A. Kazakov
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Joe @ 2008-10-14 15:35 UTC (permalink / raw)


Hey all,

I'm trying to build a simple stack the evaluates expressions in
postfix notation (i.e. "1 2 +").  I can't find a way to use the
operator directly when I get to it.  When I get to the  "+", but how
do I apply this string to 1 and 2?  The best I can do is make a case
statement that has a case for each binary operator, but this seems
very klunky.  I know you can write "+"(1,2) to return 3 but how do I
get Ada to recognize the string as an operator?  Here's a short
example of what I would like to do:

with Ada.Integer_Text_IO;  use Ada.Integer_Text_IO;
procedure Operators is
   Plus : String := "+";
begin
   Put( Plus(1,2));
end Operators;

Thanks,
Joe



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-14 15:35 Using a string as a binary operator Joe
@ 2008-10-14 17:05 ` Dmitry A. Kazakov
  2008-10-14 18:51 ` Jeffrey R. Carter
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2008-10-14 17:05 UTC (permalink / raw)


On Tue, 14 Oct 2008 08:35:23 -0700 (PDT), Joe wrote:

> I'm trying to build a simple stack the evaluates expressions in
> postfix notation (i.e. "1 2 +").  I can't find a way to use the
> operator directly when I get to it.  When I get to the  "+", but how
> do I apply this string to 1 and 2?  The best I can do is make a case
> statement that has a case for each binary operator, but this seems
> very klunky.  I know you can write "+"(1,2) to return 3 but how do I
> get Ada to recognize the string as an operator?  Here's a short
> example of what I would like to do:
> 
> with Ada.Integer_Text_IO;  use Ada.Integer_Text_IO;
> procedure Operators is
>    Plus : String := "+";
> begin
>    Put( Plus(1,2));
> end Operators;

with Ada.Integer_Text_IO;  use Ada.Integer_Text_IO;
procedure Operators is
   function Plus (L, R : Integer) return Integer renames "+";
begin
   Put (Plus (1, 2));
end Operators;

P.S. I am quite sure that this is not what you need. You don't need strings
in order to evaluate an expression. Evaluation of an expression /= parsing
an expression. It is unclear which one you actually want, or maybe both.

P.P.S. Ada does not "recognize strings as operators." "+" when used to
declare or reference + is technically not a string. It is a string literal.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-14 15:35 Using a string as a binary operator Joe
  2008-10-14 17:05 ` Dmitry A. Kazakov
@ 2008-10-14 18:51 ` Jeffrey R. Carter
  2008-10-15 15:22   ` Adam Beneschan
  2008-10-14 22:01 ` george.priv
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Jeffrey R. Carter @ 2008-10-14 18:51 UTC (permalink / raw)


Joe wrote:
> 
> I'm trying to build a simple stack the evaluates expressions in
> postfix notation (i.e. "1 2 +").  I can't find a way to use the
> operator directly when I get to it.  When I get to the  "+", but how
> do I apply this string to 1 and 2?  The best I can do is make a case
> statement that has a case for each binary operator, but this seems
> very klunky.  I know you can write "+"(1,2) to return 3 but how do I
> get Ada to recognize the string as an operator?  Here's a short
> example of what I would like to do:

The short answer is that you can't. You have to evaluate "1" and "2" to get 
values of some numeric type and push them on a stack, then find a branch in an 
if-elsif-else chain that matches your operator string, and in that branch pop 
the operands and apply the appropriate operator to them. See 
PragmARC.Postfix_Calculator for an (Ada-95) example.

http://pragmada.home.mchsi.com/

-- 
Jeff Carter
"Every sperm is sacred."
Monty Python's the Meaning of Life
55



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-14 15:35 Using a string as a binary operator Joe
  2008-10-14 17:05 ` Dmitry A. Kazakov
  2008-10-14 18:51 ` Jeffrey R. Carter
@ 2008-10-14 22:01 ` george.priv
  2008-10-15  3:51 ` Gene
  2008-10-15  5:45 ` anon
  4 siblings, 0 replies; 12+ messages in thread
From: george.priv @ 2008-10-14 22:01 UTC (permalink / raw)


On Oct 14, 11:35 am, Joe <joesmo...@gmail.com> wrote:
> Hey all,
>
> I'm trying to build a simple stack the evaluates expressions in
> postfix notation (i.e. "1 2 +").  I can't find a way to use the
> operator directly when I get to it.  When I get to the  "+", but how
> do I apply this string to 1 and 2?  The best I can do is make a case
> statement that has a case for each binary operator, but this seems
> very klunky.  I know you can write "+"(1,2) to return 3 but how do I
> get Ada to recognize the string as an operator?  Here's a short
> example of what I would like to do:
>
> with Ada.Integer_Text_IO;  use Ada.Integer_Text_IO;
> procedure Operators is
>    Plus : String := "+";
> begin
>    Put( Plus(1,2));
> end Operators;
>
> Thanks,
> Joe

You are confusing compile time and run time phases of your program's
life.  When you call "+"(a,b), it is treated as any other function
(Could have been Add(a,b)). Ada overload feature allows for more
convenient substitution in form a+b.  The construct is recognized
during compilation of the source code.   At run time compiler is no
longer used and sometimes unavailable.  So you have to write your own
parser that will handle your input string.  There is plentiful code
samples out there on the WEB in variety of languages I am sure.

George.




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-14 15:35 Using a string as a binary operator Joe
                   ` (2 preceding siblings ...)
  2008-10-14 22:01 ` george.priv
@ 2008-10-15  3:51 ` Gene
  2008-10-15  5:45 ` anon
  4 siblings, 0 replies; 12+ messages in thread
From: Gene @ 2008-10-15  3:51 UTC (permalink / raw)


On Oct 14, 11:35 am, Joe <joesmo...@gmail.com> wrote:
> Hey all,
>
> I'm trying to build a simple stack the evaluates expressions in
> postfix notation (i.e. "1 2 +").  I can't find a way to use the
> operator directly when I get to it.  When I get to the  "+", but how
> do I apply this string to 1 and 2?  The best I can do is make a case
> statement that has a case for each binary operator, but this seems
> very klunky.  I know you can write "+"(1,2) to return 3 but how do I
> get Ada to recognize the string as an operator?  Here's a short
> example of what I would like to do:
>
> with Ada.Integer_Text_IO;  use Ada.Integer_Text_IO;
> procedure Operators is
>    Plus : String := "+";
> begin
>    Put( Plus(1,2));
> end Operators;
>

The "+" in Ada code such as "+"(1, 2) is a function call, just like
f(1, 2).  You can't cast a string "+" to a function in Ada, just as
you can't cast "f".  You have to convert the string yourself.  Here is
a toy code with many things go fix:

with Ada.Text_IO; use Ada.Text_IO;

procedure Postfix is

   subtype Number is Integer;

   Operands : array(1 .. 1000) of Number;
   SP : Natural := 0;

   procedure Push(X : in Number) is
   begin
      SP := SP + 1;
      Operands(SP) := X;
   end Push;

   procedure Pop(X : out Number) is
   begin
      X := Operands(SP);
      SP := SP - 1;
   end Pop;

   Buf : String(1 .. 1000);
   Last : Natural;
   X, Y : Number;
begin
   loop
      Get_Line(Buf, Last);
      exit when Last = 0;
      case Buf(1) is
         when '+' =>
            Pop(X); Pop(Y); Push(X + Y);
         when '-' =>
            Pop(X); Pop(Y); Push(X - Y);
         when '*' =>
            Pop(X); Pop(Y); Push(X * Y);
         when '/' =>
            Pop(X); Pop(Y); Push(X / Y);
         when others =>
            Push(Number'Value(Buf(1 .. Last)));
      end case;
      if SP = 1 then
         Put_Line(Number'Image(Operands(1)));
      end if;
   end loop;
end Postfix;



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-14 15:35 Using a string as a binary operator Joe
                   ` (3 preceding siblings ...)
  2008-10-15  3:51 ` Gene
@ 2008-10-15  5:45 ` anon
  2008-10-15 12:18   ` Joe
  4 siblings, 1 reply; 12+ messages in thread
From: anon @ 2008-10-15  5:45 UTC (permalink / raw)


First, it seams that your talking about a version of "Polish notation" or 
"Lisp notation".  There are 100s of articles and some sample program 
across the net.  Just do a search, and these article should give more 
information than you have question for.

For a starter in this simple example there will be one push/pop function 
one for "operations" and the other for numeric values.


  type operations is ( add, sub, mul, div, equal ) ;  - sample list
  for operations use ( noop => 0, add => 1,  sub   => 2,
                        mul  => 3, div => 4,  equal => 5 ) ;  - sample list


  procedure do_notation ( buffer : string ) is  

      operation_code : character ;

    begin

      -- decode operation_code and arguments from buffer 

       -- push arguments 

       push ( arg1 )  ;  -- push numeric value of argument 1 and 2
       push ( arg2 )  ;

      case operation_code is
        when '+' =>
            push ( add )  ;
        when '-' =>
            push ( sub ) ;
        ...
        when others =>
            raise Operations_Error ; - illegal operation
        end case ;
    end ;

-----

  function process_notation return data_type is
    cmd : operations ;  
    begin 
      arg1 := pop ;
      arg2 := pop ;
      cmd := pop ;
      case cmd is 
        when add =>
          result := arg1 + arg2 ;
        when sub =>
          result := arg1 - arg2 ;
        when div =>
          if arg2 /= 0 then
            result := arg1 / arg2 ;
          else
            raise Div_Zero_Error ;
          end ;
       ...
        when others =>
          raise Stack_Error ;
      end case ;

      -- Display or return result.

    end ;


    result : data_type ; -- data_type is user assigned numeric type

begin
   push ( noop )  ; -- not needed. Used only for showing stack list
   -- stack should have ( 0, ... )

   do_notation ( "5 + 10" ) ; 
   -- stack should have ( 5, 10, 1, 0, ... )

   result := process_notation ; 
  -- If the  then after  the stack should have ( 0, ... ) and result := 15

  ...
end ;


In <8cbb04c3-e789-4b67-897a-fd6f83486bbc@x16g2000prn.googlegroups.com>, Joe <joesmoe10@gmail.com> writes:
>Hey all,
>
>I'm trying to build a simple stack the evaluates expressions in
>postfix notation (i.e. "1 2 +").  I can't find a way to use the
>operator directly when I get to it.  When I get to the  "+", but how
>do I apply this string to 1 and 2?  The best I can do is make a case
>statement that has a case for each binary operator, but this seems
>very klunky.  I know you can write "+"(1,2) to return 3 but how do I
>get Ada to recognize the string as an operator?  Here's a short
>example of what I would like to do:
>
>with Ada.Integer_Text_IO;  use Ada.Integer_Text_IO;
>procedure Operators is
>   Plus : String := "+";
>begin
>   Put( Plus(1,2));
>end Operators;
>
>Thanks,
>Joe




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-15  5:45 ` anon
@ 2008-10-15 12:18   ` Joe
  2008-10-15 13:43     ` John McCormick
  0 siblings, 1 reply; 12+ messages in thread
From: Joe @ 2008-10-15 12:18 UTC (permalink / raw)


First of all, thanks for the help.  I was unclear on the difference
between string literals and regular strings, but I think I'm all set
now.  It seems I've been spoiled by Python.

Thanks again,
Joe



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-15 12:18   ` Joe
@ 2008-10-15 13:43     ` John McCormick
  0 siblings, 0 replies; 12+ messages in thread
From: John McCormick @ 2008-10-15 13:43 UTC (permalink / raw)


On Oct 15, 7:18 am, Joe <joesmo...@gmail.com> wrote:
> First of all, thanks for the help.  I was unclear on the difference
> between string literals and regular strings, but I think I'm all set
> now.  It seems I've been spoiled by Python.

Check out Chapter 5 of Ada Plus Data Structures.  The application in
the Stack Chapter is a postfix expression evaluator.  The original
expression is stored in an unbounded string.  The programming
assignment I give to my class for this chapter uses infix expressions.

John




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-14 18:51 ` Jeffrey R. Carter
@ 2008-10-15 15:22   ` Adam Beneschan
  2008-10-15 17:23     ` Jeffrey R. Carter
                       ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Adam Beneschan @ 2008-10-15 15:22 UTC (permalink / raw)


On Oct 14, 11:51 am, "Jeffrey R. Carter"
<spam.jrcarter....@spam.acm.org> wrote:
> Joe wrote:
>
> > I'm trying to build a simple stack the evaluates expressions in
> > postfix notation (i.e. "1 2 +").  I can't find a way to use the
> > operator directly when I get to it.  When I get to the  "+", but how
> > do I apply this string to 1 and 2?  The best I can do is make a case
> > statement that has a case for each binary operator, but this seems
> > very klunky.  I know you can write "+"(1,2) to return 3 but how do I
> > get Ada to recognize the string as an operator?  Here's a short
> > example of what I would like to do:
>
> The short answer is that you can't. You have to evaluate "1" and "2" to get
> values of some numeric type and push them on a stack, then find a branch in an
> if-elsif-else chain

If-elsif-elsif-elsif-elsif-elsif-else chain?  That's not very
imaginative!  Why not:

    type Operator_Descriptor is record
        Name      : access String;
        Operation : access function (Left, Right : Integer)
                             return Integer;
    end record;
    type Operator_Desc_Array is
        array (natural range <>) of Operator_Descriptor;

    Available_Operators : constant Operator_Desc_Array :=
        ((new string' ("+"), Plus'access),
         (new string' ("-"), Minus'access), .......);

Then you can search the array for an element whose Name.all matches
the operator string, and then call the Operation function of the
element.  You'll have to write Plus, Minus, etc., since you can't take
the 'access of an intrinsic function.  If you want to mix some unary
operators in the array, you might use a variant record, or with a
tagged type that has "Unary_Operation" or "Binary_Operation" type
extensions, or something along those lines.

Although it isn't always possible, I definitely prefer to set things
up in an array or some sort of data structure when possible, rather
than to rely on a 67-branch IF statement or even a CASE statement.

                               -- Adam






^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-15 15:22   ` Adam Beneschan
@ 2008-10-15 17:23     ` Jeffrey R. Carter
  2008-10-15 19:32     ` sjw
  2008-10-16  8:14     ` Dmitry A. Kazakov
  2 siblings, 0 replies; 12+ messages in thread
From: Jeffrey R. Carter @ 2008-10-15 17:23 UTC (permalink / raw)


Adam Beneschan wrote:
> 
> If-elsif-elsif-elsif-elsif-elsif-else chain?  That's not very
> imaginative!  Why not:
> 
>     type Operator_Descriptor is record
>         Name      : access String;
>         Operation : access function (Left, Right : Integer)
>                              return Integer;
>     end record;

I detest anonymous types.

> Although it isn't always possible, I definitely prefer to set things
> up in an array or some sort of data structure when possible, rather
> than to rely on a 67-branch IF statement or even a CASE statement.

By the time you've written all the support functions and the scaffolding to 
handle both unary and binary operations, your code is at least as big as with 
the big if statement, and less clear. If you're allowing a client to define the 
operators and their actions, this would be the way to go, but for hard-coded 
choices, I prefer the if statement.

-- 
Jeff Carter
"Unix and C are the ultimate computer viruses."
Richard Gabriel
99



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-15 15:22   ` Adam Beneschan
  2008-10-15 17:23     ` Jeffrey R. Carter
@ 2008-10-15 19:32     ` sjw
  2008-10-16  8:14     ` Dmitry A. Kazakov
  2 siblings, 0 replies; 12+ messages in thread
From: sjw @ 2008-10-15 19:32 UTC (permalink / raw)


On Oct 15, 4:22 pm, Adam Beneschan <a...@irvine.com> wrote:

>     Available_Operators : constant Operator_Desc_Array :=
>         ((new string' ("+"), Plus'access),
>          (new string' ("-"), Minus'access), .......);
>
> Then you can search the array for an element whose Name.all matches
> the operator string, and then call the Operation function of the
> element.

Or you could use the Containers library - looks like a Map from string
to access-to-function



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Using a string as a binary operator
  2008-10-15 15:22   ` Adam Beneschan
  2008-10-15 17:23     ` Jeffrey R. Carter
  2008-10-15 19:32     ` sjw
@ 2008-10-16  8:14     ` Dmitry A. Kazakov
  2 siblings, 0 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2008-10-16  8:14 UTC (permalink / raw)


On Wed, 15 Oct 2008 08:22:36 -0700 (PDT), Adam Beneschan wrote:

> Although it isn't always possible, I definitely prefer to set things
> up in an array or some sort of data structure when possible, rather
> than to rely on a 67-branch IF statement or even a CASE statement.

This is what I do in my parsers. I use an enumeration type for the
operations. For example:

   type Operations is
           (  Add, Sub, Mul, Div, Pow,    -- Infix operators
              Abs_Value, Plus, Minus,     -- Prefix operators
              Left_Bracket, Right_Bracket -- Brackets
           );

When the parser pops an operation from the stack of operations it calls the
corresponding primitive operation (of the stack type) that switches over
Operations value using plain case statement.

I don't define unary and binary operations separately, because with
subprograms supported the number of arguments will vary anyway. Then even
for +, I prefer to allow the parser to coalesce expressions like

  "+" ("+" (A, B), C)

into

  "+" (A, B, C)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2008-10-16  8:14 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-14 15:35 Using a string as a binary operator Joe
2008-10-14 17:05 ` Dmitry A. Kazakov
2008-10-14 18:51 ` Jeffrey R. Carter
2008-10-15 15:22   ` Adam Beneschan
2008-10-15 17:23     ` Jeffrey R. Carter
2008-10-15 19:32     ` sjw
2008-10-16  8:14     ` Dmitry A. Kazakov
2008-10-14 22:01 ` george.priv
2008-10-15  3:51 ` Gene
2008-10-15  5:45 ` anon
2008-10-15 12:18   ` Joe
2008-10-15 13:43     ` John McCormick

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox