User:FireFly/argh.mrc

From Esolang
Jump to navigation Jump to search

A half-complete Argh! interpreter written in mIRC scripting (old).

execargh {
  set %arghTimeout $calc( $ctime + 5)
  if (!$1-) {
    echo $chan Error: You must specify a file to be parsed.
  }
  set %i 0
  while (%i < 40) {
    set %arghSource_ [ $+ [ %i ] ] $read($1, $calc(%i + 1))
    inc %i
  }
  ; set default variables, unset Flow var!
  set %arghX 0
  set %arghY 0
  unset %arghFlow
  set %arghOut $null
  set %arghStack $null
  ; Check if file begins with a flow instruction.
  if ($countcs(%arghVartypeFlow,$mid(%arghSource_0,1,1)) == 0) {
    echo $chan Error: File did not begin with a flow control instruction. (File begun with $mid(%arghSource_0,1,1) $+ )
    goto End
  }

  :CheckInstruction
  if ($ctime > %arghTimeout) {
    goto ErrOverflow
  }
  if (%charX < 0 || %charY < 0 || %charX > 80) {
    echo $chan Error: Could not read cell, pointer out of bounds.
    goto End
  }
  set %arghCurr $mid(%arghSource_ [ $+ [ %arghY ] ] ,%arghX,1)
  if (%arghCurr islower) {
    ; LOWERCASE INSTRUCTIONS
    ; Flow control
    if (%arghCurr == h) {
      ; Set flow to left.
      set %arghFlow 1
    }
    if (%arghCurr == j) {
      ; Set flow to down.
      set %arghFlow 3
    }
    if (%arghCurr == k) {
      ; Set flow to up.
      set %arghFlow 0
    }
    if (%arghCurr == l) {
      ; Set flow to right.
      set %arghFlow 2
    }
    if (%arghCurr == x) {
      ; if the value on top of the stack is positive, turn
      ; the execution direction 90 degrees to the right.
      if ($right(%arghStack,1) > 0) {
        if (%arghFlow == 0) {
          set %arghFlow 2
        }
        elseif (%arghFlow == 1) {
          set %arghFlow 0
        }
        elseif (%arghFlow == 2) {
          set %arghFlow 3
        }
        else {
          set %arghFlow 1
        }
      }
    }
    if (%arghCurr == q) {
      ; End program execution.
      goto End
    }
    ; Stack control
    if (%arghCurr == s) {
      ; Store (push) value of cell below to top of stack.
      set %arghStack %arghStack $+ $mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1)
    }
    if (%arghCurr == d) {
      ; Duplicate to value on top of stack.
      set -u0 %arghTmp $right(%arghStack,1)
      set %arghStack %arghStack $+ %arghTmp
    }
    if (%arghCurr == a) {
      ; Add value of the cell below to value on top of stack.
      set %arghTmp $mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1)
      ; $chr($calc($asc($right(%arghStack,1)) + $asc(%arghTmp)))
      ; set -u0 %arghTmp2 $calc( %arghTemp + $asc($mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1)))
      set %arghStack $right(%arghStack,-1) $+ $chr($calc($asc($right(%arghStack,1)) + $asc(%arghTmp)))
    }
    if (%arghCurr == r) {
      ; Reduce the value on top of stack with the value of below cell.
      set %arghTmp $mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1)
      ; $chr($calc($asc($right(%arghStack,1)) - $asc(%arghTmp)))
      ; set -u0 %arghTmp2 $calc( %arghTemp + $asc($mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1)))
      set %arghStack $right(%arghStack,-1) $+ $chr($calc($asc($right(%arghStack,1)) - $asc(%arghTmp)))
    }
    if (%arghCurr == f) {
      ; Fetch (pop) value from top of stack and store in cell below.
      set %arghSource_ [ $+ [ $calc( %arghY + 1) ] ] $left(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] , $calc( %arghX - 1)) $+ $right(%arghStack,1) $+ $right(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] , $calc( %arghX - 2 * %arghX ))
      set %arghStack $left(%arghStack,-1)
    }
    ; I/O
    if (%arghCurr == p) {
      ; Print character from the cell below.
      set %arghOut %arghOut $+ $mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1)
      if ($mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1) == $chr(10)) {
        ; Trying to print newline, echo & reset output var.
        echo $chan %arghOut
        set %arghOut $null
      }
    }
    if (%arghCurr == g) {
      ; Get one byte from stdin and store in cell below.
    }
    if (%arghCurr == e) {
      ; Insert value of system EOF in cell below.
    }
  }
  elseif (%arghCurr isupper) {
    ; UPPERCASE INSTRUCTIONS
    ; Flow control
    if (%arghCurr == H) {
      ; Set flow to left, jump left to the next char whose value matches the value of top of stack.
      set %arghFlow 1
    }
    if (%arghCurr == J) {
      ; Set flow to down, jump down to the next char whose value matches the value of top of stack.
      set %arghFlow 3
    }
    if (%arghCurr == K) {
      ; Set flow to up, jump up to the next char whose value matches the value of top of stack.
      set %arghFlow 0
    }
    if (%arghCurr == L) {
      ; Set flow to right, jump right to the next char whose value matches the value of top of stack.
      set %arghFlow 2
    }
    if (%arghCurr == X) {
      ; if the value on top of the stack is negative, turn
      ; the execution direction 90 degrees to the left.
    }
    ; Stack control
    if (%arghCurr == S) {
      ; Store (push) value of cell above to top of stack.
      set %arghStack %arghStack $+ $mid(%arghSource_ [ $+ [ $calc( %arghY - 1) ] ] ,%arghX,1)
    }
    if (%arghCurr == D) {
      ; Delete value on top of stack.
      set %arghStack $left(%arghStack,-1)
    }
    if (%arghCurr == A) {
      ; Add value of the cell above to value on top of stack.
      set %arghTmp $mid(%arghSource_ [ $+ [ $calc( %arghY - 1) ] ] ,%arghX,1)
      ; $chr($calc($asc($right(%arghStack,1)) + $asc(%arghTmp)))
      ; set -u0 %arghTmp2 $calc( %arghTemp + $asc($mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1)))
      set %arghStack $right(%arghStack,-1) $+ $chr($calc($asc($right(%arghStack,1)) + $asc(%arghTmp)))
    }
    if (%arghCurr == R) {
      ; Reduce the value on top of stack with the value of above cell.
      set %arghTmp $mid(%arghSource_ [ $+ [ $calc( %arghY - 1) ] ] ,%arghX,1)
      ; $chr($calc($asc($right(%arghStack,1)) - $asc(%arghTmp)))
      ; set -u0 %arghTmp2 $calc( %arghTemp + $asc($mid(%arghSource_ [ $+ [ $calc( %arghY + 1) ] ] ,%arghX,1)))
      set %arghStack $right(%arghStack,-1) $+ $chr($calc($asc($right(%arghStack,1)) - $asc(%arghTmp)))
    }
    if (%arghCurr == F) {
      ; Fetch (pop) value from top of stack and store in cell above.
      set %arghSource_ [ $+ [ $calc( %arghY - 1) ] ] $left(%arghSource_ [ $+ [ $calc( %arghY - 1) ] ] , $calc( %arghX - 1)) $+ $right(%arghStack,1) $+ $right(%arghSource_ [ $+ [ $calc( %arghY - 1) ] ] , $calc( %arghX - 2 * %arghX ))
      set %arghStack $left(%arghStack,-1)
    }
    ; I/O
    if (%arghCurr == P) {
      ; Print character from the cell above.
      set %arghOut %arghOut $+ $mid(%arghSource_ [ $+ [ $calc( %arghY - 1) ] ] ,%arghX,1)
      if ($mid(%arghSource_ [ $+ [ $calc( %arghY - 1) ] ] ,%arghX,1) == $chr(10)) {
        ; Trying to print newline; echo & reset output var.
        echo $chan $replace(%arghOut,$chr(32),$chr(160))
        echo $chan �Debug:� Stack containts: %arghStack
        set %arghOut $null
      }
    }
    if (%arghCurr == g) {
      ; Get one byte from stdin and store in cell above.
    }
    if (%arghCurr == e) {
      ; Insert value of system EOF in cell above.
    }
  }

  :ReadNextChar
  if (%arghFlow = 0) {
    ; Flow is going up
    set %arghY $calc( %arghY - 1)
  }
  if (%arghFlow = 1) {
    ; Flow is going left
    set %arghX $calc( %arghX - 1)
  }
  if (%arghFlow = 2) {
    ; Flow is going right
    set %arghX $calc( %arghX + 1)
  }
  if (%arghFlow = 3) {
    ; Flow is going down
    set %arghY $calc( %arghY + 1)
  }
  ; echo $chan [Debug] Reading line: %arghY $+ , col: %arghX
  goto CheckInstruction


  if (1 == 2) {
    :End
    echo $chan Program has ended.
    /return
    :ErrOverflow
    echo $chan Error: Overflow.
    /return
  }
  echo $chan Error: An unknown error has occured.
}