image thumbnail
from toy compiler by Bill McKeeman
A toy compiler

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