Re: Question
--=====================_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==_--
|
Not Categorized, Please Help
|
|