Re: Question

new topic     » goto parent     » topic index » view thread      » older message » newer message

--=====================_852879883==_

At 12:54 9-01-97 +0100, you wrote:
>---------------------- Information from the mail header -----------------------
>Sender:       Euphoria Programming for MS-DOS <EUPHORIA at
>MIAMIU.ACS.MUOHIO.EDU>
>Poster:       Raul Benavides Cordoba <f62becor at UCO.ES>
>Subject:      Question
>-------------------------------------------------------------------------------
>
> Hi everybody,
>
>              I'm a new user of Euphoria. My first questions are:
>
>   - How can I create a small interpreter that one works inside the main
>     program and other that read a file and interpret it?. The reason is
>     that I'm working in a project for my class, (I'm studing Physic and
>     a NOVICE in the Programation), and I want my program interpret at
>     the moment the instructions I give, for example, commands to draw
>     a figure on the screen after I give the instruction and so on.
>
>      The other alternative is to create a small program that reads a ASCII
>     file and interprets it by, for example, turning the screen in colors,
>     for using it in .BAt files.
>
>
>    TANKYOU FOR ALL.
>
>                           HAPPY NEW YEAR...........
>
>
>  P.D: Sorry about my english, because I'm a spanish boy.
>

Hi Raul,

I send you as an attachement turtle.e which is an include file implementing
a simple
drawing robot. the commands are single letter.  For how to use it see comment at
beginning of file.


--=====================_852879883==_

-- NAME: turtle.e
-- OBJECT: graphic drawing using a script language.
-- BY: Jacques Deschenes, Baie-Comeau, Canada, PQ., e-mail: desja at
quebectel.com
-- CREATION DATE: December 21th, 1996
--
--      scripting language:
--  Commands are 1 letter
--  Some commands can have a 1 letter prefix affecting their behavior
--
--  commands follows each other without any separator
--  some commands act on a sub-script which is enclosed in square bracket
--  distances are in pixels
--
--  COMMANDS:
--  notes: 1) [factor] is a programmable parameter
--         2) all displacements are relative to current turtle position except
--            for command M, which is a move to command.
--         3) 0deg. angle point to right, positive angle are anti clockwise
--            negative angles are clockwise.
--
--     Fn   turtle move forward  n*factor pixels  where [n] is an integer
--     C    clear screen and reset all turtle states.
--     D    Pen down means turtle leave a trace screen
--     U    Pen up  mean turtle displacement doesn't leave a trace on screen
--     Ha   Set Heading to angle [a] where [a] is a real number (ex. 39.85)
--     Er[,a]  Draw an filled ellipse (! prefix can be used for empty ellipse)
--              parameter: r is radius in pixel centered to turtle pos
--                         a is long/short axes ratio to be omitted for circle
--     Mx,y  Move turtle to x,y screen coordinate.
--     Pc    Set drawing color used by turtle
--     Rn[script]   repeat n times the script enclosed in square bracket.
--     Ta    Turn by the specified [a] angle if a > 0 rotate left else right
--     Wn    Set trace width in pixel. where [n] is a positive integer.
--     X[=|+|-|*|/]n  Set a new scale factor.
--                 =  set factor egal to n
--                 +  increase current factor by a value
--                 -  decrease current factor by a value
--                 *  multiply scale factor by a value
--                 /  divide scale factor by a value
--
--     %v[=|+|-|*|/]n Set a variable, where v is var. id. in range A..Z
--                 =  set variable v egal to n
--                 +  add n to actual value of the variable
--                 -  substract n to actual value of the variable
--                 *  multiply actual value of var. by n
--                 /  divide actual value of var. by n
--
-- COMMAND PREFIX:
--     N  "No update" prefix, to be used before command F or [. Turtle come back
--         to it's original state after execution of prefexed command or
--         subscript.
--         the effect of N is to push on stack all turtle states.
--
--     !  "No paint" prefix, to be used with E to draw hollow ellipse
-----------------------------------------------------------------------------
--
--    EXPORTED:
--  function UCase(sequence String)
--  procedure DrawTurtle(sequence script)
--  function InitTurtle(integer gmode)

include graphics.e

integer CurrentX,  -- Current x coord of turtle
        CurrentY,  -- Current y coord of turtle
        PenWidth,  -- pen width in pixel
        PenColor   -- pen color

atom    Head,      -- turtle heading angle.
        Factor     -- scale factor.

sequence Stack, -- use to preserve turtle parameters
                     -- {PenWidth,PenColor,Head,Factor,CurrentX,CurrentY}
                     -- see PushState() and PopSate()
         VarList,    -- containt variables values: %A to %Z
         vc          -- video config information. Set by InitTurtle()

constant PI = 3.141592654


---------------------------------------------


global function UCase(sequence String)  -- convert to upper case
sequence UStr
    UStr = {}
    for i = 1 to length(String) do
        if String[i] >= 'a' and String[i] <= 'z' then
            UStr = UStr & String[i] - 'a' + 'A'
        else
            UStr = UStr & String[i]
        end if
    end for
    return UStr
end function -- UCase()

---------------------------------------------

global function InitTurtle(integer gmode)
-- input: gmode  is graphic mode to be set.
-- output: 1 if success else 0
integer junk

  junk = graphics_mode(gmode)
  if junk then
    return 0
  end if
  vc = video_config()
  -- center turtle to screen
  CurrentX = floor(vc[VC_XPIXELS]/2)
  CurrentY = floor(vc[VC_YPIXELS]/2)
  Head = 0
  Factor = 1
  PenWidth = 1
  PenColor = 15
  Stack = {}
  VarList=repeat(0,26)
  return 1
end function --InitTurtle()


---------------------------------------------

procedure PushState()
-- sequence order is {PenWidth,PenColor,Head,Factor,CurrentX,CurrentY}
    Stack = append(Stack,{PenWidth,PenColor,Head,Factor,CurrentX,
                        CurrentY})
end procedure -- PushSate()

---------------------------------------------

procedure PopState()
sequence last
    if length(Stack) = 0 then
        return
    end if
    last = Stack[length(Stack)]
    PenWidth = last[1]
    PenColor = last[2]
    Head = last[3]
    Factor = last[4]
    CurrentX = last[5]
    CurrentY = last[6]
    Stack = Stack[1..length(Stack)-1]
end procedure -- PopSate()

---------------------------------------------

procedure TurtleEllipse(integer color, -- color of ellipse
                        integer fill,  -- set to 1 to fill ellipse
                        integer width,  -- thickness of the line
                        integer radius, -- radius of ellipse
                        atom ratio      -- x_radiu/y_radius
                      )
integer x1,y1,x2,y2
integer rx, ry
    rx = radius*ratio
    ry = floor(radius/ratio)
    x1 = CurrentX - rx
    y1 = CurrentY - ry
    x2 = CurrentX + rx
    y2 = CurrentY + ry
    if fill then
      ellipse(color,1,{x1,y1},{x2,y2})
    else
      for i = 0 to width - 1  do
        ellipse(color,0,{x1+i,y1+i},{x2-i,y2-i})
      end for
    end if
end procedure -- TurtleEllipse()

---------------------------------------------

-- trace a line from current position
procedure TurtleForward(integer color, -- pen color
                        integer width, -- pen width
                        integer d,     -- distance
                        atom a,        -- angle
                        )
sequence c1,c2,c3,c4
integer NewX, NewY
integer wx, wy

  NewX = floor(CurrentX + cos(a) * d )
  NewY = floor(CurrentY + (-sin(a) * d))
  if width = 1 then
    draw_line(color,{{CurrentX,CurrentY},{NewX,NewY}})
    CurrentX = NewX
    CurrentY = NewY
    return
  end if
  if NewX = CurrentX then -- vertical lines
     wx = floor(width/2)
     wy = wx
     c1 = {NewX - wx,CurrentY}
     c2 = {NewX - wx,NewY}
     c3 = {NewX + wx,NewY}
     c4 = {NewX + wx,CurrentY}
     ellipse(color,1,{CurrentX-wx,CurrentY-wy},{CurrentX + wx,CurrentY+wy})
     ellipse(color,1,{NewX-wx,NewY-wy},{NewX+wx,NewY+wy})

  elsif NewY = CurrentY then -- horizontal lines
     wy = floor(width/2)
     wx = wy
     c1 = {CurrentX,NewY - wy}
     c2 = {NewX,NewY - wy}
     c3 = {NewX,NewY + wy}
     c4 = {CurrentX,NewY + wy}
     ellipse(color,1,{CurrentX-wx,CurrentY-wy},{CurrentX+wx,CurrentY+wy})
     ellipse(color,1,{NewX-wx,NewY-wy},{NewX+wx,NewY+wy})
  else  -- other angle
     wx = floor((sin(a) * width)/2)
     wy = floor((cos(a) * width)/2)
     c1 = {CurrentX - wx, CurrentY - wy}
     c2 = {NewX - wx, NewY - wy}
     c3 = {NewX + wx, NewY + wy}
     c4 = {CurrentX + wx, CurrentY + wy}
     ellipse(color,1,c1,c4)
     ellipse(color,1,c2,c3)
  end if
  polygon(color,1,{c1,c2,c3,c4})
  CurrentX = NewX
  CurrentY = NewY
end procedure --TurtleForward()

---------------------------------------------

function GetVal(sequence script, integer i)
-- get numerical parameter from script. Scanning start at position i
-- output: {error,value, Updated i}

integer c, q, neg,VarId
atom Nb
    if i > length(script) then
        return {1,0,i}  -- error
    end if
    script = script
    Nb = 0
    q = 0
    neg = 0
    c = script[i]
    if c = '%' then
        i = i + 1
        VarId = script[i]-'A'+1
        if VarId <1 or VarId > 26 then
            return {1,0,i}
        end if
        return {0,VarList[VarId],i+1}

    elsif c = '-' then
      neg = 1
    elsif c = '+' then
      neg = 0
    elsif find(c,"0123456789") then
        Nb = c-'0'
    elsif c = '.' then
        q = 1
    else
        return {1,0,i}
    end if
    i = i + 1
    while i < length(script)  do
        c = script[i]
        i = i + 1
        if find(c,"0123456789") then
            Nb = Nb*10+c-'0'
            q = q*10
        elsif c = '.' then
             if q > 0 then
                i = i - 1
                exit
             end if
             q = 1
        else
           i = i - 1
           exit
        end if
    end while
    if q > 0 then
        Nb = Nb/q
    end if
    if neg then
        Nb = -Nb
    end if
    return {0,Nb,i}
end function -- GetVal()

---------------------------------------------

global procedure TurtleDraw (sequence script)

  atom    Ratio,    -- ellipse axes ratio
          Radius,   -- ellipse radius
          Param     -- receive command parameter


  integer PenDown,  -- current pen state (1 if down)
          UpDate,   -- set to 1 for  turtle position update
          RepCnt,   -- repetion count for command R
          Fill,     -- set to 1 for filled ellipse
          Depth,    -- square bracket depth
          s_len,    -- script length
          i,        -- index into script
          j,        -- another index into script
          char,     -- Hold char from script[i]
          VarId     -- Variable identifier

  sequence NumVal   -- sequence containing the number returned by GetVal()

  PenDown = 1
  Fill = 1
  UpDate = 1
  i = 1
  script = UCase(script)&' '
  s_len = length(script)

  while i <= s_len do
    char = script[i]
    i = i + 1

    if char = '!' then -- No fill
        Fill = 0

      elsif char = '%' then -- set variable
        VarId = script[i] - 'A' + 1
        if VarId <1 or VarId > 26 then
            exit
        end if
        i = i + 1
        char = script[i]
        i = i + 1
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
                exit
        end if
        if char = '=' then
            VarList[VarId] = NumVal[2]
          elsif char = '+' then
            VarList[VarId] = VarList[VarId] + NumVal[2]
          elsif char = '-' then
            VarList[VarId] = VarList[VarId] - NumVal[2]
          elsif char = '*' then
            VarList[VarId] = VarList[VarId] * NumVal[2]
          elsif char = '/' then
            VarList[VarId] = VarList[VarId] / NumVal[2]
        end if

      elsif char = ' ' or char = ','  then --skip blanck and comma

      elsif char = 'C' then

        clear_screen()
        Head = 0
        PenColor = 15
        PenWidth = 1
        UpDate = 1
        Fill = 1
        Factor = 1
        CurrentX = floor(vc[VC_XPIXELS]/2)
        CurrentY = floor(vc[VC_YPIXELS]/2)
        Stack = {}
        VarList = repeat(0,26)

      elsif char = 'F'  then --forward move
        NumVal = GetVal(script, i)
        i = NumVal[3]
        if NumVal[1] then
            exit
        end if
        Param = NumVal[2] * Factor
        if PenDown then
          TurtleForward(PenColor,PenWidth,Param,Head)
        else
          CurrentX = floor(CurrentX + cos(Head) * Param)
          CurrentY = floor(CurrentY + (-sin(Head) * Param))
        end if
        if not UpDate then
          PopState()
          UpDate = 1
        end if

      elsif char = 'D' then --Pen Down
        PenDown = 1

      elsif char = 'H' then  -- set heading
        NumVal = GetVal(script, i)
        i = NumVal[3]
        if NumVal[1] then
            exit
        else
            Head = NumVal[2] * PI / 180
        end if

      elsif char = 'E' then  --draw ellipse
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
            exit
        end if
        Radius = NumVal[2] * Factor
        if script[i] != ',' then
          Ratio = 1 --circle
        else
          i = i + 1
          NumVal = GetVal(script, i)
          i = NumVal[3]
          if NumVal[1] then
              exit
          end if
          Ratio = NumVal[2]
        end if
        TurtleEllipse(PenColor,Fill,PenWidth,Radius,Ratio)
        Fill = 1

      elsif char = 'U'  then --Pen Up
        PenDown = 0

      elsif char = 'M' then -- move turtle to
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
            exit
        end if
        CurrentX = floor(NumVal[2])
        i = i + 1
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
            exit
        end if
        CurrentY = floor(NumVal[2])

      elsif char = 'N' then --set No update
        UpDate = 0
        PushState()

      elsif char = 'P'  then --set Pen color
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
                exit
        end if
        PenColor = floor(NumVal[2])

      elsif char = 'R' then --repeat sub-script (use recursive call)
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
                exit
        end if
        RepCnt = NumVal[2]
        if script[i] != '[' then
          exit
        end if
        i = i + 1
        j = i
        Depth = 1
        while Depth > 0 and i <= length(script) do
          if script[i] = '[' then
              Depth = Depth + 1
          elsif script[i] = ']' then
            Depth = Depth - 1
          end if
          i = i + 1
        end while
        for nx = 1 to RepCnt do
          TurtleDraw(script[j..i-1])
        end for
        if not UpDate then
           PopState()
           UpDate = 1
        end if

      elsif char = 'T'  then  -- Turn (heading rotation)
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
                exit
        end if
        Head = Head + NumVal[2] * PI / 180

      elsif char = 'W' then -- set pen width
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
                exit
        end if
        PenWidth = floor(NumVal[2])

      elsif char = 'X' then -- change scale factor
        char = script[i]
        i = i + 1
        NumVal = GetVal(script,i)
        i = NumVal[3]
        if NumVal[1] then
                exit
        end if
        if char = '=' then
            Factor = NumVal[2]
          elsif char = '+' then
            Factor = Factor + NumVal[2]
          elsif char = '-' then
            Factor = Factor - NumVal[2]
          elsif char = '*' then
            Factor = Factor * NumVal[2]
          elsif char = '/' then
            Factor = Factor / NumVal[2]
        end if
        if Factor < 1 then Factor = 1 end if

      elsif char = '['  then --make recursive call
        j = i
        Depth = 1
        while Depth > 0 and i <= length(script) do
          if script[i] = '[' then
              Depth = Depth + 1
            elsif script[i] = ']' then
                Depth = Depth - 1
          end if
          i = i + 1
        end while
        PushState()
        TurtleDraw(script[j..i-1])
        PopState()
        if not UpDate then
          PopState()
          UpDate = 1
        end if

      elsif char = ']'  then -- get out of recursive call
        exit

      else
        exit

    end if
  end while
end procedure -- TurtleDraw()

if not InitTurtle(18) then  -- initialise by default to VGA 640X480, 16 COLORS
  puts(1,"Failed to initialise turtle.")
  abort(1)
end if



--=====================_852879883==_

Jacques Deschenes
Baie-Comeau, Quebec
Canada
desja at quebectel.com

--=====================_852879883==_--

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu