Namespaces

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

--7JfCtLOvnd9MIVvH

Why doesn't euphoria support inline namespaces? it would make combining
include file much easier! instead, if you want namespaces, you either have
to write a program that pulls them out into seperate files, or you
have to write a program that renames the variables & routines in
a program, like I did. Anyone know why?

TIA,
jbrown

P.S. I inclose a namespace program in this email,
and it renames the data, not make a hundred diffrent include files.

-- 
Linux User:190064
Linux Machine:84163
http://jbrown105.1avenue.com


--7JfCtLOvnd9MIVvH
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="namespace.ex"

--namespace.ex
--based on my combine.ex
--based on David Cuny's concat.ex
--Altered to adjust name according to namespace
--Supports routine_id-ing routines in namespace
--Doesn't support multiple namespaces (one inside the other) yet.

--JBrown
--combine.ex
--global scopes aren't redefined
    --this MIGHT cause an error, however, euphoria should normally have an
    --error in that case too.
--procedure-scope vars aren't saved, this makes code more readable
    --N/A if shroud is on
--you can either choose not to combine files in a list, or
    --you can ignore include files on 1 dir (default: eu's include dir)
--shrouding symbols is optional.
--bug fixed: local symbols were being treated as global.
--bug fixed: strings with \x were changed to \x\x.
--bug fixed: file c:\myfile.e and myfile.e were the diffrent files.
--added platform to sequence builtin
--bug: using routine_id("abort_") gives error
    --"Unable to resolve routine id for abort"
    --to fix made routine_id-ing of builtin routines legal.

with trace

-- concat.ex
-- version 1.0
--
-- replacement for Euphoria's bind routine

include get.e
include file.e
include wildcard.e
include misc.e

integer slash, IGNORE
if platform() = 3 then
    slash = '/'
else
    slash = '\\'
end if
IGNORE = 0
sequence ignore_table, ignore_dir
ignore_dir = getenv("EUDIR")&slash&"include"
if ignore_dir[1] = -1 then
    ignore_dir = "include"
end if
ignore_table={ --the default euphoric files
"dll.e",
"file.e",
"get.e",
"graphics.e",
"image.e",
"machine.e",
"misc.e",
"mouse.e",
"msgbox.e",
"safe.e",
"sort.e",
"wildcard.e",
""}


sequence charClass

-- character classes
constant    
    DIGIT       = 1,
    OTHER       = 2,
    LETTER      = 3,
    BRACKET     = 4,
    QUOTE       = 5,
    DASH        = 6,
    WHITE_SPACE = 7,
    NEW_LINE    = 8

    charClass = repeat( OTHER, 255 )

    
    charClass['a'..'z'] = LETTER
    charClass['A'..'Z'] = LETTER
    charClass['_']      = LETTER
    charClass['0'..'9'] = DIGIT
    charClass['[']      = BRACKET
    charClass[']']      = BRACKET
    charClass['(']      = BRACKET
    charClass[')']      = BRACKET
    charClass['{']      = BRACKET
    charClass['}']      = BRACKET
    charClass['\'']     = QUOTE
    charClass['"']      = QUOTE
    charClass[' ']      = WHITE_SPACE
    charClass['\t']     = WHITE_SPACE
    charClass['\n']     = NEW_LINE
    charClass['-']      = DASH

    "constant",
    "do",
    "else",
    "elsif",
    "end",
    "exit",
    "for",
    "function",
    "global",
    "if",
    "include",
    "not",
    "or",
    "procedure",
    "profile",
    "profile_time",
    "return",
    "to",
    "type",   
    "type_check",
    "then",       
    "warning",
    "while",
    "with",
    "without",
    "xor",
    "namespace"} --not really builtin, but treated so


    "and_bits",
    "append",
    "arctan",
    "atom",
    "call",
    "c_func",   
    "c_proc",
    "call_func",
    "call_proc",
    "clear_screen",
    "close",
    "command_line",
    "compare",
    "cos",
    "date",
    "equal",
    "find",
    "floor",
    "get_key",
    "get_pixel",
    "getc",
    "getenv",
    "gets",
    "integer",
    "length",
    "log",
    "machine_func",
    "machine_proc",
    "match",
    "mem_copy",
    "mem_set",
    "not_bits",
    "object",
    "open",
    "or_bits",
    "peek",
    "peek4s",
    "peek4u",
    "pixel",
    "poke",
    "poke4",
    "position",
    "power",
    "prepend",
    "print",
    "printf",
    "profile",
    "puts",
    "rand",
    "remainder",
    "repeat",
    "routine_id",
    "sequence",
    "sin",
    "sprintf",
    "sqrt",         -- missing
    "system",
    "system_exec",
    "tan",
    "time",
    "trace",
    "platform",
    "xor_bits" }


    ids,                    -- count of ids issued
    outFile,                 -- file to write to
    addtype,
    nextGoff,
    inname
    
    globalState = 0         
    routineFlag = 0
    procState = 0
    ids = 0
    addtype = 0
    nextGoff = 0
    inname = 0
    
sequence
    oldProc, newProc,
    oldLocal, newLocal,
    oldGlobal, newGlobal,
    included, types, all_ids, name, names

    oldProc = {}
    newProc = {}
    oldLocal = {}
    newLocal = {}
    oldGlobal = {}
    newGlobal = {}
    included = {}
    types = {"atom", "integer", "object", "sequence"}
    all_ids = {}
    name = {}
    names = {}


constant
    EuPlace = getenv( "EUDIR" ),
    --Place = { "", EuPlace & "\\", EuPlace & "\\INCLUDE\\" }
Place = { current_dir()&slash, EuPlace & slash, EuPlace & slash&"include"&slash,
"" }

    -- returns where a file is
    -- looks in the usual places
    
    -- look in the usual places
    --trace(1)
    if find(fName[length(fName)], {10, 13}) then
	fName = fName[1..length(fName)-1]
    end if
    for i = 1 to length( Place ) do
	if sequence( dir( Place[i] & fName ) ) then
	    if platform() = 3 then
		return Place[i] & fName
	    else
		return upper( Place[i] & fName )
	    end if
	end if
    end for
    
    printf( 1, "Unable to locate file %s.\n", {fName} )
    abort(0)
    
end function

function curnames()
    sequence s
    s = ""
    for i = 1 to length(name) do
	s &= name[i] &"_"
    end for
    return s
end function


    integer at
    sequence new

    --if equal(word, "char") then
	--trace(1)
    --end if
    -- negates global?
    if globalState = 2
    and find( word, { "constant", "for","function","procedure","type" } ) 
    then
	-- clear global flag
	globalState = 0
    elsif nextGoff then
	globalState = 0
	nextGoff = 0
    end if
    
    if addtype then
	types &= {word}
	addtype = 0
    end if
    
    if globalState = 2 and find(word, types) then
	globalState = 0
    end if

    -- ignore if builtin
    if find( word, builtin ) then
	if equal(word, "type") then
	    addtype = 1
	end if
	return word --commented out so local types can be redefined
    end if
    
    -- ignore if identifier
    if find( word, identifier ) then
	return word
    end if
    
    -- scoped to current procedure?
    -- scopes reversed so last redefinition will be used
    if procState = 2 then
	--at = find( word, reverse(oldProc) )
	at = find( word, oldProc )
	if at then     
	    return newProc[at]
	end if
    end if

    -- scoped to current module?
    -- scopes reversed so last redefinition will be used
    --at = find( word, reverse(oldLocal) )
    at = find( word, oldLocal )
    if at then
	return newLocal[at]
    end if

    -- scoped to globals?
    -- scopes reversed so last redefinition will be used
    --at = find( word, reverse(oldGlobal) )
    at = find( word, oldGlobal )
    if at then
	return newGlobal[at]
    end if

    -- not found; add to appropriate list    
    --if SHROUD_ON then
	--new = sprintf( "id_%d", {ids} )
    --else
	new = word
	if globalState = 0 then --never change a global name
	    --if find(new, all_ids) then
		new = sprintf( "%s%s", {curnames(), word} )
		names &= {word}
		word = new
	    --end if
	end if
    --end if
    if procState != 2 then --only add globals and locals, procs don't go in
	all_ids &= {new} --but proc names do.
	ids += 1
    end if

    if procState = 2 then
	-- defined in a proc
	oldProc = append( oldProc, word )
	newProc = append( newProc, new )
	
    elsif globalState then
	-- global declaration
	oldGlobal = append( oldGlobal, word )
	newGlobal = append( newGlobal, new )
	
    else
	-- local
	oldLocal = append( oldLocal, word )
	newLocal = append( newLocal, new )
	
    end if

    return new
    
end function

function checkn(sequence word)
    if find(word, names) then
	return 1
    end if
    return 0
end function

    
    integer at, char, i
    sequence out, word
    integer namewaiting, needtoreplace
    namewaiting = 0
    needtoreplace = 0
    
    out = {}
    at = 1

    while at <= length( s ) do        
    
	-- get a character
	char = s[at]      

	-- identifier
	if charClass[char] = LETTER then     
	
	    word = {}
	
	    -- read until end
	    while charClass[char] = LETTER
	    or    charClass[char] = DIGIT do
	
		-- add to word
		word = append( word, char )
		-- next letter
		at += 1       
		char = s[at]
	
	    end while       

	    -- routine flag
	    routineFlag = equal( word, "routine_id" )
	    needtoreplace = checkn(word)

	    if equal(word, "namespace") then
		if inname = 0 then --need to change to support multiple names
		    name = append(name, "")
		    namewaiting = 1
		    inname = 1
		else
		    inname = 0
		    names = ""
		    name = name[1..length(name)-1]
		end if
		out = "--" & out --comment out
	    elsif namewaiting then
		namewaiting = 0
		name[length(name)] = word
	    else
	    -- substitute?            
	    word = replaceWord( word )
	    end if

	    -- global flag
	    if equal( word, "global" ) then
		-- new occurance
		globalState = 1
		
	    elsif globalState = 1 then
		-- mark as used
		globalState = 2
	    end if

	    
	    -- manage proc state
	    if equal( word, "function" )
	    or equal( word, "procedure" )
	    or equal( word, "type" ) then
		if procState = 0 then
		    -- beginning of definition
		    procState = 1

		elsif procState = 2 then
		    -- end function/procedure
		    procState = 0
		    oldProc = {}
		    newProc = {}

		end if          
	    elsif procState = 1 then
		-- move state ahead
		procState = 2    
		globalState = 0
	    end if

	    -- substitute, if needed            
	    out = out & word

	-- number: handles hex as well
	elsif charClass[char] = DIGIT
	or    char = '#' then

	    word = {}
	    
	    -- read until end
	    while charClass[char] = DIGIT
	    or    charClass[char] = LETTER
	    or    char = '#' do
	    
		-- add to word
		word = append( word, char )
		-- next letter
		at += 1       
		char = s[at]
	
	    end while       

	    -- accumulated number            
	    out = out & word

	
	-- comment
	elsif char = '-'
	and   s[at+1] = '-' then
	    -- comment
	    out = out & s[at..length(s)]
	    -- move past end
	    at = length(s)+1
	
	-- character literal        
	elsif char = '\'' then
	    at += 1
	    if s[at] = '\\' then
		-- special
		at += 1
		word = "'\\" & s[at] & "'"
	    else          
		-- normal
		word = "'" & s[at] & "'"
	    end if       

	    -- move past quote            
	    at += 2

	    -- accumulate            
	    out = out & word

	-- quote                 
	elsif char = '"' then

	    word = {'"'}
	    while 1 do 
		-- move ahead
		at += 1
		-- special?
		if s[at] = '\\' then           
		    at += 1
		    --word = word & s[at-1] & s[at]
		    word = word & '\\' & s[at]
		    -- prevent reading as quote
		    s[at] = ' '
		else
		    word = word & s[at]
		end if

		-- end of quote?                
		if s[at] = '"' then
		    -- move ahead and exit
		    at += 1
		    exit
		end if
		
	    end while

	    -- handle routine_id
	    if routineFlag then
		needtoreplace = 1
	    end if
	    if needtoreplace then
		if routineFlag then
		    -- remove quotes
		    word = word[2..length(word)-1]
		end if
		if find(word, names) then
		    word = curnames() & names[find(word, names)]
		end if
		
		-- scoped to current procedure?
		i = 0
		if procState = 2 then
		    i = find( word, oldProc )
		    if i then
			word = newProc[i]
		    end if
		end if

		-- not found in procedure?
		if i = 0 then
		    -- scoped to current module?
		    i = find( word, oldLocal )
		    if i then
			word = newLocal[i]
		    end if
		end if

		-- not found procedure or module?
		if i = 0 then
		    -- scoped to current module?
		    i = find( word, oldGlobal )
		    if i then
			word = newGlobal[i]
		    end if
		end if
		
		if find(word, builtin) or find(word, identifier) then
		    i = 1
		    word = word --so routine_id("abort_") will work
		end if
		
		if i = 0 then
		    printf( 1, "Unable to resolve routine id for %s\n", {word} )
		    abort(0)
		end if
		
		-- re-apply quotes
		word = '"' & word & '"'
		
	    end if

	    -- accumulated
	    out = out & word
	    
	-- delimiter
	else        
	    out = out & char
	    at += 1
					  
	end if
	
    end while
    
    return out
    
end function



    -- if the statement is an include statement, return the file name
    integer at
    
    -- include statement missing?
    if not match( "include ", data ) then
	return ""
    end if

    -- trim white space
    while charClass[ data[1] ] = WHITE_SPACE do
	data = data[2..length( data ) ]
    end while      
    
    -- line feed?
    if find( '\n', data ) then
	data = data[1..length(data)-1]
    end if

    -- not first statement?
    if not equal( data[1..8], "include " ) then
	-- not an include statement
	return ""  
    else
	-- remove statement
	data = data[9..length(data)]
    end if

    -- remove data after space
    at = find( ' ', data )
    if at then
	data = data[1..at-1]
    end if

    return data

end function



    -- if statement is a with/without instruction, comment it out
    
    -- include statement missing?
    if match( "with ", data )
    or match( "without ", data ) then

	-- trim white space
	while charClass[ data[1] ] = WHITE_SPACE do
	    data = data[2..length( data ) ]
	end while      

	-- first statement?
	if length( data ) > 8 then      
	    if equal( data[1..5], "with " )
	    or equal( data[1..8], "without " ) then
	    
		-- comment out
		data =  "-- " & data
		
	    end if
	end if

    end if
	
    return data

end function

function trimer(sequence s)
    sequence t
    integer u
    if s[length(s)] = '\n' then
	s = s[1..length(s)-1]
    end if
    if s[length(s)] = '\r' then
	s = s[1..length(s)-1]
    end if
    t = reverse(s)
    u = find(slash, t)
    if not u then
	return s
    end if
    t = t[1..u-1]
    s = reverse(t)
    return s
end function

function includable(sequence name)
    --IGNORE=1 is table, IGNORE=2 is dir
    sequence s
    if IGNORE = 0 then
	return 1
    elsif IGNORE = 1 then
	if not find(name, ignore_table) then
	    return 1
	else
	    return 0
	end if
    elsif IGNORE = 2 then
	s = dir(ignore_dir)
	if atom(s) then
	    return 1
	end if
	s = s[3..length(s)] --skip '.' and '..'
	for i = 1 to length(s) do
	    s[i] = s[i][D_NAME]
	end for
	if not find(name, s) then
	    return 1
	else
	    return 0
	end if
    end if
    return 0 --unknown IGNORE option, so always ignore
end function


    integer inFile
    sequence newPrior, oldPrior, includeName
    object data

    -- find the file
    fName = findFile( fName )

    -- already part of the file?
    if find( fName, included ) then
	return
    else
	included = append( included, fName )
    end if  
    
    -- store locals and clear
    oldPrior = oldLocal
    newPrior = newLocal
    oldLocal = {}
    newLocal = {}

    -- write header                              
    --puts( outFile, "\n" )
    --puts( outFile, repeat( '-', 80 ) & "\n" )
    --puts( outFile, repeat( '-', 80 ) & "\n" )
    --printf( outFile, "-- INCLUDE FILE: %s\n", {fName} )
    --printf( outFile, "--file %s\n", {fName} )
    --puts( outFile, repeat( '-', 80 ) & "\n" )
    --puts( outFile, repeat( '-', 80 ) & "\n" )
    --puts( outFile, "\n" )
    
    inFile = open( fName, "r" )
    
    while 1 do        
    
	-- read a line
	data = gets( inFile )
    
	-- end of file?
	if integer( data ) then
	    exit
	end if

	-- include file?
	includeName = getIncludeName( data )
	--if match("file.e", includeName) then trace(1) end if
	--if length( includeName ) and includable(trimer(includeName)) then
	
	    -- include the file
	    --parseFile( includeName )
	    
	if length(includeName) then --no parse
	    puts( outFile, data )        
	
	elsif sequence(data) and length(data) >= 2 and
		equal(data[1..2], "#!") then --remove all #!
	    puts( outFile, "--"&data )        
	
	else
	
	    -- translate
	    data = parseLine( data )

	    -- remove with/without
	    data = removeWith( data )
	    
	    -- output
	    puts( outFile, data )        
	    
	end if
	
    end while
    
    close( inFile )
    --end of file header
    --puts( outFile, "\n" )
    --printf( outFile, "--end of file %s\n", {fName} )
    --puts( outFile, "\n" )

    -- restore locals
    oldLocal = oldPrior
    newLocal = newPrior

    
end procedure

procedure command_length(integer i, sequence s)
    if length(s) > i then
	printf(2, "\nError - too many parameters! - %s \n", {s[i+1]})
	abort(2)
    end if
end procedure

procedure get_options(sequence c)
    if equal(c[1], "--table") then
	command_length(5, command_line())
	IGNORE = 1
    elsif equal(c[1], "--dir") then
	command_length(6, command_line())
	IGNORE = 2
	if length(c) = 2 then
	    ignore_dir = c[2]
	end if
    else --simulate too many parameters
	command_length(4, command_line())
    end if
end procedure

		  
    sequence cmd, inFileName, outFileName

    -- read the command line
    cmd = command_line()

    -- get input file
    if length( cmd ) > 2 then
	inFileName = cmd[3]
    else
	inFileName = prompt_string( "File to concatonate? " )
	if length( inFileName ) = 0 then
	    abort(0)
	end if
    end if
		     
    -- get output file
    if length( cmd ) > 3 then
	outFileName = cmd[4]
    else
	outFileName = prompt_string( "File to create? " )
	if length( outFileName ) = 0 then
	    abort(0)
	end if
    end if

    --trace(1)
    if length(cmd) > 4 then
	get_options(cmd[5..length(cmd)])
    end if

    -- make sure they are different
    if equal( inFileName, outFileName ) then
	puts( 1, "File names must be different!\n" )
	abort(0)
    end if
		       
    -- open the file
    outFile = open( outFileName, "w" )
    puts(outFile, "--This file was created by namespace.ex\n")
    puts(outFile, "--by JBrown at jbrown105 at hotpop.com\n")
    puts(outFile, "--based on concat.ex, by David Cuny\n")

    -- process the input file
    parseFile( inFileName )
    
    -- close the output file
    close( outFile )
		       
end procedure


run()


--7JfCtLOvnd9MIVvH--

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

Search



Quick Links

User menu

Not signed in.

Misc Menu