1. Self Modifying Code

Is there a way to write self-modifying code in Euphoria? Or, perhaps, more simply, to have a Euphoria program write Euphoria code to an external file and then later "include" it in the same program?

new topic     » topic index » view message » categorize

2. Re: Self Modifying Code

lgregg said...

Is there a way to write self-modifying code in Euphoria? Or, perhaps, more simply, to have a Euphoria program write Euphoria code to an external file and then later "include" it in the same program?

Have you looked at the Preprocessor ?

It's not something I've used, but might work for your requirement.

Due to the parsing order (I'm guessing) Euphoria tries to read all the includes first, before running any code, so the following sort of thing will not work:

atom fn = open("time.e","w") 
puts(fn,sprintf("atom clock=%d",time())) 
close(fn) 
 
include time.e 
? clock 

<0052>:: can't find 'time.e' in any of ... 
    /home/irv 
    /home/irv/inc.ex 
    /home/irv/demos 
    /usr/local/include 
 
include time.e 
              ^ 

There's always the possibility of having your code write a (modified) copy of itself, then run that copy, I suppose.

It all depends upon what you are trying to do. Need more details - for example, EuGTK can certainly modify a program's appearance on the fly - button labels, colors, text, visibility of controls, etc. thru the use of simple .ini files, which can be written and loaded at any point, not just on startup.

new topic     » goto parent     » topic index » view message » categorize

3. Re: Self Modifying Code

irv said...
lgregg said...

Is there a way to write self-modifying code in Euphoria? Or, perhaps, more simply, to have a Euphoria program write Euphoria code to an external file and then later "include" it in the same program?

Have you looked at the Preprocessor ?

It's not something I've used, but might work for your requirement.

Due to the parsing order (I'm guessing) Euphoria tries to read all the includes first, before running any code, so the following sort of thing will not work:

atom fn = open("time.e","w") 
puts(fn,sprintf("atom clock=%d",time())) 
close(fn) 
 
include time.e 
? clock 

<0052>:: can't find 'time.e' in any of ... 
    /home/irv 
    /home/irv/inc.ex 
    /home/irv/demos 
    /usr/local/include 
 
include time.e 
              ^ 

There's always the possibility of having your code write a (modified) copy of itself, then run that copy, I suppose.

It all depends upon what you are trying to do. Need more details - for example, EuGTK can certainly modify a program's appearance on the fly - button labels, colors, text, visibility of controls, etc. thru the use of simple .ini files, which can be written and loaded at any point, not just on startup.

It seems like so much of the World Wide Web is built with php, using embedded php code in html documents. For example:

<!DOCTYPE html> 
<html> 
<body> 
 
<?php 
$txt = "Hello world!"; 
$x = 5; 
$y = 10.5; 
 
echo $txt; 
echo "<br>"; 
echo $x; 
echo "<br>"; 
echo $y; 
?> 
 
</body> 
</html> 

BUT, why could we not do something similar using Euphoria?

<!DOCTYPE html> 
<html> 
<body> 
 
<?euphoria 
sequence txt = "Hello world!" 
integer x = 5 
atom y = 10.5 
 
printf(1,"txt=%s\n",{txt}) 
printf(1,"x=%g\n",x) 
printf(1,"y=%g\n",y) 
?> 
 
</body> 
</html> 

I wrote a preprocessor using an example from the OpenEuphoria site, to extract the Euphoria code and execute it. At this time, it does not return an html document with the embedded Euphoria code replaced with the results of running the preprocessor, although I imagine that is possible. I thought that Self Modifying code might be helpful. Here is the preprocessor:

/* 
Program:  process_file_eup.ex 
Date:  19-JAN-2019 
Purpose: To read a file and process one line at at time, pulling 
			out Euphoria (or other) code and writing to a file. 
			Blank lines are not output. 
			Should be able to use as a Euphoria pre-processor. 
Invocation: eui process_file_eup.ex i text_file o code_file 
				or as a preprocessor 
				eui extension:process_file_eup.ex {filename.extension (as shown earlier)} 
				e. g. 
				eui html:process_file_eup.ex eup_test_2.html 
 
*/ 
public include std/cmdline.e 
public include std/io.e 
public include std/sequence.e 
public include std/text.e 
 
 
constant begin_tag = lower("<?euphoria") -- change for other start tag 
		 , begin_tag_len = length(begin_tag) 
		 , end_tag = "?>" -- change for other stop tag 
		 , end_tag_len = length(end_tag) 
 
integer start = 0, stop  = 0 
sequence NULL = "" 
 
-- Process each supplied line. 
function process_each_line(sequence aLine, integer line_no, object data) 
	sequence lp=NULL 
	integer beginpos=0, endpos=0, done=0 
--		printf(data[1],"aLine=%s, start=%g\n",{aLine}&start) 
 
	loop do 
		if start = 0 then 
			beginpos = match(begin_tag, lower(aLine)) 
			if beginpos > 0 then 
				start = 1 
				aLine = aLine[beginpos + begin_tag_len .. $] 
			end if 
		end if 
		 
		if start = 1 then 
			endpos = match(end_tag, aLine) 
			if endpos > 0 then 
				stop = 1 
				lp = aLine[endpos + end_tag_len .. $] 
				aLine = aLine[1 .. endpos - 1] 
			end if 
		end if 
 
		if start = 1 and length(aLine) > 0 then 
			printf(data[1],"%s\n",{aLine}) 
		end if 
		 
		if stop = 1 then 
			start = 0 
			stop = 0 
		end if 
		 
		if length(lp) > 0 then 
			aLine = lp 
			lp = NULL 
		else 
			done = 1 
		end if 
			 
		until done=1 
	end loop 
 
	if data[2] > 0 and line_no = data[2] then 
		return 1 
	else 
		return 0 
  end if 
end function 
 
 
-- Main 
procedure main() 
integer in1, out1 
sequence cmd, extras 
 
cmd = command_line() 
if length(cmd) > 6 then 
	extras = cmd[7] 
else extras = {} 
end if 
 
--  Get input file 
if length(cmd) < 4 
	or compare(upper(cmd[4]),"STDIN") = 0 
then in1 = STDIN  
else 
	in1 = open(cmd[4],"r") 
	if in1 = -1 then  
		printf(1,"Could not open input file, %s, aborting\n",{cmd[4]}) 
		abort (11) 
	end if 
end if 
 
--  Get output file 
if length(cmd) < 6 
	or compare(upper(cmd[6]),"STDOUT") = 0 
then out1 = STDOUT  
else 
	out1 = open(cmd[6],"w") 
	if out1 = -1 then 
		printf(1,"Could not open ouput file, %s, aborting\n",{cmd[6]}) 
		abort (12) 
	end if 
end if 
 
--  The first element of the third argument is the output file handle 
process_lines(in1, routine_id("process_each_line"), {out1, 0}) 
 
close(in1) 
close(out1) 
 
end procedure 
main() 
 

new topic     » goto parent     » topic index » view message » categorize

4. Re: Self Modifying Code

lgregg said...

It seems like so much of the World Wide Web is built with php, using embedded php code in html documents. For example:

Just because PHP does it, and just because PHP is popular, does not make this approach good. See: Appeal to Popularity.

This is my biggest gripe with PHP. Having the ability to intermix backend code with frontend markup is very bad and very sloppy.

Designing an application around proper separation of concerns leads to a cleaner design that's (if done well) easier to maintain.

lgregg said...

BUT, why could we not do something similar using Euphoria?

What you're looking for already exists. It's running this website right now. Check out the euweb project, which is built with Jeremy's webclay. Specifically etml.ex, the HTML/code preprocessor.

lgregg said...

I wrote a preprocessor using an example from the OpenEuphoria site, to extract the Euphoria code and execute it. At this time, it does not return an html document with the embedded Euphoria code replaced with the results of running the preprocessor, although I imagine that is possible. I thought that Self Modifying code might be helpful. Here is the preprocessor:

I firmly believe that self-modifying code is a very bad idea. I think that if you've reach this idea as a solution, you need to take a step back and re-examine your approach. What exactly is the problem you're trying to solve?

I'm planning to replace euweb/webclay with a new framework: Euphoria MVC. This new framework provides cleaner separation of the parts of your web application. I think you'll like it. Please check it out.

At the very least, you may be interested in the template parser. It supports basic Euphoria code structures like if and for. There's also automatic dot notation for map keys, which makes for very clean code markup? template logic.

-Greg

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu