|
|
| gen(src, tc, ts, te, sr) |
% FILE: gen.m
% PURPOSE: Sample x86 code generator for type double
% SIG: [char] = gen([char], [uint16], [uint16], [uint8]))
% CALL: asm = gen(src, ts, te, sr)
% asm is X86 assembly text
% src is the source input
% ts is the vector of token starts
% te is the vector of token ends (see lexer.m)
% sr is the shift/reduce sequence (see parser.m)
% Accepts source text, token markers and shift/reduce sequence
% Produces assembly level x86 code
% USAGE: See gen_test.m for example of use
function asm = gen(src, tc, ts, te, sr)
TOK = enum(tokens); % enumerations
RULE = enum(rules);
sri = uint16(1); % shift/reduce index
symi = uint16(0); % symbol stack index
syms = zeros(1,100,'uint16'); % some preallocation
lno = 0; % no lines yet
line = cell(1,00); % some preallocation
EOL = 10; % ASCII newline character
while(true)
switch sr(sri) % rule number
case RULE.shift
sri = sri+1; % move to token val
t = tc(sr(sri)); % token code
if t == TOK.id || t == TOK.int % significant?
symi = symi+1;
syms(symi) = sr(sri); % stack token
end
case RULE.program1 % quit
break;
case RULE.stmts1
case RULE.stmts2
case RULE.stmt1
case RULE.assign1 % x=exp;
v = syms(symi);
symi = symi-1;
appd([' fstp ' src(ts(v):te(v)) EOL]);
case RULE.var1
case RULE.expr1
case RULE.expr2 % a+b
appd([' fadd' EOL]);
case RULE.expr3 % a-b
appd([' fsub' EOL]);
case RULE.term1
case RULE.term2 % a*b
appd([' fmul' EOL]);
case RULE.term3 % a/b
appd([' fdiv' EOL]);
case RULE.term4 % a\b
appd([' fdivr' EOL]);
case RULE.factor1
case RULE.factor2 % abc
v = syms(symi);
symi = symi-1;
appd([' fld ' src(ts(v):te(v)) EOL]);
case RULE.factor3 % 123
v = syms(symi);
symi = symi-1;
appd([' fld =' src(ts(v):te(v)) EOL]);
otherwise
error('unknown rule');
end
sri = sri +1; % next shift/reduce
end
asm = ['ENTRY' EOL line{:}];
return;
% helper fcn
function appd(txt) % append to asm
lno = lno + 1;
line{lno} = txt;
end
end
|
|
Contact us at files@mathworks.com