Patch title: Release 95 bulk changes
Abstract:
File: /pliant/language/type/text/char.pli
Key:
    Removed line
    Added line
# Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# 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
# version 2 along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

scope "/pliant/language/" "/pliant/install/"
module "/pliant/install/ring2.pli"


type Char
  field Byte raw


function character i -> c
  arg Int i ; arg Char c
  has_no_side_effect ; gcc_inline "*(unsigned char *)@2 = $1;"
  memory_copy addressof:i addressof:c 1

method c number -> i
  arg Char c ; arg Int i
  has_no_side_effect ; gcc_inline "$2 = *(unsigned char *)@1;"
  i := 0
  memory_copy addressof:c addressof:i 1


function compare a b -> c
  arg Char a b ; arg Int c
  gcc_inline "$3 = *(unsigned char *)@1<*(unsigned char *)@2 ? "+'convert to string':compare_inferior+" : *(unsigned char *)@1>*(unsigned char *)@2 ? "+'convert to string':compare_superior+" : "+'convert to string':compare_equal+";"
  gcc_inline_compare "$3 = *(unsigned char *)@1 compare *(unsigned char *)@2;"
  c := compare a:number b:number


export Char character '. number' compare


#----------------------------------------------------------------


method s '' i -> c ## section "map one char"
  arg Str s ; arg Int i ; arg_C Char c
  check i>=0 and i<s:len "out of range character index"
  c :> (s:characters translate Char i) map Char
# ((the_function '' Str Int -> Char) arg 2) maps := 1

export ''


function cast_Char_Str c -> s ## section "cast to string"
  arg Char c ; arg Str s
  extension ; has_no_side_effect
  s set (memory_allocate 1 addressof:s) 1 true
  s 0 := c

alias 'cast Str' cast_Char_Str in "/pliant/language/basic/ultrasafe.pli"


#----------------------------------------------------------------


function parse_char context line parameter
  arg_rw ParserContext context ; arg Str line ; arg Address parameter
  if line:len<2 or line:0<>"[dq]":0
    return
  var Char c ; var Int l
  if line:1<>"[lb]":0 and line:1<>"[rb]":0 and line:1<>"[dq]":0
    c := line 1 ; l := 1
  eif (line 1 4)="[lb]lb[rb]"
    c := "[lb]" 0 ; l := 4
  eif (line 1 4)="[lb]rb[rb]"
    c := "[rb]" 0 ; l := 4
  eif (line 4 3)="[lb]dq[rb]"
    c := "[dq]" 0 ; l := 4
  eif (line 1 4)="[lb]cr[rb]"
    c := "[cr]" 0 ; l := 4
  eif (line 1 4)="[lb]lf[rb]"
    c := "[lf]" 0 ; l := 4
  eif (line 1 3)="[lb]0[rb]"
    c := "[0]" 0 ; l := 3
  eif (line 1 5)="[lb]tab[rb]"
    c := "[tab]" 0 ; l := 5
  else
    return
  if (line 1+l 1)="[dq]"
    var Link:Char cc :> new Char ; cc := c
    context add_token addressof:cc
    context forward l+2

gvar ParserFilter char_filter
char_filter function :> the_function parse_char ParserContext Str Address
constant 'pliant parser basic types' char_filter
export 'pliant parser basic types'


#----------------------------------------------------------------


method c isidentcharacter -> r
  arg Char c ; arg CBool r
  if c:number>="A":number and c:number<="Z":number
    return true
  eif c:number>="a":number and c:number<="z":number
    return true
  eif c:number>="0":number and c:number<="9":number
    return true
  eif c:number="_":number
    return true
  else
    return false


export '. isidentcharacter'


#----------------------------------------------------------------

module "/pliant/language/data/string_cast.pli"


method data 'to string' options -> string
  arg Char data ; arg Str options ; arg Str string
  var Str s := data
  string := to_string addressof:s Str options
  

method data 'from string' string options may_skip skiped offset -> status
  arg_w Char data ; arg Str string options ; arg CBool may_skip ; arg_w Int skiped offset ; arg Status status
  status := from_string addressof:(var Str s) Str string options may_skip skiped offset
  if status=failure
    data := " "
    void
  eif s:len<>1
    data := " "
    status := failure
  else
    data := s 0