Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- let s:look = ''
- let s:input = ''
- let s:output = ''
- let s:pos = 0
- function! GetChar()
- let s:look = strpart(s:input, s:pos, 1)
- let s:pos += 1
- endfunction
- function! Error(msg)
- echoerr "Error: " . a:msg . "."
- endfunction
- function! Abort(msg)
- call Error(a:msg)
- " Halt let s:running = 0
- endfunction
- function! Expected(msg)
- call Abort(a:msg . ' Expected')
- endfunction
- function! Match(c)
- if s:look == a:c
- call GetChar()
- else
- call Expected("'" . x . "'")
- endif
- endfunction
- function! IsAddop(c)
- return index(['+', '-'], a:c) != -1
- endfunction
- function! IsAlpha(c)
- return match(a:c, '\C[A-Z]') != -1
- endfunction
- function! IsDigit(c)
- return match(a:c, '[0-9]') != -1
- endfunction
- function! GetName()
- if !IsAlpha(s:look)
- call Expected('Name')
- endif
- let retval = toupper(s:look)
- call GetChar()
- return retval
- endfunction
- function! GetNum()
- if !IsDigit(s:look)
- call Expected('Integer')
- endif
- let retval = s:look
- call GetChar()
- return retval
- endfunction
- function! Emit(code)
- let s:output .= a:code
- endfunction
- function! EmitLn(code)
- call Emit(a:code)
- let s:output .= "\r"
- endfunction
- function! Init(input)
- let s:look = ''
- let s:input = a:input
- let s:output = ''
- let s:pos = 0
- call GetChar()
- endfunction
- function! Ident()
- let name = GetName()
- if s:look == '('
- call Match('(')
- call Match(')')
- call EmitLn('BSR ' . name)
- else
- call EmitLn('MOVE ' . name . '(PC),D0')
- endif
- endfunction
- function! Factor()
- if s:look == '('
- call Match('(')
- call Expression()
- call Match(')')
- elseif IsAlpha(s:look)
- call Ident()
- else
- call EmitLn('MOVE #' . GetNum() . ',D0')
- endif
- endfunction
- function! Multiply()
- call Match('*')
- call Factor()
- call EmitLn('MULS (SP)+,D0')
- endfunction
- function! Divide()
- call Match('/')
- call Factor()
- call EmitLn('MOVE (SP)+,D1')
- call EmitLn('DIVS D1,D0')
- endfunction
- function! Term()
- call Factor()
- while index(['*', '/'], s:look) != -1
- call EmitLn('MOVE D0,-(SP)')
- if s:look == '*'
- call Multiply()
- elseif s:look == '/'
- call Divide()
- endif
- endwhile
- endfunction
- function! Add()
- call Match('+')
- call Term()
- call EmitLn('ADD (SP)+,D0')
- endfunction
- function! Subtract()
- call Match('-')
- call Term()
- call EmitLn('SUB (SP)+,D0')
- call EmitLn('NEG D0')
- endfunction
- function! Expression()
- if IsAddop(s:look)
- call EmitLn('CLR D0')
- else
- call Term()
- while IsAddop(s:look)
- call EmitLn('MOVE D0,-(SP)')
- if s:look == '+'
- call Add()
- elseif s:look == '-'
- call Subtract()
- endif
- endwhile
- endif
- endfunction
- function! Assignment()
- let name = GetName()
- call Match('=')
- call Expression()
- call EmitLn('LEA ' . name . '(PC),A0')
- call EmitLn('MOVE D0,(A0)')
- endfunction
- function! Parse(input)
- call Init(a:input)
- call Expression()
- if s:look != "\n"
- call Expected('Newline')
- else
- echomsg s:output
- endif
- endfunction
- call Parse("(1+2)/9\n")
Advertisement
Add Comment
Please, Sign In to add comment