Liste des Groupes | Revenir à cl c |
Bart <bc@freeuk.com> wrote:On 06/09/2024 11:19, Waldek Hebisch wrote:Bart <bc@freeuk.com> wrote:
I believe that C's compound literals can give a reference to a+1:(You can balance it out by by requiring ASSIGN(&A, &B)!)This would not work in general, as I wrote it, the following are
valid:
assign(&a, 42)
assign(&a, a + 1)
but the second argument has no address, so your variant would not
work.
You can use stack machines to get reasonably simple definition of(My stack IL is different. The stack is a compile-time stack only, and code is scanned linearly during code-generation. Roughly, the 'stack' corresponds to the machine's register-file, although in practice register allocation is ad-hoc.
semantics. But still slightly more complex than what I outlined
above. And code for stack machines is unpleasent to optimize.
In a compiler for a language where official semantics is stack
based the first things that compiler does is to track few items
on top of the stack and match them to sequences like
push a
push b
call op
Once sequence is matched it is replaced by corresonding operation
on variables. If this matching works well you get conventional
(non-stack) intermediate representaion and reasonably good code.
If matching fails, the resulting object code wastes time on stack
operations.
Of course, if you don not minds slowdowns due to stack use, thenI use a software stack for interpreted code.
stack machine leads to very simple implemantaion.
Best Forth compilersThen you no longer have a language which can be implemented in a few KB. You might as well use a real with with proper data types, and not have the stack exposed in the language. Forth code can be very cryptic because of that.
have sophisticated code to track stack use and replace it by
use of registers. Other Forth compilers just accept slowness.
But it's not prohibited by the grammar.Obviously, you can have RHS terms that cannot appear on the left, likeWell, logically you can not change value of a number, so you can
'42', but that's usually due to separate constraints of the language.
not assign to a number, that is very fundamental.
You could(Actually, 'x + 1 = y' is well defined in my languages. But that's because '=' means equality. The result is true/false.)
try to define
x + 1 = y
as solving equation for x, that quickly runs into trouble due to
equations which are no solutions or multiple solutions.
If you look typical generated code, then 'compute value' can often require discrete loads. But sometimes it is implicit:Why don't you need to compute the address of B?Well, B may have no address. In case when B is variable computing
its address is part of computation of its value. In general,
computing value of B need computing addresses of all variables
contained in B.
Why don't you need to"compute value" means putting result in place which is available
load the value of B?
to subsequent operations, so logically no extra load is needed.
And for variables "compute value" includes loading them.Suppose you had a 2-address machine with this instruction:
It is more like this:The point is that last part (that is store instruction) logically
>
compute address of B
load value of B via that address to some temporary location
compute address of A
store new value of A via that address
does not change when you vary A and B. Only this part corresponds to
assignment. The first to lines logically form a whole, that
is "compute B". And when you vary B you may get quite different split
of "compute B" into part. Moreover, logically "compute value of B"
and "compute address of A" are completely independent.
What started the subthread was the question of which HLL goes between ASM and C (since someone suggested that C was mid-level).(c ? a : b) = (c ? a : b);As noticed, people prefer symmetric notation, so most languages
make it "symmetric looking". But if you dig deeper there is
fundametal asymetry.
Les messages affichés proviennent d'usenet.