Results 1 to 2 of 2

Thread: Exponents using variants ... and death thereby.

  1. #1

    Exponents using variants ... and death thereby.

    I'm going to do something I don't normally do, but I'll give full source along with this. It's just a test bed, but part of a bigger project.

    One of my annoyances is that data is either arbitrarily compiled, thus never changing except when you recompile, or or stored in an external format. Sometimes these external formats are just too heavy and bloated for a given purpose. Thus I was working on a makeshift parser and tokenizer which relies heavily upon the use of variants. If these wacky bugs continue I swear I'll switch to FPC!

    Anyway. I made a very simple console application that takes an input string and tokenizes it into an array of strings. From there the first is a command followed by data. So to permit things like mixing integers and floats I started using variants. There are only 4 functions:
    • Sum: totals all following numbers regardless of format or type. Works like a charm.
    • Sub: Subtracts number 2 from number 1; also works like a charm.
    • Power: Calculates x1 to the x2 power; dies like Dracula with a stake in his chest.
    • Exit: <_<


    What I have determined through the use of breakpoints is that in power the two numbers are never assigned, and that the output is never written. Almost as if that part of the code just isn't called at all; but is should be.

    Anyone have any clues? I'm using Turbo Delphi with the hotfix rollup with the following code. I'm about to go mad! I have tried 3-4 different ways of assignment but I can't get variants in this section to function, or breakpoints either (anymore). Oddest of all, when I first added the functionality it WORKED -- now it doesn't. I will assuredly need variants once I start the true function call implementations!

    Remember, I am showing this for troubleshooting purposes; don't use it without asking me first. Here's the code:
    Code:
    program tokenizer;
    
    &#123;$APPTYPE CONSOLE&#125;
    
    uses
      SysUtils, Math, Variants;
    
    type TDynStrArray = array of string;  
    
        function tokenize&#40;line&#58; string&#41;&#58; TDynStrArray;
        var temp&#58; string;
            l,i&#58; cardinal;
            inStr,wasStr&#58; boolean;
        begin
          l &#58;= 0;
          temp &#58;= line;
          instr &#58;= false;
    
          while temp <> '' do begin
            if l > length&#40;result&#41;-1 then
              SetLength&#40;result, l+8&#41;;
            wasStr &#58;= false;
            for i &#58;= 1 to Length&#40;temp&#41; do
              case temp&#91;i&#93; of
                '`'&#58; begin inStr &#58;= not inStr; wasStr &#58;= true; end;
                ' ',#0&#58; if not inStr then Break;
              end;
            if not wasStr then
              result&#91;l&#93; &#58;= copy&#40;temp,1,i-1&#41;
            else
              result&#91;l&#93; &#58;= copy&#40;temp,2,i-3&#41;;
            Delete&#40;temp,1,i&#41;;
            inc&#40;l&#41;;
          end;
    
          setlength&#40;result,l&#41;;
        end;
    
    var inputtokens&#58; TDynStrArray;
        input&#58; string;
        i&#58; integer;
        exit&#58; boolean = false;
        v1,v2&#58; variant;
    
    begin
      writeln&#40;'Enter tokens seperated by spaces, strings delimited by `''s.'&#41;;
    
      repeat
        v1 &#58;= 0;
        v2 &#58;= 0;
        input &#58;= '';
        setlength&#40;inputtokens,0&#41;;
    
        write&#40;'> '&#41;; readln&#40;input&#41;;
        writeln;
    
        if input <> '' then begin
          inputtokens &#58;= tokenize&#40;input&#41;;
    
          for i &#58;= 0 to Length&#40;inputtokens&#41; - 1 do
            writeln&#40;'Token'#9'#',i,'&#58; "',inputtokens&#91;i&#93;,'"'&#41;;
          writeln;
    
          if inputtokens&#91;0&#93; = 'sum' then begin
            v1 &#58;= Variant&#40;inputtokens&#91;1&#93;&#41; + 0;
            for i &#58;= 2 to length&#40;inputtokens&#41; - 1 do begin
              v2 &#58;= inputtokens&#91;i&#93;;
              v1 &#58;= v1 + v2;
            end;
    
            writeln&#40;'Sum&#58;'#9,v1&#41;;
          end else if inputtokens&#91;0&#93; = 'sub' then
            if length&#40;inputtokens&#41; >= 3 then
              writeln&#40;'Sub&#58;'#9,Variant&#40;inputtokens&#91;1&#93;&#41; - Variant&#40;inputtokens&#91;2&#93;&#41;&#41;
          else if inputtokens&#91;0&#93; = 'pwr' then
            if length&#40;inputtokens&#41; >= 3 then begin
              v1 &#58;= 0.0 + Math.Power&#40;StrToFloatDef&#40;inputtokens&#91;1&#93;,0&#41;,StrToFloatDef&#40;inputtokens&#91;2&#93;,0.0&#41;&#41;;
              writeln&#40;'Power&#58;'#9,v1&#41;;
            end else writeln&#40;'Error, PWR given too few parameters.'&#41;
          else
            writeln&#40;'Unknown command "',inputtokens&#91;0&#93;,'"'&#41;;
    
          exit &#58;= pos&#40;'exit',input&#41; > 0;
          
        end;
    
        writeln;
      until &#40;exit&#41;;
    end.
    (Someone needs to look into posting... I had to disable HTML to post this at all; it died between the list and the code, but the code wasn't wrapped correctly.)

  2. #2

    Exponents using variants ... and death thereby.

    I solved it myself. I realized that when I called "sub" with no parameters I ran into the "pwr" breakpoint that something was dreadfully wrong. It mixed the stupid if-the-else's up so I had to add some begin/end's to make sure it worked properly.

    :roll:

    Here's the working code for those interested:
    Code:
    program tokenizer;
    
    &#123;$APPTYPE CONSOLE&#125;
    
    uses
      SysUtils, Math&#123;, Variants&#125;;
    
    type TDynStrArray = array of string;  
    
        function tokenize&#40;line&#58; string&#41;&#58; TDynStrArray;
        var temp&#58; string;
            l,i&#58; cardinal;
            inStr,wasStr&#58; boolean;
        begin
          l &#58;= 0;
          temp &#58;= line;
          instr &#58;= false;
    
          while temp <do> length&#40;result&#41;-1 then
              SetLength&#40;result, l+8&#41;;
            wasStr &#58;= false;
            for i &#58;= 1 to Length&#40;temp&#41; do
              case temp&#91;i&#93; of
                '`'&#58; begin inStr &#58;= not inStr; wasStr &#58;= true; end;
                ' ',#0&#58; if not inStr then Break;
              end;
            if not wasStr then
              result&#91;l&#93; &#58;= copy&#40;temp,1,i-1&#41;
            else
              result&#91;l&#93; &#58;= copy&#40;temp,2,i-3&#41;;
            Delete&#40;temp,1,i&#41;;
            inc&#40;l&#41;;
          end;
    
          setlength&#40;result,l&#41;;
        end;
    
    var inputtokens&#58; TDynStrArray;
        input&#58; string;
        i&#58; integer;
        exit&#58; boolean = false;
        v1,v2&#58; variant;
    
    begin
      writeln&#40;'Enter tokens seperated by spaces, strings delimited by `''s.'&#41;;
    
      repeat
        v1 &#58;= 0;
        v2 &#58;= 0;
        input &#58;= '';
        setlength&#40;inputtokens,0&#41;;
    
        write&#40;'> '&#41;; readln&#40;input&#41;;
        writeln;
    
        if input <then>= 3 then
              writeln&#40;'Sub&#58;'#9,Variant&#40;inputtokens&#91;1&#93;&#41; - Variant&#40;inputtokens&#91;2&#93;&#41;&#41;;
          end else if inputtokens&#91;0&#93; = 'pwr' then
            if length&#40;inputtokens&#41; >= 3 then begin
              v1 &#58;= 0.0 + Math.Power&#40;StrToFloatDef&#40;inputtokens&#91;1&#93;,0&#41;,StrToFloatDef&#40;inputtokens&#91;2&#93;,0.0&#41;&#41;;
              writeln&#40;'Power&#58;'#9,v1&#41;;
            end else writeln&#40;'Error, PWR given too few parameters.'&#41;
          else
            writeln&#40;'Unknown command "',inputtokens&#91;0&#93;,'"'&#41;;
    
          exit &#58;= pos&#40;'exit',input&#41; > 0;
          
        end else writeln&#40;'Enter something I can process first.'&#41;;
    
        writeln;
      until &#40;exit&#41;;
    end.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •