⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interpreter.inc

📁 This a basic compiler for MSP430
💻 INC
📖 第 1 页 / 共 5 页
字号:
x_print_20:
        cmp.b   #T_HEX, r4                   ; print value in hexadecimal?
        jnz     x_print_23                   ; ...no, continue to decode it
        call    #get_eval_expr               ; evaluate expression to print
        call    #print_hex                   ; print it in hex
        jmp     x_print_35                   ; deal with termimators
x_print_23:
        cmp.b   #T_BIN, r4                   ; print value in binary?
        jnz     x_print_25                   ; ...no, continue to decode it
        call    #get_eval_expr               ; evaluate expression to print
        call    #print_bin                   ; print it in binary
        jmp     x_print_35                   ; deal with termimators
x_print_25:
        cmp.b   #T_CLEAR, r4                 ; CLEAR?
        jnz     x_print_30                   ; ...no, continue to decode it
        mov.w   #0x0c, r15                   ; prepare to print form feed
        call    #print_char                  ; send it to the channel
        jmp     x_print_40                   ; deal with separators
x_print_30:
	call    #end_of_statement            ; end of line which terminates printing?
        jz      x_print_end                  ; ...yes, wrap up
        call    #eval_expr                   ; nothing matches, so parse it as an expression
        call    #print_integer               ; print it in decimal
x_print_35:
        sub.w   #1, tp                       ; back up token pointer for code ahead
x_print_40:
        mov.w   #1, r11                      ; prepare to hold CRLF
        mov.b   @tp+, r4                     ; prime R4 with next character
x_print_50:
        cmp.b   #';', r4                     ; expression separator?
        jz      x_print_01                   ; ...yes, continue with hold flag set
        cmp.b   #',', r4                     ; expression separator?
        jz      x_print_00                   ; ...yes, continue with hold flag set
        cmp.w   #0, r4                       ; end of line?
        jz      x_print_end_10               ; yes, terminate with a new line
        cmp.w   #':', r4                     ; end if statement?
        jz      x_print_end_10               ; yes, terminate with a new line
        jmp     syntax_error                 ; bad termination is reported as a syntax error

x_print_end:
        cmp.w   #0, r11                      ; hold CRLF?
        jnz     term                         ; ...yes, forget new line and continue with execution
x_print_end_10:
        mov.w   #'\n', r15                   ; print a new line
        call    #print_char
        jmp     term                         ; continue with processing

; Print the string delimited by a quotation mark.
; Shared between INPUT and PRINT.
print_quoted_string:
        mov.b   @tp+, r4                     ; get character in string
        cmp.b   #'"', r4                     ; terminated?
        jz      print_quoted_string_return   ; ...yes, deal with terminators
        cmp.b   #0, r4                       ; end of string?
        jz      mismatched_quote_error       ; ...yes, report error
        mov.w   r4, r15                      ; prepare character to print
        call    #print_char                  ; print it
        jmp     print_quoted_string          ; and get the next one
print_quoted_string_return:
        mov.b   @tp+, r4                     ; fetch token after final quotation mark
	ret

; BPUT [#channel, ] expr, expr, ...
x_bput:
        mov.w   #1, r15                      ; default to channel 1 if no channel number given
        call    #select_channel
        cmp.w   #'#', r4                     ; channel number being specified?
        jnz     x_bput_10                    ; ...no, so just use default
        call    #get_eval_expr               ; evaluate the channel number
        mov.w   r14, r15                     ; only use the low 16 bits of the channel number
        call    #select_channel              ; select the channel, error if it's bad
x_bput_00:
	call	#check_comma                 ; a comma must come next
x_bput_10:
	call	#eval_expr                   ; get the byte to put to the channel
	mov.w   r14, r15                     ; the byte is delivered in R14, so move to R15
	call	#print_char                  ; put the byte
	call	#end_of_statement            ; finished statement?
	jnz	x_bput_00                    ; ...no, need a comma and another expression
	jmp	term                         ; finish off statement

; BGET #channel
x_bget:
	cmp.b	#'#', r4                     ; require a channel number
	jnz	syntax_error                 ; ...but didn't get one
	mov.b   @tp+, r4                     ; skip '#'
	call    #eval_unary                  ; get the channel number
        mov.w   r14, r15                     ; only use the low 16 bits of the channel number
	call    #select_channel              ; select the channel
	call	#get_char                    ; read the character into R15
	mov.w	r15, r14                     ; zero-extend TOS
	mov.w   #0, r15
	ret

; RESET
x_reset:
        mov.w   #0, &WDTCTL                  ; bad password generates reset
        jmp     term                         ; ...but simulator doesn't

; MEMORY
x_memory:
        call    #memory
        jmp     term

memory:
        mov.w   sp, r14
        sub.w   &ramtop, r14
        mov.w   #0, r15
        call    #print_integer
        mov.w   #ram_message, r15
        call    #print_message
        mov.w   #0xfc00, r14
        sub.w   &flashtop, r14
        call    #print_integer
        mov.w   #flash_message, r15
        call    #print_message
        ret

; BREAK [ ON | OFF | expr ]
x_break:
        call    #eval_expr_on_off            ; Evaluate ON to -1, OFF to 0, and
        bic.w   #BREAK, &flags               ; Prepare for BREAK OFF
        bis.w   r14, r15
        cmp.w   #0, r15                      ; zero value means BREAK OFF
        jz      x_break_return
        bis.w   #BREAK, &flags               ; non-zero value turns on BREAK flag
x_break_return:
        jmp     term

; RESUME
x_resume:
        pop.w   r4                           ; get opened structure
        cmp.w   #T_RESUME, r4                ; RESUME expected from ON ... processing?
        jnz     cant_resume_error            ; ...no, can't RESUME
        pop.w   lp                           ; restore resume point
        pop.w   tp
        sub.w   #1, tp
        pop.w   sr                           ; restore interrupt enable status
        jmp     chrget                       ; continue with mainline code

; INTERRUPT ON
; INTERRUPT OFF
x_interrupt:
        cmp.b   #T_ON, r4
        jnz     x_interrupt_10
        eint
        mov.b   @tp+, r4
        jmp     term
x_interrupt_10:
        cmp.b   #T_OFF, r4
        jnz     syntax_error
        dint
        mov.b   @tp+, r4
        jmp     term

; Evaluate an expression with ON evaluating to -1 and OFF evaluating to 0
eval_expr_on_off:
        cmp.w   #T_ON, r4                    ; ON?
        jz      eval_expr_on_off_10          ; ...yes, return TRUE
        cmp.w   #T_OFF, r4                   ; OFF?
        jnz     eval_expr                    ; ...no, parse as an expression
        mov.b   @tp+, r4                     ; skip OFF token
        jmp     x_false                      ; return FALSE
eval_expr_on_off_10:
        mov.b   @tp+, r4                     ; skip ON token
        jmp     x_true                       ; return TRUE

; Get next token and evaluate expression
get_eval_expr:
        mov.b   @tp+, r4                     ; get next token

; Evaluate expression and return an integer in R15:R14
eval_expr:
        push.w  #T_PLUS-1                    ; least binding operator, lower precedence than any other

eval_expr_10:
	call    #eval_unary                  ; evaluate a unary expression

; Operator?
eval_expr_cont:
        cmp.w   #FIRST_BINARY_TOKEN, r4      ; if this isn't a binary operator, reduce whole stack and wrap up
        jnc     eval_expr_60
        cmp.w   #LAST_BINARY_TOKEN+1, r4
        jc      eval_expr_60

        mov.w   @sp, r13                     ; get stacked operator and compare precendence of this operator
        cmp.b   operator_precedence-FIRST_BINARY_TOKEN+1(r4), operator_precedence-FIRST_BINARY_TOKEN+1(r13)
        jc      eval_expr_60                 ; same or lower precedence, so reduce and keep parsing
        push.w  r15                          ; save TOS value on stack
        push.w  r14
        push.w  r4                           ; save current operator on stack
        mov.b   @tp+, r4                     ; get next character from the token stream
        jmp     eval_expr_10                 ; and it must start a unary expression

eval_expr_60:
        pop.w   r10                          ; get stacked operator
        cmp.w   #FIRST_BINARY_TOKEN-1, r10   ; if it's the lowest precedence (cf eval_expr), we're done.
        jz      eval_expr_return
        pop.w   r12                          ; pop saved TOS into NOS
        pop.w   r13
        add.w   r10, r10                     ; compute index into operator table
	                                     ; invoke operator routine
        call    binarytab-FIRST_BINARY_TOKEN*2(r10) 
        jmp     eval_expr_cont               ; continue with parsing expression
eval_expr_return:
        ret

get_eval_unary:
	mov.b   @tp+, r4                     ; get next token

eval_unary:
        tst.b   r4
        jge     eval_expr_20

; Token is negative, so it's an operator or function
        cmp.w   #T_BIT, r4                   ; BIT used as unary operator?
	jz      x_unary_bit                  ; ...yes, handle it specially
        cmp.w   #T_MINUS, r4                 ; - used as unary operator?
	jz      x_negate                     ; ...yes, handle it specially
        cmp.w   #T_PLUS, r4                  ; + used as unary operator?
	jz      get_eval_unary               ; ...yes, handle it specially

        cmp.w   #FIRST_UNARY_TOKEN, r4
        jnc     syntax_error
        cmp.w   #LAST_UNARY_TOKEN+1, r4
        jc      syntax_error
        add.w   r4, r4
        mov.w   r4, r13
        mov.b   @tp+, r4
        br      unarytab-FIRST_UNARY_TOKEN*2(r13)

eval_expr_20:
        cmp.b   #'(', r4
        jne     eval_expr_30
        call    #get_eval_expr
        cmp.b   #')', r4
        jne     mismatched_parenthesis_error
        mov.b   @tp+, r4
	ret

eval_expr_30:
        call    #is_digit
        jc      read_int

eval_expr_50:
	call    #varptr                      ; parse variable and get address into R14
	cmp.w   #4, r15                      ; address of a 32-bit value?
	jz      eval_expr_70                 ; ...yes, read 32-bit value
	cmp.w   #2, r15                      ; address of a 16-bit value?
	jz      eval_expr_80                 ; ...yes, read 16-bit value
	mov.b   @r14, r14                    ; ...no, read byte
	mov.w   #0, r15                      ; zero extend
	ret
eval_expr_70:
	mov.w   2(r14), r15                  ; fetch 32 bits
	mov.w   @r14, r14
	ret
eval_expr_80:
	mov.w   @r14, r14                    ; fetch 16 bits
	mov.w   #0, r15                      ; zero extend
	ret

; Read integer value into R15:R14 from the token stream.
read_int:
        mov.w   #0, r15
        mov.w   #0, r14
read_int_10:
        sub.w   #'0', r4
        call    #mul_10
        add.w   r4, r14
        addc.w  #0, r15
        mov.b   @tp+, r4
        call    #is_digit
        jc      read_int_10
        ret

; >
x_gt:
        sub.w   r12, r14
        subc.w  r13, r15
        jl      x_true
        jmp     x_false

; <
x_lt:
        sub.w   r14, r12                     ; compare operands, less?
        subc.w  r15, r13
        jl      x_true                       ; ...yes, return true else fall through

; FALSE
x_false:
        mov.w   #0, r15                      ; FALSE is zero
        mov.w   #0, r14
        ret

; =
x_eq:
        cmp.w   r14, r12                     ; same low parts?
        jnz     x_false                      ; ...no, must be different
        cmp.w   r15, r13                     ; same high parts?
        jnz     x_false                      ; ...no, return false else fall through

; TRUE
x_true:
        mov.w   #-1, r15                     ; true value is all bits set
        mov.w   #-1, r14
        ret

; <>
x_ne:
        cmp.w   r14, r12                     ; same low parts?
        jnz     x_true                       ; ...no, must be true
        cmp.w   r15, r13                     ; same high parts?
        jnz     x_true                       ; ...no, must be true
        jmp     x_false                      ; both parts are the same, so result is false

; a <= b = !(b > a)
x_le:
        sub.w   r12, r14
        subc.w  r13, r15
        jl      x_false
        jmp     x_true

; a >= b = !(b < a)
x_ge:
        sub.w   r14, r12
        subc.w  r15, r13
        jl      x_false
        jmp     x_true

; x BIT y
; If bit is not in 0..31, return 0.
x_bit:
        cmp.w   #0, r15
        jnz     x_false
        cmp.w   #0x20, r14
        jc      x_false

; If bit is within the high word, shift and adjust bit number.
        cmp.w   #16, r14
        jnc     x_bit_10
        mov.w   r13, r12

; Test bit and return value
x_bit_10:
        and.w   #0xf, r14                    ; now testing bits 0 through 15
        add.w   r14, r14

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -