Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Constant Declarations
- const
- TAB = '\t'
- CR = '\r'
- #Variable Declarations
- var look: char #Lookahead Character
- #Read New Character From Input Stream
- proc getChar = look = stdin.readChar()
- #Report an Error
- proc error(s: string) = echo '\l', "Error: ", s, '.'
- #Report Error and Halt
- proc abort(s: string) =
- error s
- quit()
- #Report What Was Expected
- proc expected(s: string) = abort s & " Expected"
- #Recognize White Space
- proc isWhite(c: char): bool = c in [' ', TAB]
- #Skip Over Leading White Space
- proc skipWhite =
- while isWhite look: getChar()
- #Match a Specific Input Character
- proc match(x: char) =
- if look != x: expected '\"' & x & '\"'
- else:
- getChar()
- skipWhite()
- #Recognize an Alpha Character
- import strutils
- proc isAlpha(c: char): bool = (toUpper c) in 'A'..'Z'
- #Recognize a Decimal Digit
- proc isDigit(c: char): bool = c in '0'..'9'
- #Recognize an Addop
- proc isAddop(c: char): bool = c in ['+', '-']
- #Recognize an Alphanumeric
- proc isAlNum(c: char): bool = (isAlpha c) or (isDigit c)
- #Get an Identifier
- proc getName: string =
- if not isAlpha look: expected "Name"
- result = ""
- while isAlNum look:
- add result, (toUpper look)
- getChar()
- skipWhite()
- #Get a Number
- proc getNum: string =
- if not isDigit look: expected "Integer"
- result = ""
- while isDigit look:
- add result, look
- getChar()
- skipWhite()
- #Output a String with Tab
- proc emit(s: string) = echo TAB, s
- #Output a String with Tab and CRLF
- proc emitLn(s: string) =
- emit s
- echo ' '
- #Initialize
- proc init =
- getChar()
- skipWhite()
- #Parse and Translate an Identifier
- proc ident =
- let name = getName()
- if look == '(':
- match '('
- match ')'
- emitLn "BSR " & name
- else: emitLn "MOVE " & name & "(PC), D0"
- proc expression #Forward dec
- #Parse and Translate a Math Factor
- proc factor =
- if look == '(':
- match '('
- expression()
- match ')'
- elif isAlpha look: ident()
- else: emitLn "MOVE #" & getNum() & ", D0"
- #Recognize and Translate a Multiply
- proc multiply =
- match '*'
- factor()
- emitLn "MULS (SP)+, D0"
- #Recognize and Translate a Divide
- proc divide =
- match '/'
- factor()
- emitLn "MOVE (SP)+, D1"
- emitLn "DIV D1, D0"
- #Parse and Translate a Math Term
- proc term =
- factor()
- while look in ['*', '/']:
- emitLn "MOVE D0, -(SP)"
- case look
- of '*': multiply()
- of '/': divide()
- else: expected "Mulop"
- #Recognize and Translate an Add
- proc add =
- match '+'
- term()
- emitLn "ADD (SP)+, D0"
- #Recognize and Translate a Subtract
- proc subtract =
- match '-'
- term()
- emitLn "SUB (SP)+, D0"
- emitLn "NEG D0"
- #Parse and Translate an Expression
- proc expression =
- if isAddop look: emitLn "CLR D0"
- else: term()
- while isAddop look:
- emitLn "MOVE D0, -(SP)"
- case look:
- of '+': add()
- of '-': subtract()
- else: expected "Addop"
- #Parse and Translate an Assignment Statement
- proc assigment =
- let name = getName()
- match '='
- expression()
- emitLn "LEA " & name & "(PC), A0"
- emitLn "MOVE D0, (A0)"
- #Main Program
- init()
- assigment()
- if look != CR: expected "NewLine"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement