#
#    Mecrisp-Quintus - A native code Forth implementation for RISC-V
#    Copyright (C) 2018  Matthias Koch
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# Token und Parse zum Zerlegen des Eingabepuffers
# Token and parse to cut contents of input buffer apart

# -----------------------------------------------------------------------------
  Definition Flag_visible, "token" # ( -- c-addr length )
token:
# -----------------------------------------------------------------------------
  pushdaconst 32
  j parse

# -----------------------------------------------------------------------------
  Definition Flag_visible, "parse" # ( c -- c-addr length )
parse:
# -----------------------------------------------------------------------------
  push x1
  push x10
  push x11
  push x12
  push x13
  push x14

  call source
  popda x11  # Length  of input buffer
  popda x10  # Pointer to input buffer

  call source_in # Current >IN gauge
  lw x12, 0(x3)  
  drop

  add x14, x10, x12 # Start address of parsed string

  # Speziell for Token, falls das Trennzeichen das Leerzeichen ist:
  li x13, 32
  bne x3, x13, 2f

1:  beq x11, x12, 3f # Any characters left ?
      add x13, x10, x12
      lbu x13, 0(x13) # Fetch character
      bne x13, x3, 2f # Ist es das Leerzeichen ? Is this the delimiter which is space in this loop ?
        addi x12, x12, 1     # Don't collect spaces, advance >IN to skip.
        add x14, x10, x12   # Recalculate start address of parsed string
        j 1b

2:# Sammelschleife. Collecting loop.
  beq x11, x12, 3f # Any characters left ?

    add x13, x10, x12
    lbu x13, 0(x13)      # Fetch character
    addi x12, x12, 1     # Advance >IN
    bne x13, x3, 2b      # Is this the delimiter ?
      # Finished, fallthrough for delimiter detected.
      add x3, x10, x12
      sub x3, x3, x14
      addi x3, x3, -1    # Delimiter should not be part of the parsed string but needs to be count in >IN
      j 4f

3:# Finished. Fallthrough for end-of-string. Calculate length of parsed string
  add x3, x10, x12
  sub x3, x3, x14

4:# Store start address
  addi x4, x4, -4
  sw x14, 0(x4)

  # Store new >IN
  call source_in # Current >IN gauge
  sw x12, 0(x3)  # Fresh >IN gauge
  drop

  pop x14
  pop x13
  pop x12
  pop x11
  pop x10 
  pop x1
  ret
