Re: Question
- Posted by Jacques Deschenes <desja at QUEBECTEL.COM> Jan 09, 1997
- 734 views
--=====================_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==_--