Support Forums

Full Version: Well, this is difficult...
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Okay, so I have a problem.
I'm build a special kind of preprocessor. It'll look over a source file for specific keywords, and if it finds those keywords, insert strings based on those keywords (and everything else following that single line), and such.

Since this is almost impossible to explain without an example, I'll throw one at you.

Look at this source code:
Code:
struct Data
    string s = "Hello World" // poor example, but still.
endstruct

Will get compiled into this:
Code:
globals
    integer si__Data_F=0
    integer si__Data_I=0
    integer array si__Data_V
    string array s__Data_fx
endglobals

function s__Data__allocate takes nothing returns integer
local integer this=si__Data_F
    if (this!=0) then
        set si__Data_F=si__Data_V[this]
    else
        set si__Data_I=si__Data_I+1
        set this=si__Data_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: Data")
        return 0
    endif

    set si__Data_V[this]=-1
return this
endfunction

//Generated destructor of Data
function sc__Data_destroy takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: Data")
        return
    elseif (si__Data_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: Data")
        return
    endif
    set f__arg_this=this
    call TriggerEvaluate(st__Data_onDestroy)
    set si__Data_V[this]=si__Data_F
    set si__Data_F=this
endfunction

Things like the "globals" block will be merged with an already existing "globals" block (there is only one, at the start of the file).


My problem is finding out how to do all this (and much, much more).
But wait! That's not my only problem! My other problem is how to do it efficiently.

Speed of the preprocessor, and of the generated code (which is all me. I don't need help on that one. Tongue) is the main priority. If it's not fast, people aren't going to use it, which is bad.

So my questions are:

1. How can I look for specific keywords, and if I find them, output results into a file in specific blocks?
2. How can I optimize this so it can compile several thousand lines under 30 (preferably 20) seconds?
3. How can I do all this, and still get full cross compatibility over Mac, Linux, and Windows?

Thanks for any help.
3.)Well, if it is in Python anyone with python installed will be able to use it.

2.)The only way I can think of to optimize it is to do exactly what you need to do, and nothing more, KISS(keep it simple stupid).

1.)Do you have any knowledge of Python?
I have a beginners knowledge of Python, but I'm a very fast learner. I learnt the syntax in about an hour or two.
Sorry it took me so long to reply I havn't looked at my subscribed threads box in a while Omg. I can work on a script for you, is this what you want?:
text1.txt
Code:
globals
    integer si__Data_F=0
    integer si__Data_I=0
    integer array si__Data_V
    string array s__Data_fx
endglobals

function s__Data__allocate takes nothing returns integer
local integer this=si__Data_F
    if (this!=0) then
        set si__Data_F=si__Data_V[this]
    else
        set si__Data_I=si__Data_I+1
        set this=si__Data_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: Data")
        return 0
    endif

    set si__Data_V[this]=-1
return this
endfunction

//Generated destructor of Data
function sc__Data_destroy takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: Data")
        return
    elseif (si__Data_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: Data")
        return
    endif
    set f__arg_this=this
    call TriggerEvaluate(st__Data_onDestroy)
    set si__Data_V[this]=si__Data_F
    set si__Data_F=this
endfunction
text2.txt
Code:
globals
    integer si__Data_F=1
endglobals
text3.txt
Code:
function sc__Data_destroy takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: Data")
        return
    elseif (si__Data_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: Data")
        return
    endif
    set f__arg_this=this
    call TriggerEvaluate(st__Data_onDestroy)
    set si__Data_V[this]=si__Data_F
    set si__Data_F=this
endfunction
So that when text1 gets run against text2, it turns into this:
Code:
globals
    integer si__Data_F=1
    integer si__Data_F=0
    integer si__Data_I=0
    integer array si__Data_V
    string array s__Data_fx
endglobals

function s__Data__allocate takes nothing returns integer
local integer this=si__Data_F
    if (this!=0) then
        set si__Data_F=si__Data_V[this]
    else
        set si__Data_I=si__Data_I+1
        set this=si__Data_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: Data")
        return 0
    endif

    set si__Data_V[this]=-1
return this
endfunction

//Generated destructor of Data
function sc__Data_destroy takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: Data")
        return
    elseif (si__Data_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: Data")
        return
    endif
    set f__arg_this=this
    call TriggerEvaluate(st__Data_onDestroy)
    set si__Data_V[this]=si__Data_F
    set si__Data_F=this
endfunction
and then when 1 is run against 3, it automatically makes blocks like this:
Code:
globals
    integer si__Data_F=1
endglobals

function sc__Data_destroy takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: Data")
        return
    elseif (si__Data_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: Data")
        return
    endif
    set f__arg_this=this
    call TriggerEvaluate(st__Data_onDestroy)
    set si__Data_V[this]=si__Data_F
    set si__Data_F=this
endfunction
Is that right. In this example the keyword is globals