converting delphi to c/c++

Does anyone know of any little program or website etc that will show me how to convert delphi code to c/c++
many thanks

What you’re going to have to do is learn delphi, at least a little bit of it, then do the conversion from looking at the delphi code and writing the c/c++ equivalent. For the most part if you just look at the delphi code it’s not that hard to see what’s going on even if you don’t know delphi, like me. There are only a very few things I have come across looking at delphi and not knowing wtf it means, but most of the code should not be much of a problem to figure out.

-SirKnight

Crossposter alert

Originally posted by bramley1:
Does anyone know of any little program or website etc that will show me how to convert delphi code to c/c++

Why would anyone want to do that?!?

– Tom

Cos I found some nice delphi code, but i code in c/c++ - and i wanna try and work out how they did it and get it working in c/c++

(a) Delphi’s core language is similar to Pascal…

Searching for “learn delphi” on Google yields 232,000 links…

(b) This is an OPENGL forum (Sound out the word O-PEN-G-L). Now write 100 times…

Delphi/C++ questions do not go in the OPENGL forum.
Delphi/C++ questions do not go in the OPENGL forum.
Delphi/C++ questions do not go in the OPENGL forum.

well the code does relate to opengl - so yes it is relevant

If you post the code that you do not understand, there are a bunch Delphi people on this board that can help you out.

Originally posted by bramley1:
well the code does relate to opengl - so yes it is relevant

You’re kidding right…

You’re post didn’t even contain the word OpenGL - let alone have ANYTHING to do with OpenGL.

By your logic if I post “Hey everyone, I can’t seem to get VC++ running” it must be an OpenGL post because I intend to use it to write some Opengl code.

Hi

perhaps you can use delphi to put the code into a dll library and call that from C++ ?

Bye
ScottManDeath

Like jra101 said, post a bit of code, or a link if it’s a lot and we can help you out. Like I said I don’t really know delphi all that well but I know a few little things and I can figure out what’s going on just by looking at it, reguardless if I know the language or not.

-SirKnight

I can figure out what’s going on just by looking at it, reguardless if I know the language or not.

heh, alright. Here’s a challenge. I wrote this code to solve a problem my lecturer posed. The code is in a real language (but I won’t say what:-), it does execute (its a script, so I can’t say it “compiles”) and it does what I intended it to do. All I’ve done is removed the comments; all YOU have to do is work out what it does in a vague kind of way.

> mkTransactionList :: num->[num]->[(num,bool,[num])]
> mkTransactionList x ys
>    = (x, True, []) [img]http://www.opengl.org/discussion_boards/ubb/frown.gif[/img]map (convertToNode) ys)
>      where convertToNode amt = (amt, False, []),    if amt>0
>                              = (0,   False, [amt]), otherwise

> process :: (num,bool,[num])->(num,bool,[num])->(num,bool,[num])
> process (lBal, lDef, lLst) (rBal, rDef, rLst)
>   = processTransactions currBal currLst, if lDef \/ rDef = True
>   = queueTransactions currBal currLst,   otherwise
>     where currBal = (lBal+rBal), if lLst=[]
>                   = lBal,        otherwise
>           currLst = rLst,               if lLst=[]
>                   = lLst++[rBal]++rLst, otherwise

> processTransactions :: num->[num]->(num,bool,[num])
> processTransactions bal []
>  = (bal, True, [])
> processTransactions bal (x:xs)
>   = processTransactions (bal+x) xs, if bal+x >= 0
>   = processTransactions bal xs,     otherwise

> queueTransactions :: num->[num]->(num,bool,[num])
> queueTransactions bal []
>   = (bal, False, [])
> queueTransactions bal (x:xs)
>   = queueTransactions (bal+x) xs, if bal+x >= 0
>   = (bal, False, x:xs),           otherwise

> distribute :: [(num,bool,[num])]->(num,bool,[num])
> distribute xs
>   = process (leftHalf) (rightHalf), if #xs>1
>   = hd xs,                          otherwise                
>     where leftHalf = distribute (take half xs)
>           rightHalf = distribute (drop half xs)
>           half = #xs div 2

> extractBalance :: (num,bool,[num])->num
> extractBalance (bal,def,lst)
>   = error "internal conflict",       if def=False
>   = error "unresolved transactions", if lst~=[]
>   = bal,                             otherwise

enjoy

That’s one SCAAARY language…

Looks to me like you give “Distribute” a list of balances/transactions, which it consolidates into a single balance…

Probably for combining accounts or calculating a total balance across accounts? Given all items in the lists [] have their own balances and transaction lists.

What language is it? Has the developer been shot?

[This message has been edited by rgpc (edited 01-21-2003).]

OMG, that’s some scary s**t!. Now when I said that I meant delphi, not every other language out there but I’ll look through it and see what I come up with. But I mean for the most part, if one knows C or C++ quite well then looking at other languages and figuring out what’s going on isn’t all that bad usually. That’s if the language isn’t real nasty looking like the code you provided. I wasn’t trying to say I’m some kind of programming god that can understand all with out trying, even though I probably made it sound that way. But for the most part, knowing one language well can help you understand what’s going on in a another language even if you don’t really know that language. That’s all I meant by that if I confused any.

-SirKnight

I must say, that is one of the most ugly programming languages I have ever seen. Most of it to me doesn’t make sence why it’s done in the way it is. The syntax is just like…wow. I can see that it’s doing somekind of banking thing with transactions, balances, swaping them around if certain conditions happen, etc. I bet I could come up with a bit more if I went through each character almost and studied it but since I know I would have to do that, that tells me this language was poorly designed and I hope is dead. I’m so sorry you had to learn it. May God be with you! lol

Oh also, if you did not use meaningful identifiers , I don’t think I could have even come up with what I did.

-SirKnight

It’s Haskell, isn’t it?
If so, this is the FIRST language that is taught to computer science students here at Oxford. It is also the only computing-related course I can take as part of my maths degree, so I am currently studying it.

Quite why they decide to start students off on this is anyone’s guess. Mind you, after that, they teach “procedural programming” using something equally obscure called “Oberon”. Needless to say, I am moving next year to take my Computer Science masters.

Good to see Oxford are teaching languages that are widely used within the IT industry. I thought it was crap when I found that most of my second year was spent doing Cobol (& that was in 1993).

Not only does it seem to be somewhat obscure but it’s also completely a*#? about with its syntax. Instead of “do a; if b then c” its “c if b after doing a”.

I wonder if it’s creator was dyslexic?

(A link on the “applications written in Haskell” page on the site below appears to support this - VOP - Vision of Persistence)

From the “www.haskell.org” home page…

Haskell is a general purpose, purely functional programming language. Haskell compilers are freely available for almost any computer

Is “purely functional” the opposite of “completely practical” or “very useful”?

Howdy,

no, I’m not dyslexic; that’s the coding style. It’s a programming language called ‘Miranda’. It’s a Functional programming language. “Functional” is a paradigm, not “it does stuff” :slight_smile: C and Pascal are Imperative languages; C++ is object-orientated imperative; and Prolog is Logical. They are all different ways of describing a program and they all have different uses. For example, suppose you wanted to fill an array with zero. You’d do something like this in C, right?

for(int i=0; i<1000; i++)
array[i]=0;

ok, maybe you’d do something like memset(array, 1000, 0) or something, but the point is that the language is forcing the programmer into explicitly defining control. That is, implicit in the above code is the understanding that array[i] will ALWAYS be initialised before array[i+1], right? That might not sound so bad on a uniprocessor machine with the kind of linear memory addressing you’re used to, but what if you were coding for a 1000 processor machine? Instead of getting one processor to set some memory to zero and increment some counter, the 1000 processor machine could say to each processor “have some bit of memory and set your bit to zero”. Each processor could get this instruction off a instruction broadcast and set its bit of memory to zero in parallel. The idea of functional languages is to describe a program WITHOUT constraining its execution flow with artificial constraints (like “you have to set array[0] before array[1]”, which is clearly a non-sensical constraint for a multiprocessor machine).

Incidentially, that for() loop would look like

map fn array where fn x = 0

map takes a vector and applies the function “fn” to every element of that vector. The underlying machine is free to choose how that function is mapped; on a uniprocessor machine with linear memory, it may very well unroll to the for() loop above.

The language is like maths in a lot of respects. For example, functions are not allowed to have side-effects: they can only take in input and return some output. There is no such thing as global variables in Miranda because this would make it impossible to arbitarly schedule execution. For example, what if ‘fn’ modified some global variable and based its execution on the state of the variable? The program’s behaviour would then depend on what order fn was called with respect to the vector.

Miranda is a funky language. It seriously screws with your head when you’re so used to programming in imperative languages, but it IS very cool when you’re in the zone and can write essentially pipelined programs :slight_smile:

Some explanation of the syntax:

> mkTransactionList :: num->[num]->[(num,bool,[num])]
> mkTransactionList x ys
>    = (x, True, []) [img]http://www.opengl.org/discussion_boards/ubb/frown.gif[/img]map (convertToNode) ys)
>      where convertToNode amt = (amt, False, []),    if amt>0
>                              = (0,   False, [amt]), otherwise

this just declares a function called mkTransactionList. the :: num->[num]->[(num,bool,[num])] is its prototype: it just means its a function that takes in a number and a list of numbers ( meaning list) and it returns a ‘tuple’ or structure which has a number, a boolean and a list of numbers.
The body of this function is just
= (x, True, ) map (convertToNode) ys)

this makes a list of num/bool/list structures. the ‘:’ is a list concatenation operator; it munges an element of the list (x, True, ) with the result of mapping the function convertToNode applied over the vector ys. ‘x’ and ‘ys’ are parameters passed to the function; convertToNode is a locally defined function. It looks like

>convertToNode amt = (amt, False, []),    if amt>0
>                              = (0,   False, [amt]), otherwise

You should be able to see how that works; the way Miranda writes its IF statements looks backwards to C:
=result1, if condition
=result2, if someothercondition
=result3, otherwise

All this function does is take a list of numbers and turns them into a list of structures. Miranda isn’t really all that complicated; the trick is to THINK in the functional language paradigm. This means you haev to realise that you code in a pipeline, and that later stages of the pipeline may kick in before the first stage has finished becaause its demand-driven. For example, this function returns a structure and a list of structures; but if the function that takes this list as input MAY work on the first structure before the function mkTransactionList has finished making the rest of the list because its a pipeline with no side-effects :slight_smile:

Anyway. What that program does is it takes a list of transactions on a bank account and works out the final balance. Not hard, right? But the trick is: you can’t withdraw more money than you haev in the account, and the trick of the assignment was to parallelise the code as much as problem. The problem is you can’t look at some random trasaction and process it because you don’t know the history. The problem with computing the history is that you’re making the problem sequential :slight_smile:

What it does is spread the list of transactions over the processors and get processors to collapse neighbouring transactions together (ie. exchanging info) and solving withdrawls if its temporary balance allows it, but queue pending withdrawls if the temporary balance doesn’t have enough money. This is the full code with comments:

> &#0124; &#0124; This is a literate script

Parallel Banker's algorithm
coded by John Bastian

//// BEGIN TESTS ////

Should note that this algo includes a starting balance (which is the
first digit, dentoted 'b')

The first test should be unable to complete the second transaction (withdraw
$10), but complete the others

   Transactions: B50 w45 w10  d30 d70 w40 w5 w50
        Success: OK  OK  FAIL OK  OK  OK  OK OK
Running Balance: 50  5   5    35  105 65  60 10

> testBank1
>   = extractBalance (distribute (50 $mkTransactionList [-45, -10, 30, 70, -40, 
-5, -50]))

B100 w150 d50 w100 w25 d100 w150 w25 d500 w550 d100 w50
OK   FAIL OK  OK   OK  OK   FAIL OK  OK   OK   OK   OK
100  100  150 50   25  125  125  100 600  50   150  100

> testBank2
>   = extractBalance (distribute (mkTransactionList 100 [-150, 50, -100, -25, 
100, -150, -25, 500, -550, 100, -50]))

Trace writes, or “an explanation on how this is parallel”

The idea of this algorithm is to reduce the balance when it knows it can,
but queue pending transactions when it doesn’t know if they are allowed.
For example, if the user deposits $100 and then withdraws $50, then the
withdrawl will succeed irrespective of the history prior to the transaction;
The net result for this pair is a deposit of $50.
However, suppose two transactions are d10 w20. The system isn’t yet sure
whether this will work, so it needs to queue the transactions. It can’t
even say that the net result is -10 (10-20), since it doesn’t know if the
w20 will succeed. However, suppose a transaction before this pair was
a deposit of 100; then the system will know it can transfer a partial list
of transactions into the balance, and start withdrawing. For instance, the
d10 will succeed and give 110 “plus a bit” in the balance, and then withdraw
20 from this 110. The “plus a bit” indicates that the system doesn’t yet
know the true balance. This is the purpose of the middle field of the
tupple: it indicates if the system knows for sure that the balance it
carries is the real balance.
Knowing for sure has a different effect on processing transactions. If the
system does know the balance in the tuple is the real thing, then it will
delete (== invalidate) any transactions that fail, since there is no way
prior transactions will make the transaction possible: there is no history
for definate balances. However, if the system doesn’t know, then it must
queue the transactions.

Consider a trace write of the first test which demonstrates the parallel
stuff. The mkTransactionList func converts all the transactions into nodes,
or tupples. The distribute func sets up the process tree, and the process
func is the magic.

The first line of the following diagram are the raw transactions; the second
line is the conversion performed by mkTransactionList
The only node which is sure about the balance is the balance node (hence
the ‘t’); the rest are unsure, so they get a ‘f’. The deposit nodes know the
balance is at least what was deposited, so their ‘sub balance’ is the value
of the transaction (the first field of the tupple). The withdrawl nodes fear
the worst: they think the balance is 0, and so have to put the withdrawl on
the pending transaction queue (the last field of the tupple)

Consider the first node of the second line. It takes in the two previous
nodes, and sees that the balance is DEFINATELY 50. The withdrawl will succeed
and so the balance becomes 5. Since this is derived from a definate balance,
this new node’s balance is also definate.

Consider the second node of the second line. It can’t do anything with
the w10, since it doesn’t know if there are enough funds. So it has to
keep the w10 in the queue. When it munges the deposit, it sees there are
pending transactions in the history (the history is everything to the left),
and so it is also forced to queue the deposit.

The third node, however, knows the balance is at least 70; thus the withdraw
of 40 will succeed, regardless of the history. Since there are no pending
transactions on the left node, it can withdraw from the sub-balance, leaving
$30.

The fourth node is just like the second node; the transactions must be
queued.

Ok, the third line. The algo knows the balance is 5, so it looks at the
widthdrawl of $10 from the right node, and realises there is no way it
can be accepted, so it’s deleted. The deposit of $30 can now proceed,
so the balance definately becomes $35.

The second node on the third line is similar. The “working balance”
is the sum of the sub-balances on both nodes, since there are no pending
transactions on the left. The w5 can succeed from the sub-balance, but
the w50 is blocked (and thus queued)

The final node is the result, since the w50 can now succeed. yay!

b50 w45 w10 d30 d70 w40 w5 w50

(50|t| (0|f|-45) (0|f|-10) (30|f| (70|f| (0|f|-40) (0|f|-5) (0|f|-50)
\ / \ / \ / \ /
(5|t| (0|f|-10:30) (30|f| (0|f|-5:-50)
\ / \ /
(35|t| (25|f|-50)
\ /
(10|t|

//// END TESTS ////

mkTransactionList :: num->[num]->[(num,bool,[num])]
mkTransactionList x ys
= (x, True, ) map (convertToNode) ys)
where convertToNode amt = (amt, False, ), if amt>0
= (0, False, [amt]), otherwise

process :: (num,bool,[num])->(num,bool,[num])->(num,bool,[num])
process (lBal, lDef, lLst) (rBal, rDef, rLst)
= processTransactions currBal currLst, if lDef / rDef = True
= queueTransactions currBal currLst, otherwise
where currBal = (lBal+rBal), if lLst=
= lBal, otherwise
currLst = rLst, if lLst=
= lLst++[rBal]++rLst, otherwise

processTransactions :: num->[num]->(num,bool,[num])
processTransactions bal
= (bal, True, )
processTransactions bal (x:xs)
= processTransactions (bal+x) xs, if bal+x >= 0
= processTransactions bal xs, otherwise

queueTransactions :: num->[num]->(num,bool,[num])
queueTransactions bal
= (bal, False, )
queueTransactions bal (x:xs)
= queueTransactions (bal+x) xs, if bal+x >= 0
= (bal, False, x:xs), otherwise

distribute :: [(num,bool,[num])]->(num,bool,[num])
distribute xs
= process (leftHalf) (rightHalf), if #xs>1
= hd xs, otherwise
where leftHalf = distribute (take half xs)
rightHalf = distribute (drop half xs)
half = #xs div 2

extractBalance :: (num,bool,[num])->num
extractBalance (bal,def,lst)
= error “internal conflict”, if def=False
= error “unresolved transactions”, if lst~=
= bal, otherwise

[This message has been edited by john (edited 01-21-2003).]

Haskell totally rulez, altough it’s syntax can be abused just as bad as in any other language. Normally, programs are 5-10 times shorter than C++/Java though and development time matches that.

My thesis project (currently in the middle of it) is a Particle system compiler written in Haskell. It compiles from an embedded neat language down to C++ and ARB_VP, then you can use it in your engine or just have it as a standalone glutapp/screensaver.

EDIT: But that looks like a very obsucre way to write if’s. From my compiler, a function that returns the number of times a variable occurs in an expression (syntax tree):

varOccurs v = f e
where f e | isVar e && v == v’ = 1
f (A _ es) = sum $ map f es
f _ = 0

[This message has been edited by macke (edited 01-22-2003).]

John, face the front and get on with your work!