fir said:
W dniu niedziela, 26 maja 2013 19:27:27 UTC+2 u?ytkownik fir napisa?:
for example what does do this ->
pswitch() {
Generally, the compiler handles differently expressions and
all other constructs. First part of compiler is lexical
analyser, namely 'symbol()' function in c00.c -- this
function returns code of current symbol. Parsing mostly
uses recursive descent method, for example 'statement()'
function is responsible for parsing (and generating code!)
of a single (possibly compound statemnt). Expressions
are parsed using priority based parsed (the 'tree()'
function) building parse trees which are stored in a
temporary file for the second pass. The first pass
produces assembly code for most constructs. However,
for expressions instead of real code the '#' sign
is printed to assembly file (and tree is stored in the
temporary file). The 'pswitch' routine is responsible
for parsing and generating code for body of switch
expression. It is called after the 'switch (....)'
part has been handled. In particular code which
computes value to switch on is already generated.
First part of 'pswitch()' handles variables: info about
switch cases is stored in the global array 'swtab',
the 'swp' variable points to info abit current switch.
'deflab' variable stores label number of default
label of current switch, brklab stores label number
of label ending current switch. 'pswitch()' stores
info about (possible) surrounding switch in its
local variables, so that it can restore it at the
end -- that way switches can nest. Note 'pswitch()'
restores 'swp' and 'deflab' while 'brlab' is
restored by code calling 'pswitch()'. After
setting up variables 'pswitch()' generates code
to perform actual switch, using:
printf("jsr pc,bswitch; l%d\n", swlab);
^^^^
label
I know only little about PDP-11 assembly but this seem
to be call to a subroutine resposible for performing
actual switch action. When 'jsr' is executed
value to be switched on is in machine register.
Apparently the label after the 'jsr' instruction serves
as the second argument. More precisely, assembler is
supposed to replace label by corresponding address.
This addres points to table of pairs (constant, address)
were constants correspond to cases, while address is
addres of code for the case. After emmiting the
'jsr' instruction and setting variables 'pswitch()'
calls 'statement(0)' to parse swich body (which is
a single (usuallly compound) C statement). 'statement'
generates code for the body. When 'statement' meets 'case'
it generates (emits) a new label and puts (constant, label)
pair in place pointed by 'swp' and increments 'swp' to
point to free space. When 'statement' meets 'break' it
generates jump to 'brklab'. After 'statement' finished
its work 'pswitch()' first checks if it needs add
defalut label (if there is no explicit defaut case in
the switch the compiler must add a fake one). Then
it emits 'brklab' and then emits
table of data used by 'jsr'. The '.data' assembler
directive means that corresponding output will be
put in "data space" so that it is not mistaken as
instructions. After emmiting table of
switch data 'pswitch()' emits '.text' assembler
directive which means that after it there will be
code (assembly instructions). Then 'pswitch()'
restores variables and returns.