1. Automatic entry point preprocessor

Forked from Re: Interesting benchmark results - Euphoria vs. Euphoria

ghaberek said...
mattlewis said...

I think wrapping it in a main() function isn't much cheating, since many languages make you do that anyways.

I do this all the time, simply as a measure of proper practice. It sure would be nice if Euphoria ran a main() routine automatically. (wink wink, nudge nudge) blink

Oh what the heck, here's a preprocessor that adds an entry point automatically. smile

Side note: does <eucode> not handle multi-line triple-quotes or multi-line backticks correctly? getlost

entrypoint.e

 
include std/filesys.e 
include std/regex.e 
include std/text.e 
without type_check 
without warning 
 
constant ENTRY_POINT_FUNC_EMPTY = "" 
& EOL 
& "-- automatic entry point" & EOL 
& "abort( main() ) " & EOL 
& EOL 
 
constant ENTRY_POINT_FUNC_PARAM = "" 
& EOL 
& "-- automatic entry point" & EOL 
& "abort( main(length(command_line()), command_line()) )" & EOL 
& EOL 
 
constant ENTRY_POINT_PROC_EMPTY = "" 
& EOL 
& "-- automatic entry point" & EOL 
& "main()" & EOL 
& EOL 
 
constant ENTRY_POINT_PROC_PARAM = "" 
& EOL 
& " -- automatic entry point" & EOL 
& " main( length(command_line()), command_line() )" & EOL 
& EOL 
 
regex re_main_empty = regex:new(`^(procedure|function)\s+main\(\s*\)`) 
regex re_main_param = regex:new(`^(procedure|function)\s+main\(\s*integer\s+[a-zA-Z][a-zA-Z0-9_]*\s*,\s*sequence\s+[a-zA-Z][a-zA-Z0-9_]*\s*\)`) 
 
public function preprocess( sequence inFileName, sequence outFileName, sequence options = {} ) 
     
    sequence routine_type = "" -- "function" or "procedure" 
    integer has_params = 0 
     
    integer output = open( outFileName, "w" ) 
    if output = -1 then 
        printf( 2, "could not write file: %s", {outFileName} ) 
        return -1 
    end if 
     
    integer input = open( inFileName, "r" ) 
    if input = -1 then 
        printf( 2, "could not read file: %s", {inFileName} ) 
        return -1 
    end if 
     
    object line = gets( input ) 
    while sequence( line ) do 
         
        -- trim trailing whitespace 
        line = text:trim_tail( line, "\r\n" ) 
         
        if equal( line, "without entrypoint" ) then 
            -- stop processing 
             
            line = gets( input ) 
            exit 
             
        elsif regex:is_match( re_main_empty, line ) then 
            -- this is an entry point without params 
             
            sequence matches = regex:matches( re_main_empty, line ) 
            routine_type = matches[2] 
            has_params = 0 
             
        elsif regex:is_match( re_main_param, line ) then 
            -- this is an entry point with params 
             
            sequence matches = regex:matches( re_main_param, line ) 
            routine_type = matches[2] 
            has_params = 1 
             
        end if 
         
        -- write out this line 
        puts( output, line & EOL ) 
        line = gets( input ) 
         
        if length( routine_type ) then 
            -- stop searching for an entry point 
            exit 
        end if 
         
    end while 
     
    while sequence( line ) do 
        -- copy the rest of the lines 
        puts( output, line ) 
         
    end while 
     
    close( input ) 
     
    switch routine_type do 
        -- output the appropriate entry point 
         
        case "function" then 
            if has_params then 
                puts( output, ENTRY_POINT_FUNC_PARAM ) 
            else 
                puts( output, ENTRY_POINT_FUNC_EMPTY ) 
            end if 
             
        case "procedure" then 
            if has_params then 
                puts( output, ENTRY_POINT_PROC_PARAM ) 
            else 
                puts( output, ENTRY_POINT_PROC_EMPTY ) 
            end if 
             
    end switch 
     
    close( output ) 
     
    return 0 
end function 
 
ifdef not EUC_DLL then 
 
procedure main() 
     
    sequence cmds = command_line() 
    sequence inFileName, outFileName 
     
    for i = 3 to length( cmds ) do 
         
        switch cmds[i] do 
            case "-i" then 
                inFileName = cmds[i+1] 
                 
            case "-o" then 
                outFileName = cmds[i+1] 
                 
        end switch 
         
    end for 
     
    preprocess( inFileName, outFileName ) 
     
end procedure 
 
main() 
 
end ifdef 

eu.cfg

[linux] 
-p ex:entrypoint.sh 
 
[windows] 
-p ex:entrypoint.cmd 

entrypoint.sh

#!/bin/sh 
eui -batch entrypoint.e $* 

entrypoint.cmd

@echo off 
eui.exe -batch entrypoint.e %* 

test.ex (input)

namespace test 
 
function main( integer argc, sequence argv ) 
     
    puts( 1, "Hello, world!\n" ) 
     
    return 0 
end function 

test.pp.ex (output)

namespace test 
 
function main( integer argc, sequence argv ) 
     
    puts( 1, "Hello, world!\n" ) 
     
    return 0 
end function 
 
-- automatic entry point 
abort( main(length(command_line()), command_line()) ) 

example

>eui test.ex 
Hello, world! 

-Greg

new topic     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu