cvsuser     03/07/03 19:13:41

  Modified:    languages/BASIC/compiler compile.pl testsuite.pl
  Added:       languages/BASIC/compiler RT_aggregates.imc RT_builtins.imc
                        RT_debugger.imc RT_initialize.imc RT_io.imc
                        RT_platform.imc RT_platform_ANSIscreen.imc
                        RT_platform_win32.imc RT_support.imc
  Removed:     languages/BASIC/compiler RT_aggregates.pasm RT_builtins.pasm
                        RT_debugger.pasm RT_initialize.pasm RT_io.pasm
                        RT_platform.pasm RT_platform_ANSIscreen.pasm
                        RT_platform_win32.pasm RT_support.pasm
  Log:
  IMCC now doesn't allow .const in .pasm files.  Renamed all of the .pasm files
  to .imc (they're PIR anyway).
  
  Revision  Changes    Path
  1.13      +7 -7      parrot/languages/BASIC/compiler/compile.pl
  
  Index: compile.pl
  ===================================================================
  RCS file: /cvs/public/parrot/languages/BASIC/compiler/compile.pl,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -w -r1.12 -r1.13
  --- compile.pl        29 Jun 2003 01:23:26 -0000      1.12
  +++ compile.pl        4 Jul 2003 02:13:41 -0000       1.13
  @@ -45,7 +45,7 @@
   
   open(CODE, ">TARG_test.imc") || die;
   
  -print CODE qq{.include "RT_initialize.pasm"\n};
  +print CODE qq{.include "RT_initialize.imc"\n};
   foreach my $seg ("_main", "_basicmain", keys %code) {
        next unless exists $code{$seg};
        my @debdecl=();
  @@ -206,12 +206,12 @@
        #
        # Pull in the runtime libraries
        #
  -.include "RT_aggregates.pasm"
  -.include "RT_builtins.pasm"
  -.include "RT_debugger.pasm"
  -.include "RT_io.pasm"
  -.include "RT_platform.pasm"
  -.include "RT_support.pasm"
  +.include "RT_aggregates.imc"
  +.include "RT_builtins.imc"
  +.include "RT_debugger.imc"
  +.include "RT_io.imc"
  +.include "RT_platform.imc"
  +.include "RT_support.imc"
   RUNTIMESHUTDOWN
   
   close(CODE);
  
  
  
  1.16      +4 -0      parrot/languages/BASIC/compiler/testsuite.pl
  
  Index: testsuite.pl
  ===================================================================
  RCS file: /cvs/public/parrot/languages/BASIC/compiler/testsuite.pl,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -w -r1.15 -r1.16
  --- testsuite.pl      30 Jun 2003 01:21:08 -0000      1.15
  +++ testsuite.pl      4 Jul 2003 02:13:41 -0000       1.16
  @@ -32,6 +32,10 @@
   }
   
   __DATA__
  +input a$,
  +print a$
  +
  +STOPPLEASE
   ' Expect 10
   sub second(b() )
        b(5)=10
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_aggregates.imc
  
  Index: RT_aggregates.imc
  ===================================================================
        # Array things.
        # Yes, the _N and _S are cheesy hacks. 
  .const int FLOAT = 2
  .const int STRING = 3 
  .const int PMC = 4
  .sub _ARRAY_LOOKUP_N  # float ARRAY_LOOKUP_N(string array, int keycount[, 
string|float])
        saveall
        .param string array
        .local string key
        .local PerlHash BASICARR
        find_global BASICARR, "BASICARR"
        call _ARRAY_BUILDKEY
        .result key
        set $P0, BASICARR[array]
        ne key, "", ARR_NORMAL
        .return $P0             # Return the whole array.
        branch ARR_END
  ARR_NORMAL:
        $P1=$P0["hash"]         # forked arrays, awaiting keys()
        set $N0, $P1[key]
        .return $N0
  ARR_END:
        restoreall
        ret
  .end
  .sub _ARRAY_LOOKUP_S  # string ARRAY_LOOKUP_S(string array, int keycount[, 
string|float])
        saveall
        .param string array
        .local string key
        .local PerlHash BASICARR
        find_global BASICARR, "BASICARR"
        call _ARRAY_BUILDKEY
        .result key
        set $P0, BASICARR[array]
        ne key, "", ARR_NORMAL
        .return $P0
        branch ARR_END
  ARR_NORMAL:
        $P1=$P0["hash"]         # forked arrays, awaiting keys()
        set $S0, $P1[key]
        .return $S0
  ARR_END:
        restoreall
        ret
  .end
                        # void ARRAY_ASSIGN_N(string array, PerlArray rhs, int 
keycount[, string|float keys])
                        # void ARRAY_ASSIGN_N(string array, string rhs, int keycount[, 
string|float keys])
  .sub _ARRAY_ASSIGN    # void ARRAY_ASSIGN_N(string array, float rhs, int keycount[, 
string|float keys])
        saveall
        .param string array
        entrytype $I0, 0
  
        # Assign a number
        ne $I0, FLOAT, ASSIGN_STRING
        .param float rhs
        .local string key
        .local PerlHash BASICARR
        find_global BASICARR, "BASICARR"
  
        call _ARRAY_BUILDKEY   # Will absorb rest of arguments.
        .result key
        set $P1, BASICARR[array]
        set $P0, $P1["hash"]
        set $P0[key], rhs
        store_global "BASICARR", BASICARR
        branch END_ASSIGN
  
        # Assign a string
  ASSIGN_STRING:
        ne $I0, STRING, ASSIGN_UNK
  
        .param string rhs
        .local string key
        .local PerlHash BASICARR
        find_global BASICARR, "BASICARR"
  
        call _ARRAY_BUILDKEY   # Will absorb rest of arguments.
        .result key
        set $P1, BASICARR[array]
        set $P0, $P1["hash"]
        set $P0[key], rhs
        store_global "BASICARR", BASICARR
        branch END_ASSIGN
  
        # Assign a... well, we dunno WTF this is.
  ASSIGN_UNK:
        ne $I0, PMC, ASSIGN_ERR
        .param PerlArray blob
        .local string key
        .local PerlHash BASICARR
        find_global BASICARR, "BASICARR"
        call _ARRAY_BUILDKEY
        set $P1, BASICARR[array]
        set $P0, $P1["hash"]
        .result key
  
        set $S0, blob[TYPE]
        ne $S0, "STRING", NOTSTRING
        set $S1, blob[VALUE]
        set $P0[key], $S1
        branch END_UNK
  
  NOTSTRING:
        ne $S0, "INT", NOTINT
        set $I0, blob[VALUE]
        set $N0, $I0
        set $P0[key], $N0
        branch END_UNK
  
  NOTINT:       ne $S0, "FLOAT", ASSIGN_ERR
        set $N0, blob[VALUE]
        set $P0[key], $N0
        branch END_UNK
  
  END_UNK:
        store_global "BASICARR", BASICARR
        branch END_ASSIGN
  
  ASSIGN_ERR:
        print "Assignment error"
        print $I0
        end
  
  END_ASSIGN:
        # Temporary, needed only until PerlHash->keys() gets implemented
        find_global BASICARR, "BASICARR"
        set $P1, BASICARR[array]
        set $P0, $P1["index"]
        .local int i
        set i, 0
  E_A:  set $S0, $P0[i]
        eq $S0, "", E_A2
        eq $S0, key, E_A2
        inc i
        branch E_A
  E_A2: $P0[i]=key
        $P1["index"]=$P0
        BASICARR[array]=$P1
        store_global "BASICARR", BASICARR
  REALEND:restoreall
        ret
  .end
  # This gets a *lot* easier when PerlHash->keys() gets implemented
  .sub _ARRAY_KEYS      # void ARRAY_KEYS(string source, string target)
        saveall
        .param string source
        .param string target
        .local PerlHash BASICARR
  
        .local PerlArray SRCINDEX
        .local PerlHash TARGARR
        .local PerlArray TARGINDEX
        .local int i
        find_global BASICARR, "BASICARR"
        $P0=BASICARR[source]
        SRCINDEX=$P0["index"]
        $P0=BASICARR[target]
        TARGARR=$P0["hash"]
        TARGINDEX=$P0["index"]
  
        set i, 0
  KEYLOOP:set $S0, SRCINDEX[i]
        eq $S0, "", ENDLOOP
        set $S1, i
        set $S2, "|"
        concat $S2, $S2, $S1
        length $I1, $S0
        dec $I1
        substr $S3, $S0, 1, $I1
        TARGARR[$S2]=$S3
        TARGINDEX[i]=$S2
        inc i
        branch KEYLOOP
   
  ENDLOOP:restoreall
        ret
  .end
  #.sub _ARRAY_ASSIGN_S # void ARRAY_ASSIGN_N(string array, string rhs, int keycount[, 
string|float keys])
  #     saveall
  #     .param string array
  #     .param string rhs
  #     .local string key
  #     .local PerlHash BASICARR
  #     find_global BASICARR, "BASICARR"
  
  #     call _ARRAY_BUILDKEY   # Will absorb rest of arguments.
  #     .result key
  #     set $P0, BASICARR[array]
  #     set $P0[key], rhs
  #
  #     store_global "BASICARR", BASICARR
  #     restoreall
  #     ret
  #.end
  # These are probably defined somewhere, I can't find them.
  .const int FLOAT = 2
  .const int STRING = 3
  .sub _ARRAY_BUILDKEY   # string ARRAY_BUILDKEY(int keycount[, string|float...])
        saveall
        .param int keycount
        .local string key
        set key, ""
  KEYLOOP:le keycount, 0, KEYDONE
        entrytype $I0, 0
        concat key, "|"
        eq $I0, FLOAT, ADDFLOAT
        eq $I0, STRING, ADDSTRING
        print "Wrong type on stack, key creation\n"
        end
  ADDFLOAT:
        restore $N0
        set $I1, $N0
        set $S0, $I1
        concat key, $S0
        dec keycount
        branch KEYLOOP
  ADDSTRING:
        restore $S0
        concat key, $S0
        dec keycount
        branch KEYLOOP
  
  KEYDONE:.return key
        restoreall
        ret
  .end
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_builtins.imc
  
  Index: RT_builtins.imc
  ===================================================================
  #  Display stuff on stack.
  #
  .const int FLOAT = 2
  .const int STRING = 3
  .sub _BUILTIN_DISPLAY                 # void display(....)
        saveall
        .local string buf
        call _BUILTIN_DISPLAY_WORK
        .result buf
        print buf
        restoreall
        ret
  .end
  # Prepares stuff for printing.  Side effect: edits the global PRINTCOL
  #  for the current column.
  #
  .sub _BUILTIN_DISPLAY_WORK            # string display_work(string|float thingy[, 
string|float thingy2])
        saveall
        .param int argc
        .local string buf
        .local int intver
        .local string s
        .local int PRINTCOL
  
        find_global $P0, "PRINTCOL"
        set PRINTCOL, $P0["value"]
  
        set buf, ""
  NEXT: eq argc, 0, END_DISPLAY
        dec argc
        entrytype $I0, 0
        eq $I0, STRING, DISPSTRING
        ne $I0, FLOAT, DISPERR
        
        # Now, do floats
        .param float number
        set intver, number
        set $N0, intver
        eq $N0, number, DISPINT # Nope, it's an integer.
        .arg number
        call _NORMALIZE_FLOAT
        .result s
        lt number, 0.0, NEGFLO
        concat buf, " "
  NEGFLO:       concat buf, s
        concat buf, " "
        branch NEXT
  
        # Integers display -1234_
        #              or  _1234
  DISPINT:set $S0, intver
        lt intver, 0, NEGINT
        concat buf, " "
  NEGINT: concat buf, $S0
        concat buf, " "
        branch NEXT
  
  DISPSTRING:
        .param string str
        length $I0, str
        eq str, "\t", DISPTAB
        concat buf, str
        eq str, "\n", DISPNL
        add PRINTCOL, PRINTCOL, $I0
        branch NEXT
  DISPTAB:
        set $I0, PRINTCOL
          mod $I0, $I0, 8
          sub $I0, 7, $I0
          set $I1, 0
          eq $I1, $I0, NEXT
        concat buf, " "
        inc PRINTCOL
          inc I1
          branch DISPTAB
  DISPNL:       set PRINTCOL, 0
        branch NEXT
  END_DISPLAY:
        .return buf
        set $P0["value"], PRINTCOL
        store_global "PRINTCOL", $P0
        restoreall
        ret
  DISPERR:print "Unknown type on stack to print\n"
        end
  .end
  
  .sub _NORMALIZE_FLOAT # string normalize_flo(float number)
        saveall
        .param float number     # INTERNAL, no argc!
        set $S0, number
  FLO_NORM:
        length $I0, $S0
        substr $S1, $S0, $I0, 1
        eq $S1, ".", FLO_CHOP_DEC
        eq $S1, "0", FLO_CHOP
        branch FLO_END
  FLO_CHOP_DEC:
        substr $S0, $S0, 0, $I0
        branch FLO_END
  FLO_CHOP:
        substr $S0, $S0, 0, $I0
        branch FLO_NORM
  FLO_END:
        .return $S0
        restoreall
        ret
  .end
  
  #  Builtin functions for BASIC
  #
  .sub _BUILTIN_ABS             # float abs(float arg)
        saveall
        .param int argc
        .param float arg
        .local float res
        abs res, arg
        .return res
        restoreall
        ret
  .end
  # INT - a math function that returns the largest integer less than
  #       or equal to a numeric-expression
  .sub _BUILTIN_INT             # float int(float arg)
        saveall
        .param int argc
        .param float arg
        .local float res
        .local int truncate
        set truncate, arg
        set res, truncate
        ge arg, 0.0, ENDINT
        dec res
  ENDINT:       .return res
        restoreall
        ret
  .end
  .sub _BUILTIN_CHR_STRING      # string chr(float arg)
        saveall
        .param int argc
        .param float arg
        .local string res
        .local int truncate
        set truncate, arg
        chr res, truncate
        .return res
        restoreall
        ret
  .end
  .sub _BUILTIN_ASC             # float asc(string arg)
        saveall
        .param int argc
        .param string arg
        .local int conv
        .local float res
        ord conv, arg
        set res, conv
        .return res
        restoreall
        ret
  .end
  .sub _BUILTIN_STR_STRING      # string str(float arg)
        saveall
        .param int argc
        .param float arg
        .local string res
        set res, arg
        .return res
        restoreall
        ret
  .end
  .sub _BUILTIN_VAL             # float val(string arg)
        saveall
        .param int argc
        .param string arg
        .local float res
        set res, arg
        .return res
        restoreall
        ret
  .end
  .sub _BUILTIN_LEN             # float len(string arg)
        saveall
        .param int argc
        .param string arg
        .local float res
        .local int conv
        length conv, arg
        set res, conv
        .return res
        restoreall
        ret
  .end
  .sub _BUILTIN_MID_STRING      # string mid(string targ, float start [, float extent])
        saveall
        .param int argc
        .param string target
        .param float start
        .local string res
        .local string a
        .local int strlen
        .local int pos
        length strlen, target
        set res, ""
        set pos, start
        dec pos
  
        eq argc, 3, MID3ARG
  
  MIDLOOP:ge pos, strlen, MIDDONE
        substr a, target, pos, 1
        concat res, a
        inc pos
        branch MIDLOOP
  
  MID3ARG:
        .local float count
        .param float extent
        set count, 0.0
  MID3L:
        ge pos, strlen, MIDDONE
        substr a, target, pos, 1
        concat res, a
        inc pos
        inc count
        ge count, extent, MIDDONE
        branch MID3L
        
  MIDDONE:
        .return res
        restoreall
        ret
  .end
  .sub _BUILTIN_LEFT_STRING     # string left(string targ, float extent)
        saveall
        .param int argc
        .param string targ
        .param float extent
        .local string res
        
        .arg extent
        .arg 1.0
        .arg targ
        .arg 3
        call _BUILTIN_MID_STRING
        restoreall
        ret
  .end
  .sub _BUILTIN_RIGHT_STRING    # string right(string targ, float extent)
        saveall
        .param int argc
        .param string targ
        .param float extent
        .local string res
        .local int conv
  
        length $I0, targ
        set conv, extent
        sub $I0, $I0, conv
        inc $I0
        set $N0, $I0
  
        .arg extent
        .arg $N0
        .arg targ
        .arg 3
        call _BUILTIN_MID_STRING
        restoreall
        ret
  .end
  # Modifies the system-wide RANDSEED
  # Produces 16-bit pseudo-random numbers.
  .sub _BUILTIN_RND     # float rnd([float seed])
        saveall
        .local int RANDSEED
        .param int argc
        find_global $P0, "RANDSEED"
        set RANDSEED, $P0["value"]
        eq argc, 0, RND_GEN
        .param float repeat
  
        eq repeat, 0.0, RND_REPEAT
  RND_GEN:
        mul RANDSEED, RANDSEED, 5
        add RANDSEED, RANDSEED, 1
        mod RANDSEED, RANDSEED, 65536
        set $N0, RANDSEED
        div $N0, $N0, 65536.0
        branch RND_BAIL
  RND_REPEAT:
        set $N0, RANDSEED
        div $N0, $N0, 65536.0
  RND_BAIL:
        .return $N0
  
        set $P0["value"], RANDSEED
        store_global "RANDSEED", $P0
  
        restoreall
        ret
  .end
  .sub _BUILTIN_TIMER   # float timer()
        saveall
        .param int argc
        time $N0
        .return $N0
        restoreall
        ret 
  .end
  .sub _BUILTIN_INSTR   # float instr([float start,] string full, string substr);
        saveall
        .param int argc
        .local int start
        set start, 1
        eq argc, 2, NOSTART
        .param float startf
        set start, startf
  NOSTART:
        dec start               # BASIC starts at 1.
        .param string full
        .param string substr
        length $I0, substr
        eq $I0, 0, ENDINSTR
        index $I0, full, substr, start
        set $N0, $I0
        
  ENDINSTR:inc $N0
        .return $N0
        restoreall
        ret
  .end
  .sub _BUILTIN_UCASE_STRING    # string ucase$(string targ)
        saveall
        .param int argc
        .arg 122
        .arg 97
        .arg 32
        call _XCASE
        restoreall
        ret
  .end
  .sub _BUILTIN_LCASE_STRING    # string lcase$(string targ)
        saveall
        .param int argc
        .arg 90
        .arg 65
        .arg -32
        call _XCASE
        restoreall
        ret
  .end
                        # For internal use only.  No ARGC!
  .sub _XCASE           # string xcase(string targ, int offset, int lower, int upper
        saveall
        .param int offset
        .param int lower
        .param int upper
        .param string targ
  
        length $I5, targ
        set $S3, ""
        set $I0, 0
  XCASE_LOOP:
        ge $I0, $I5, XCASE_DONE
        substr $S1, targ, $I0, 1
        ord $I2, $S1
        ge $I2, lower, XCASE_OK1
        branch XCASE_INSERT
  XCASE_OK1:
        le $I2, upper, XCASE_SHIFT
        branch XCASE_INSERT
  XCASE_SHIFT:
        sub $I2, $I2, offset
  XCASE_INSERT:
        chr $S1, $I2
        concat $S3, $S1
        inc $I0
        branch XCASE_LOOP
  XCASE_DONE:
        .return $S3
        restoreall
        ret
  .end
  .sub _BUILTIN_SGN     # float sgn(float number)
        saveall
        .param int argc
        .param float number
        set $N0, 0.0
        eq number, 0.0, FINISHED
        set $N0, -1.0
        lt number, 0.0, FINISHED
        set $N0, 1.0
  FINISHED:
        .return $N0
        restoreall
        ret
  .end
  .sub _BUILTIN_STRING_STRING   # string string(float repeat, float ascii)
        saveall         # string string(float repeat, string string)
        .param int argc
        .param float repeatf
        .local int repeat
        set repeat, repeatf
        .local string repeater
        .local string target
        set $I1, 0
        set target, ""
        entrytype $I0, 0
        eq $I0, FLOAT, FLOATB
        .param string thing
        set repeater, thing
        branch REP
  FLOATB:       .param float ascii
        set $I0, ascii
        chr repeater, $I0
  REP:  ge $I1, repeat, BAIL
        concat target, repeater
        inc $I1
        branch REP
  BAIL: .return target
        restoreall
        ret
  .end
  .sub _TRIG_IN
        saveall
        .param int argc
        .param float op
        set $N0, op
        ret
  .end
  .sub _TRIG_OUT
        .return $N0
        restoreall
        ret
  .end
  .sub _BUILTIN_LOG             # float log(float op)
        call _TRIG_IN
        ln $N0, $N0
        call _TRIG_OUT
        ret
  .end
  .sub _BUILTIN_EXP             # float exp(float op)
        call _TRIG_IN
        exp $N0, $N0
        call _TRIG_OUT
        ret
  .end
  .sub _BUILTIN_SIN             # float sin(float op)
        call _TRIG_IN
        sin $N0, $N0
        call _TRIG_OUT
        ret
  .end
  .sub _BUILTIN_COS             # float cos(float op)
        call _TRIG_IN
        cos $N0, $N0
        call _TRIG_OUT
        ret
  .end
  .sub _BUILTIN_TAN             # float tan(float op)
        call _TRIG_IN
        tan $N0, $N0
        call _TRIG_OUT
        ret
  .end
  .sub _BUILTIN_ATN             # float atn(float op)
        call _TRIG_IN
        atan $N0, $N0
        call _TRIG_OUT
        ret
  .end
  .const float EPSILON = 0.000001
  .sub _BUILTIN_SQR             # float sqr(float operand)
        saveall
        .param int argc
        .param float operand
        lt operand, 0.0, ERR_RANGE
        eq operand, 0.0, END
        div $N1, operand, 3.0   # First guess
  AGAIN:        div $N2, operand, $N1   # Newton's method
        add $N2, $N2, $N1
        mul $N2, $N2, 0.5
        sub $N3, $N2, $N1
        gt $N3, 0.0, INV
        mul $N3, $N3, -1.0
  INV:  set $N1, $N2
        gt $N3, EPSILON, AGAIN
        set operand, $N1
  END:  .return operand
        restoreall
        ret
  
  ERR_RANGE:
        print "Number out of range\n"
        .return -1.0
        restoreall
        ret
  .end
  .sub _BUILTIN_TAB_STRING              # string tab(float cols)
        saveall
        .param int argc
        .param float cols
        .local int PRINTCOL
        find_global $P0, "PRINTCOL"
        set PRINTCOL, $P0["value"]
  
        set $I0, cols
  
        dec $I0
        set $S0, ""
        eq $I0, PRINTCOL, TAB_RET
        lt $I0, PRINTCOL, TAB_NL
        set $I1, PRINTCOL
        branch TAB_SP
  TAB_NL: concat $S0, "\n"
        set $I0, 0
        set $I1, 0
  TAB_SP: eq $I1, $I0, TAB_RET
        concat $S0, " "
        inc $I1
        branch TAB_SP
  TAB_RET:.return $S0
        restoreall
        ret
  .end
  .sub _BUILTIN_LTRIM_STRING    # string ltrim(string oldstring)
        saveall
        .param int argc
        .param string oldstring
        set $S0, oldstring
  BI_LTRIM:
        length $I0, $S0
        eq $I0, 0, LTRIM_END
        substr $S1, $S0, 0, 1
        ne $S1, " ", LTRIM_END
        dec $I0
        substr $S0, $S0, 1, $I0
        branch BI_LTRIM
  LTRIM_END:
        .return $S0
        restoreall
        ret
  .end
  .sub _BUILTIN_RTRIM_STRING    # string rtrim(string oldstring)
        saveall
        .param int argc
        .param string oldstring
        set $S0, oldstring
  BI_RTRIM:
        length $I0, $S0
        eq $I0, 0, RTRIM_END
        dec $I0
        substr $S1, $S0, $I0, 1
        ne $S1, " ", RTRIM_END
        substr $S0, $S0, 0, $I0
        branch BI_RTRIM
  RTRIM_END:
        .return $S0
        restoreall
        ret
  .end
  .sub _BUILTIN_INPUT_STRING    # string input$(float numchars[, string fdinfo])
        saveall
        .param int argc
        .param float numcharsf
        .local int numchars
        set numchars, numcharsf
        .local int fd
        set fd, 0               # Stdin
        eq argc, 1, DOREAD
        .param string fdinfo
        length $I0, fdinfo
        dec $I0
        substr fdinfo, fdinfo, 1, $I0
        set fd, fdinfo
  DOREAD:       .arg fd
        .arg numchars
        call _READCHARS
        restoreall
        ret
  .end
  .sub _BUILTIN_INKEY_STRING    # string inkey$(void)
        .param int argc         
        call _scan_read         # Put terminal in char-at-a-time mode
        call _inkey_string
        ret
  .end
  
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_debugger.imc
  
  Index: RT_debugger.imc
  ===================================================================
  .sub _DEBUGGER_STOP_FOR_REAL  # void Debugger_stop(int line, PerlHash local_values)
        saveall
        .param int line
        .param PerlHash locals
        find_global $P25, "DEBUGGER"
  
        set $P0, $P25["code"]
        set $S0, $P0[line]
        print "\n"
        print $S0
        print "\n"
        bsr DEBUGGER_PRINTWATCH
        branch DEBUGGER_COMMAND
  
        # Commands are:
        #  \n           -- Step once, or no-op if not stepping
        #  c            -- Continue  (clears step mode)
        #  s            -- Step      (sets step mode)
        #  b,xxx        -- set breakpoint at x
        #  d,xxx        -- delete breakpoint at x
        #  p,var        -- display var's value (no arrays yet)
        #  aw,var       -- add var to watchlist
        #  dw,var       -- delete var from watchlist
        #  pw           -- print watches
        #  daw          -- delete all watches
  DEBUGGER_COMMAND:
        print line
        print "->"
  
        .arg 0
        call _READLINE
        call _CHOMP
        .result $S0
  
        length $I0, $S0
        set $I1, $P25["step"]
        add $I0, $I0, $I1
        eq $I0, 0, DEBUGGER_COMMAND  # If no step mode, and no input, re-prompt
  
        .arg 1
        .arg $S0
        call _SPLITLINE # P1 will have array of values
        .result $P1
  
        set $I0, $P1
        add $I0, $I0, $I1
        eq $I0, 0, DEBUGGER_COMMAND # If no values, re-prompt
  
        shift $S0, $P1
        eq $S0, "c", DEBUGGER_CONT
        eq $S0, "s", DEBUGGER_STEPON
        eq $S0, "b", DEBUGGER_ARG
        eq $S0, "d", DEBUGGER_ARG
        eq $S0, "p", DEBUGGER_PRINT
        eq $S0, "q", DEBUGGER_QUIT
        eq $S0, "aw", DEBUGGER_ADDWATCH
        eq $S0, "dw", DEBUGGER_DELWATCH
        eq $S0, "daw", DEBUGGER_DELALLWATCH
        eq $S0, "pw", DEBUGGER_PRINTWATCH1
        set $I1, $P25["step"]
        eq $I1, 0, DEBUGGER_UNK
        ret
  
  DEBUGGER_PRINT:
        set $I0, $P1
        eq $I0, 0, DEBUGGER_PARG
  
        shift $S0, $P1
        set $S1, locals[$S0]    
        print $S1
        print "\n"
        branch DEBUGGER_COMMAND
  
  DEBUGGER_PRINTWATCH1:
        bsr DEBUGGER_PRINTWATCH
        branch DEBUGGER_COMMAND
  
  DEBUGGER_PARG:
        print "Expected variable name argument"
        branch DEBUGGER_COMMAND
  
  DEBUGGER_UNK:
        print "Unknown command\n"
        branch DEBUGGER_COMMAND
  
  DEBUGGER_QUIT:
        print "Debugger exiting\n"
        end
  
  DEBUGGER_ADDWATCH:
        set $I0, $P1
        eq $I0, 0, DEBUGGER_PARG
  
        shift $S0, $P1
        bsr DEBUG_ADD
        print "Watch for "
        print $S0
        print " added\n"
        branch DEBUGGER_COMMAND
  
  DEBUGGER_DELWATCH:
        set $I0, $P1
        eq $I0, 0, DEBUGGER_PARG
  
        shift $S0, $P1
        bsr DEBUG_CLEAR
        print "Watch for "
        print $S0
        print " cleared\n"
        branch DEBUGGER_COMMAND
  
  DEBUGGER_DELALLWATCH:
        $P0=new PerlArray
        set $P25["watch"], $P0
        print "All watches cleared.\n"
        branch DEBUGGER_COMMAND
  
  DEBUGGER_ARG:
        set $I0, $P1
        eq $I0, 0, DEBUGGER_ERR
        shift $I0, $P1
        set $S1, $I0
        set $P0, $P25["break"]
        eq $S0, "b", DEBUGGER_SET
        branch DEBUGGER_DEL
  DEBUGGER_SET:
        set $P0[$S1], 1
        print "Breakpoint set at line "
        print $S1
        print "\n"
        branch DEBUGGER_COMMAND
  DEBUGGER_DEL:
        delete $P0[$S1]
        print "Breakpoint cleared from line "
        print $S1
        print "\n"
        branch DEBUGGER_COMMAND
  DEBUGGER_CONT:
        set $P25["step"], 0
        branch DEBUGGER_DONE
  DEBUGGER_STEPON:
        set $P25["step"], 1
        branch DEBUGGER_DONE
  
  DEBUGGER_ERR:
        print "Numeric argument expected\n"
        branch DEBUGGER_COMMAND
  
  
  
  DEBUG_CLEAR:  
        set P0, P25["watch"]
        set I0, P0
          eq I0, 0, DEBUG_CLEAREND
          set I1, 0
  DEBUG_CLEARLOOP:
          eq I1, I0, DEBUG_CLEAREND
          set S1, P0[I1]
          eq S1, S0, DEBUG_CLEARBLANK
          inc I1
          branch DEBUG_CLEARLOOP
  DEBUG_CLEARBLANK:
          set P0[I1], ""
          branch DEBUG_CLEAREND
  DEBUG_CLEAREND:
          ret
  
  DEBUG_ADD:
        set $P0, $P25["watch"]
          set $I0, $P0
          eq $I0, 0, DEBUG_ADDNEW
          set $I1, 0
  DEBUG_ADDLOOP:eq $I1, $I0, DEBUG_ADDNEW
          set $S1, $P0[$I1]
          eq $S1, "", DEBUG_ADDSLOT
          eq $S1, $S0, DEBUG_ADDEND
          inc $I1
          branch DEBUG_ADDLOOP
  
  DEBUG_ADDSLOT:set $P0[$I1], $S0
          branch DEBUG_ADDEND
  DEBUG_ADDNEW: push $P0, $S0
  DEBUG_ADDEND: ret
  
  DEBUGGER_PRINTWATCH:  
        set $P0, $P25["watch"]
        set $I0, $P0
          eq $I0, 0, DEBUG_PRINTEND
        print "Watches: "
          set $I1, 0
  DEBUG_PRINTLOOP:
          eq $I1, $I0, DEBUG_PRINTEND
          set $S0, $P0[$I1]
          inc $I1
          eq $S0, "", DEBUG_PRINTLOOP
        print $S0
        print "="
        set $S1, locals[$S0]    
        print $S1
        print "\t"
          branch DEBUG_PRINTLOOP
  
  DEBUG_PRINTEND:
          print "\n"
        ret
  
  DEBUGGER_DONE:
        store_global "DEBUGGER", $P25
        restoreall
        ret
  .end
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_initialize.imc
  
  Index: RT_initialize.imc
  ===================================================================
  .const int TYPE = 0
  .const int VALUE = 1
  .local string JUMPLABEL
  .sub _main
        $P0 = new PerlHash 
        store_global "BASICARR", $P0
        $P0 = new PerlArray
        store_global "READDATA", $P0
        $P0 = new PerlHash
        store_global "RESTOREINFO", $P0
        $P0=new PerlHash
        $P0["value"]=0
        store_global "READPOINTER", $P0
        $P0=new PerlHash
        $P0["value"]=20021107
        store_global "RANDSEED", $P0
        $P0=new PerlHash
        $P0["value"]=0
        store_global "PRINTCOL", $P0
        $P0=new PerlHash
        store_global "DEBUGGER", $P0
        $P0=new PerlHash
        store_global "COMMON", $P0
        $P0=new PerlArray
        fdopen $P1, 0, "r"      # STDIN and friends...
        $P0[0]=$P1
        fdopen $P1, 1, "w"
        $P0[1]=$P1
        fdopen $P1, 2, "w"
        $P0[2]=$P1
        store_global "FDS", $P0
  
        JUMPLABEL = ""
  
        call _data_run
        call _platform_setup
        call _basicmain_run
        call _platform_shutdown
        end
  
  .end          
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_io.imc
  
  Index: RT_io.imc
  ===================================================================
        # I/O *core* functions
        # All of this is likely to change once Parrot gets
        #    the I/O sorted out.
        #
        # Not a lot of error handling here yet
  .sub _READCHARS       # string readchars(int numchar, int fd)
        saveall
        .param int numchar
        .param int fd
        ne fd, 0, NORESET
        call _line_read
  NORESET:find_global $P0, "FDS"
        $P1=$P0[fd]
        set $S0, ""
        read $S0, $P1, numchar
        .return $S0
        restoreall
        ret
  .end
  .sub _OPEN            # void open(string filename, string mode, int fd)
        saveall
        .param string filename
        .param string mode
        .param int fd
        .local int error
        open $P1, filename, mode
        err error
        eq error, 0, OPEN_OK
        print "Error "
        print error
        print " in open\n"
        end
  OPEN_OK:
        find_global $P0, "FDS"
        $P0[fd]=$P1
        store_global "FDS", $P0
        restoreall
        ret
  .end
  .sub _CLOSE           # void close(int fd)
        saveall
        .param int fd
        .local int error
        find_global $P0, "FDS"
        set $P1, $P0[fd]
        close $P1
        err error
        eq error, 0, CLOSE_OK
        print "Error "
        print error
        print " in close\n"
        end
  CLOSE_OK:
        store_global "FDS", $P0
        restoreall
        ret
  .end
  .sub _WRITE           # void writestring(int fd, 1, string stuff)
        saveall
        .param int fd
        .local string buffer
        .local int oldprintcol
  
        find_global $P1, "PRINTCOL"
        oldprintcol=$P1["value"]
        call _BUILTIN_DISPLAY_WORK
        .result buffer
        find_global $P1, "PRINTCOL"
        $P1["value"]=oldprintcol
        store_global "PRINTCOL", $P1
  
        find_global $P0, "FDS"
        set $P1, $P0[fd]
        print $P1, buffer
        restoreall
        ret
  .end
  
  #
  #        # ###########################
  #        # READLINE    Read FD until EOL
  #        # Takes:
  #        #       I1   FD to read
  #        #       S0   String read (EOL included!)
  #        #
  #        # Returns:
  #        #       I0   Error?
  .sub _READLINE                # string readline(int fd)
        saveall
        .param int fd
        ne 0, fd, NOTSTDIN
        call _line_read
        readline $S0, fd
        branch ENDREAD
  NOTSTDIN:
        find_global $P0, "FDS"
        $P1=$P0[fd]
        set $S0, ""
        read $S0, $P1, 255
  ENDREAD:
        .return $S0
        restoreall
        ret
  .end
  #     # ###########################
  #     # SPLITLINE     Splits a line into parts
  #     # Outputs:
  #     #       P1      Array of strings
  .sub _SPLITLINE               # PerlArray splitline (string line, int splitflag)
        saveall
        .param string line
        .param int splitflag
        .local string token
        .arg line
        call _CHOMP
        .result line
  
        $P1=new PerlArray
        eq splitflag, 0, SPLITSINGLE
  
  SPLITAGAIN:
        length $I0, line
        eq $I0, 0, SPLITEND
        .arg line
        call _REMOVETOK
        .result line
        .result token
        push $P1, token
        branch SPLITAGAIN
  
  SPLITEND:
        set $I1, $P1
        ne $I1, 0, SPLITGONE
        push $P1, ""
        branch SPLITGONE
  
  SPLITSINGLE:
        push $P1, line
  
  SPLITGONE:
        .return $P1
        restoreall
  
        ret
  .end
  #
  #     # ############################
  #     # Remove a token from the front of S0
  #     # BASIC's Rules:
  #     #    COMMAS separate tokens
  #     #    Leading/trailing spaces ignored and removed.
  #     #    Quotes can surround part of a token w/commas and spaces
  .sub _REMOVETOK               # (string token, string neworiginal) removetok(string 
original)
        saveall
        .param string original
        set $I1, 0      # Inquote
        set $S1, ""     # Base string
  TOKLOOP:
        length $I0, original
        eq $I0, 0, EOTOK
        substr $S2, original, 0, 1
        dec $I0
        substr original, original, 1, $I0
        eq $S2, '"', QUOTE
        eq $I1, 1, QUOTED
        eq $S2, " ", WHITESP
        eq $S2, "\r", WHITESP
        eq $S2, "\n", WHITESP
        eq $S2, ",", EOTOK
        concat $S1, $S1, $S2
        branch TOKLOOP
  WHITESP:length $I0, $S1
        eq $I0, 0, TOKLOOP  # Leading spaces
  QUOTED: concat $S1, $S1, $S2
        branch TOKLOOP
  QUOTE:        eq $I1, 0, STARTQ
        set $I1, 0
        branch TOKLOOP
  STARTQ: set $I1, 1
        branch TOKLOOP
  EOTOK:        .return $S1     # The token
        .return original# The original, w/o the token
        restoreall
  .end
  
  #        # ###########################
  #        # CHOMP      Remove trailing \r\n thingies from S0
  .sub _CHOMP   # string chomp(string line)
        saveall
        .param string line
        length $I0, line
        dec $I0
        le $I0, 0, CHOMPOK
  CHOMPLOOK:
        substr $S1, line, $I0, 1
        eq $S1, "\n", CHOMPIT
        eq $S1, "\r", CHOMPIT
        eq $S1, "", CHOMPIT
        branch CHOMPOK
  CHOMPIT:substr line, line, 0, $I0
        dec $I0
        le $I0, 0, CHOMPOK
        branch CHOMPLOOK
  CHOMPOK:.return line
        restoreall
        ret
  .end  
  
  #
  #ERR_INPFIELDS:
  #     print "Input field count wrong"
  #     branch GEN_ERROR
  #ERR_BADF:
  #     print "File descriptor is incorrect"
  #     branch GEN_ERROR
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_platform.imc
  
  Index: RT_platform.imc
  ===================================================================
  .include "RT_platform_win32.imc"
  .include "RT_platform_ANSIscreen.imc"
  .sub _platform_setup          # void platform_setup(void)
        saveall
        sysinfo S0, 4
        ne S0, "MSWin32", NOTWIN
        call _win32_setup
        branch END
  NOTWIN: call _ansi_setup
  END:  restoreall
        ret
  .end
  .sub _platform_shutdown
        saveall
        sysinfo S0, 4
        ne S0, "MSWin32", NOTWIN
        call _win32_shutdown
        branch END
  NOTWIN: call _ansi_shutdown
  END:  restoreall
        ret
  .end
  .sub _screen_clear
        saveall
        find_global $P0, "PRINTCOL"
        set $P0["value"], 0
        store_global "PRINTCOL", $P0
        sysinfo S0, 4
        ne S0, "MSWin32", NOTWIN
        call _win32_screen_clear
        branch END
  NOTWIN: call _ansi_screen_clear
  END:  restoreall
        ret
  .end
  
  #SCREEN_SETXCUR:
  #     set I1, P6[.VALUE]
  #     sysinfo S0, 4
  #     eq S0, "MSWin32", WIN32_SCREEN_SETXCUR
  #     branch ANSI_SCREEN_SETXCUR
  #
  #SCREEN_SETYCUR:
  #     set I1, P6[.VALUE]
  #     sysinfo S0, 4
  #     eq S0, "MSWin32", WIN32_SCREEN_SETYCUR
  #     branch ANSI_SCREEN_SETYCUR
  #
  #     # X in P7, Y in P6
  .sub _screen_locate           # void screen_locate(float x, float y)
        saveall
        .param float xf
        .param float yf
        .local int x
        .local int y
        .local string sys
        set x, xf
        set y, yf
        sysinfo sys, 4
  
        .arg y
        .arg x
        ne sys, "MSWin32", NOTWIN
        call _WIN32_SCREEN_LOCATE
        branch END
  NOTWIN: call _ANSI_SCREEN_LOCATE
  END:  restoreall
        ret
  .end
  .sub _screen_color    # void screen_color(float fore, float back)
        saveall
        .param float foref
        .param float backf
        .local int fore
        .local int back
        .local string sys
        set back, backf
        set fore, foref
        .arg back
        .arg fore
        sysinfo sys, 4
        ne sys, "MSWin32", NOTWIN
        call _WIN32_SCREEN_COLOR
        branch END
  NOTWIN: call _ANSI_SCREEN_COLOR
  END:  restoreall
        ret
  .end
  
  .sub _line_read
        saveall
        .local string sys
        sysinfo sys, 4
        eq sys, "MSWin32", END
        call _TERMIO_normal
  END:  restoreall
        ret
  .end
  .sub _scan_read
        saveall
        .local string sys
        sysinfo sys, 4
        eq sys, "MSWin32", END
        call _TERMIO_scankey
  END:  restoreall
        ret
  .end
  
  .sub _inkey_string            # string inkey$(void)
        saveall
        .local string sys
        sysinfo sys, 4
        ne sys, "MSWin32", NOTWIN
        call _WIN32_INKEY
        branch END
  NOTWIN: call _TERMIO_INKEY
  END:  restoreall
        ret
  .end
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_platform_ANSIscreen.imc
  
  Index: RT_platform_ANSIscreen.imc
  ===================================================================
  .const int BLACK =  0
  .const int RED        =  1
  .const int GREEN  = 2
  .const int YELLOW = 3
  .const int BLUE   = 4
  .const int MAGENTA= 5
  .const int CYAN   = 6
  .const int WHITE  = 7
  .sub _ansi_setup
        saveall
        $P0=new PerlArray
        set $P0[0], BLACK
        set $P0[1], BLUE
        set $P0[2], GREEN
        set $P0[3], CYAN
        set $P0[4], RED
        set $P0[5], MAGENTA
        set $P0[6], YELLOW
        set $P0[7], WHITE
        store_global "ANSI_fgcolors", $P0
  
        $P0=new PerlArray
        set $P0[0], BLACK
        set $P0[1], BLUE
        set $P0[2], GREEN
        set $P0[3], CYAN
        set $P0[4], RED
        set $P0[5], MAGENTA
        set $P0[6], YELLOW
        set $P0[7], WHITE
        set $P0[8], BLACK
        set $P0[9], BLUE
        set $P0[10], GREEN
        set $P0[11], CYAN
        set $P0[12], RED
        set $P0[13], MAGENTA
        set $P0[14], YELLOW
        set $P0[15], 8
        store_global "ANSI_bgcolors", $P0
  
        $P0=new PerlHash
        $P0["value"]=0
        store_global "scankey", $P0
  
        restoreall
        ret
  .end
  .sub _ansi_screen_clear
        print "\e[2J"
        print "\e[H"
        ret
  .end
  .sub _ansi_shutdown
        call _TERMIO_normal
        ret
  .end
  .sub _ANSI_SCREEN_LOCATE      # void ansi_screen_locate (int x, int y)
        saveall
        .param int x
        .param int y
        print "\e["
        print x
        print ";"
        print y
        print "H"
        restoreall
        ret
  .end
  ## These don't work exactly right.  ANSI would require that I send
  ## \e[6n and read the input stream for a \e[row;colR reply from the 
  ## terminal.  I *really* can't do that until IO is fixed, because STDIN
  ## is line-buffered and asking the user to press return after each cursor
  ## positioning is lame.
  #ANSI_SCREEN_SETXCUR:
  #     print "\e[;"
  #     print I1
  #     print "H"
  #     ret
  #
  #ANSI_SCREEN_SETYCUR:
  #     print "\e["
  #     print I1
  #     print ";H"
  #     ret
  #
  #     # I0,I1
  #     # QB origin is 1,1
  
  ## QB.exe
  ##     0 = black       4 = red           8 = grey             12 = light red
  ##     1 = blue        5 = magenta       9 = light blue       13 = light magenta
  ##     2 = green       6 = brown        10 = light green      14 = yellow
  ##     3 = cyan        7 = white        11 = light cyan       15 = bright white
  #
  .sub _ANSI_SCREEN_COLOR               #  void ansi_screen_color(int fg, int bg)
        saveall
        .param int fore
        .param int back
        print "\e"
  #     # foreground in I0
  #     # background in I1
        print "[0;"
        find_global $P0, "ANSI_fgcolors"
        lt fore, 8, ANSI_FG
        sub fore, fore, 8
        print "1;"      # Turn on high intensity
  ANSI_FG: set $I3, $P0[fore]
        print "3"
        print $I3
        print ";"
        
        # Background
  ANSI_BG:find_global $P0, "ANSI_bgcolors"
        set $I3, $P0[back]
        print "4"
        print $I3
        print "m"
        restoreall
        ret
  .end
  .sub _set_noecho_cbreak
        saveall
        loadlib P1, ""
        dlfunc P0, P1, "ioctl", "iiip"
        set I0, 1
        P9 = new ManagedStruct  # Saved
        P10 = new ManagedStruct   # New
        set P9, 20      # sizeof termio 4/byte aligned
        set P10, 20
        set I5, 0
        set I6, 0x5405  # TCGETA
        set P5, P9
        invoke          # ioctl(0, TCGETA, &savetty);
        set I5, 0
        set I6, 0x5405
        set P5, P10
        invoke          # ioctl(0, TCGETA, &settty);
        .arg 2
        .arg 6
        .arg P10
        call _get_little_endian
        .result I0
        set I1, 2       # ICANON
        bnot I1, I1     # ~ICANON
        band I0, I0, I1 # settty.c_lflag &= ~ICANON;
        set I1, 8       # IECHO
        bnot I1, I1     # ~ICANON
        band I0, I0, I1 # settty.c_lflag &= ~ECHO;
        .arg I0
        .arg 2
        .arg 6
        .arg P10
        call _set_little_endian
        set I5, 0
        set I6, 0x5408
        set P5, P10
        invoke          # ioctl(0, TCSETAF, &settty);
        store_global "ioctl_mode", P9
        restoreall
        ret
  .end
  .sub _set_echo_nocbreak
        saveall 
        loadlib P1, ""
        dlfunc P0, P1, "ioctl", "iiip"
        find_global P9, "ioctl_mode"
        set I5, 0
        set I6, 0x5408
        set P5, P9
        invoke          # ioctl(0, TCSETAF, &savetty)
        restoreall
        ret
  .end
  
  .sub _set_nonblock    # void _set_nonblock
        saveall
        set I11, 0
        loadlib P1, ""
        dlfunc P0, P1, "fcntl", "iiii"
        set I0, 1
        set I5, 0       # Stdin
        set I6, 3       # F_GETFL
        invoke          # mode=fcntl(0, F_GETFL, unused)
  
        set I11, I5     # Old values
        dlfunc P0, P1, "fcntl", "iiil"
        bor I7, I5, 2048  # O_NONBLOCK 04000
        set I5, 0       # Stdin
        set I6, 4       # F_SETFL
        invoke          # nmode=fcntl(0, F_SETFL, mode | O_NONBLOCK)
  
        $P0=new PerlHash
        set $P0["value"], I11
        store_global "fcntl_mode", $P0
        restoreall
        ret
  .end
  .sub _unset_nonblock  # void _unset_nonblock
        saveall
        find_global P0, "fcntl_mode"
        set I11, P0["value"]
        loadlib P1, ""
        dlfunc P0, P1, "fcntl", "iiil"
        set I7, I11
        set I5, 0
        set I6, 4
        invoke          # nmode=fcntl(0, F_SETFL, mode)
        restoreall
        ret
  .end
  .sub _TERMIO_scankey
        saveall
        find_global $P0, "scankey"
        set I0, $P0["value"]
        eq I0, 1, END
          #call _set_nonblock
        call _set_noecho_cbreak
  END:    set $P0["value"], 1
        store_global "scankey", $P0
        restoreall
        ret
  .end
  .sub _TERMIO_normal
        saveall
        find_global $P0, "scankey"
        set I0, $P0["value"]
        eq I0, 0, END
        #call _unset_nonblock
        call _set_echo_nocbreak
  END:    set $P0["value"], 0
        store_global "scankey", $P0
        restoreall
        ret
  .end
  
  # For now, uses TERMIO calls directly and assumes you're on a
  # LITTLE ENDIAN machine.
  .sub _TERMIO_INKEY
        saveall
  
        read $S0, 1
  
        .return $S0
        restoreall
        ret
  .end
  
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_platform_win32.imc
  
  Index: RT_platform_win32.imc
  ===================================================================
  .const int SIZEOF_CONSOLE_SCREEN_BUFFER_INFO = 22
  .const int SIZEOF_DWORD = 4
  .sub _win32_setup                     # void win32_setup(void)
        saveall
        loadlib P1, "kernel32.dll"
        dlfunc P0, P1, "GetStdHandle", "pi"
        set I0, 1
        set I5, -11
        invoke
        store_global "kernel32", P1
        store_global "Win32handle", P5
        set I0, 1
        set I5, -10
        invoke
        store_global "Win32Inputhandle", P5
        $P0= new PerlHash
        store_global "Win32console", $P0
        call _WIN32_CONSOLE_INFO
        restoreall
        ret
  .end
  .sub _win32_shutdown                  # void win32_shutdown(void)
        ret
  .end
  .sub _WIN32_CONSOLE_INFO              # void WIN32_CONSOLE_INFO(void)
        saveall
        find_global P1, "kernel32"
        dlfunc P0, P1, "GetConsoleScreenBufferInfo", "ipp"
        find_global P5, "Win32handle"
        P6=new ManagedStruct
        set P6, SIZEOF_CONSOLE_SCREEN_BUFFER_INFO
        set I0, 1
        invoke
        set P5, P6
        find_global P0, "Win32console"
  
        .arg P5
        .arg 0                  # dwSize.X
        call _UMS_GET_SHORT
        .result $I1
        set P0["xbuf"], $I1
  
        .arg P5
        .arg 2                  # dwSize.Y
        call _UMS_GET_SHORT
        .result $I1
        set P0["ybuf"], $I1
  
        .arg P5
        .arg 4
        call _UMS_GET_SHORT
        .result $I1
        inc $I1
        set P0["curx"], $I1
  
        .arg P5
        .arg 4
        call _UMS_GET_SHORT
        .result $I1
        inc $I1
        set P0["cury"], $I1
  
        set $I1, P5[8]
        set P0["attr"], $I1     # wAttributes
        restoreall
        ret
  .end
  .sub _UMS_GET_SHORT           # int value ums_get_short(int offset, ManagedStruct 
buf)
        saveall
        .param int offset
        .param ManagedStruct buf
        set $I2, buf[offset]
        inc offset
        set $I3, buf[offset]
        shl $I3, $I3, 8
        add $I3, $I3, $I2
        .return $I3
        restoreall
        ret
  .end
  .sub _win32_screen_clear      # void _WIN32_SCREEN_CLEAR(void)
        call _WIN32_CONSOLE_CLEAR
        call _WIN32_CONSOLE_HOME
        ret
  .end
  .sub _WIN32_CONSOLE_HOME      # void Win32_console_home(void)
        saveall
        find_global P2, "kernel32"
        dlfunc P0, P2, "SetConsoleCursorPosition", "ipi"
        set I0, 1
        find_global P5, "Win32handle"
        set I5, 0
        invoke
        restoreall
        ret
  .end
  
  .sub _WIN32_CONSOLE_CLEAR     # void Win32_console_clear(void)
        saveall
        find_global P1, "Win32console"
        find_global P2, "kernel32"
        dlfunc P0, P2, "FillConsoleOutputCharacterA", "ipcilp"
        set I0, 1
        find_global P5, "Win32handle"
        P6=new ManagedStruct
        set P6, SIZEOF_DWORD
        set I5, 32                      # Char (space)
        set I1, P1["xbuf"]
        set I2, P1["ybuf"]
        mul I6, I1, I2                  # Length
        set I7, 0                       # Coords
        invoke
        # Now, re-fill screen with whatever attribute is currently
        # in effect.
        dlfunc P0, P2, "FillConsoleOutputAttribute", "ipiilp"
        set I0, 1
        find_global P5, "Win32handle"
        P6= new ManagedStruct
        set P6, SIZEOF_DWORD
        set I5, P1["attr"]              # Attrib
        set I1, P1["xbuf"]
        set I2, P1["ybuf"]
        mul I6, I1, I2                  # Length
        set I7, 0                       # Coords
        invoke
        restoreall
        ret
  .end
  .sub _WIN32_SCREEN_FINDPOS            # void Win32_screen_findpos(void)
        call _WIN32_CONSOLE_INFO
        ret
  .end
  .sub _WIN32_SCREEN_GETXCUR            # int win32_screen_getxcur(void)
        saveall
        find_global P1, "Win32console"
        set $I0, P1["curx"]
        .return $I0
        restoreall
        ret
  .end
  .sub _WIN32_SCREEN_GETYCUR            # int win32_screen_getycur(void)
        saveall
        find_global P1, "Win32console"
        set $I0, P1["cury"]
        .return $I0
        restoreall
        ret
  .end
  .sub _WIN32_SCREEN_SETXCUR    # void win32_screen_setxcur(int x)
        saveall
        .param int x
        .local int y
        call _WIN32_SCREEN_FINDPOS
        call _WIN32_SCREEN_GETYCUR
        .result y
        .arg y
        .arg x
        call _WIN32_SCREEN_LOCATE
        restoreall
        ret
  .end
  .sub _WIN32_SCREEN_SETYCUR    # void win32_screen_setycur(int y)
        saveall
        .param int y
        .local int x
        call _WIN32_SCREEN_FINDPOS
        call _WIN32_SCREEN_GETXCUR
        .result x
        .arg y
        .arg x
        call _WIN32_SCREEN_LOCATE
        restoreall
        ret
  .end
  .sub _WIN32_SCREEN_LOCATE     # void win32_screen_locate(int x, int y)
        saveall
        .param int x
        .param int y
        dec x
        dec y
        set I5, x
        shl I5, I5, 16
        add I5, I5, y
        find_global P1, "Win32console"
        find_global P2, "kernel32"
        dlfunc P0, P2, "SetConsoleCursorPosition", "ipi"
        set I0, 1
        find_global P5, "Win32handle"
        invoke
        restoreall
        ret
  .end
  
  #SCREEN Mode 0 Syntax:  COLOR [foreground][,[background][,border]]
  #   � foreground is the text color (range = 0-31, with 16-31 blinking)
  #   � background is the screen color (range = 0-7)
  #   � border is the color surrounding the screen (range = 0-15)
  #     0 = black       4 = red           8 = grey             12 = light red
  #     1 = blue        5 = magenta       9 = light blue       13 = light magenta
  #     2 = green       6 = brown        10 = light green      14 = yellow
  #     3 = cyan        7 = white        11 = light cyan       15 = bright white
  .const int  FOREGROUND_BLUE  =      1
  .const int  FOREGROUND_GREEN  =     2
  .const int  FOREGROUND_RED    =  4
  .const int  FOREGROUND_INTENSITY =  8
  .const int  BACKGROUND_BLUE   = 16
  .const int  BACKGROUND_GREEN  = 32
  .const int  BACKGROUND_RED    = 64
  .const int  BACKGROUND_INTENSITY = 128
  #WIN32_SCREEN_GETFORE:
  #     set P1, P24["console"]
  #     set I0, P1["attr"]
  #     band I0, I0, 15
  #     ret
  #WIN32_SCREEN_GETBACK:
  #     set P1, P24["console"]
  #     set I0, P1["attr"]
  #     shr I0, I0, 4
  #     ret
  #     # Call with the foreground in I0
  #     #               background in I1
  #     # "border" is not obeyed here.
  .sub _WIN32_SCREEN_COLOR      # void Win32_screen_color(int fore, int back)
        saveall
        .param int fore
        .param int back
        shl I5, back, 4
        add I5, I5, fore
        find_global P2, "kernel32"
        dlfunc P0, P2, "SetConsoleTextAttribute", "ipi"
        find_global P5, "Win32handle"
        set I0, 1
        invoke
        call _WIN32_CONSOLE_INFO  # refresh this.
        restoreall
        ret
  .end
  .const int SIZEOF_INPUT_RECORD = 20
  .const int NUMBER_OF_EVENTS = 128
  # buffer is INPUT_RECORD * EVENTS
  .const int INPUT_BUFFER = 2560
  .sub _WIN32_INKEY     # string Win32_inkey(void)
        saveall
        set S0, ""
        set I9, 0
        find_global P1, "kernel32"
        dlfunc P0, P1, "SetConsoleMode", "ipi"
        set I0, 1
        find_global P5, "Win32Inputhandle"
        set I5, 0
        invoke
  INKEY:  
        dlfunc P9, P1,  "PeekConsoleInputA",  "ippip"
          dlfunc P10, P1, "ReadConsoleInputA", "ippip"
        find_global P5, "Win32Inputhandle"
        P6=new ManagedStruct
        P7=new ManagedStruct
        set P6, INPUT_BUFFER
        set P7, SIZEOF_DWORD
  
        # Are there any events?
        set P0, P9      # Peek
        set I0, 1
        set I5, NUMBER_OF_EVENTS        # sizeof read buffer
        invoke
  
        # Peek down the event queue to see if there's a key event
        set I0, P7[0]   # Number of events.
        eq I0, 0, NO_EVENTS
        set I5, -1
  NEXT_EVENT:
        inc I5
        eq I5, I0, END_EVENTS
        mul I7, I5, SIZEOF_INPUT_RECORD
        set I1, P6[I7]
        ne I1, 1, NEXT_EVENT
  
        # Got a key event, was it a key down?
        add I8, I7, SIZEOF_DWORD
        set I1, P6[I8]
        ne I1, 1, NEXT_EVENT    # Nope, a key up
  
        # Is it a special-key thingy? (shift, alt...)
        add I8, I7, 14
        set I1, P6[I8]
        eq I1, 0, NEXT_EVENT
  
        # Cool.  Grab the key.
        set I9, I1
        chr S0, I9
  
        # I6 is the event we're interested in!
        # 
        # There *was* a key event.  Pull everything up to that event
        #
        inc I5
        set P0, P10     # ReadConsoleInput
          set I0, 1
        find_global P5, "Win32Inputhandle"
        invoke
        branch END
  
  NO_EVENTS:
  END_EVENTS:
  END:  .return S0
        restoreall
        ret
  .end
  
  
  
  1.1                  parrot/languages/BASIC/compiler/RT_support.imc
  
  Index: RT_support.imc
  ===================================================================
  #     # ##########################
  #     # Do next read for READ/DATA
  #     #  P15 has the data itself
  #     #  P16 has the index (for restore)
  #     #  I15 is the current pointer
  #     # Trashes I0
  #     # Returns:
  #     #        P0 value read.
  #READ:        set I0, P15
  #     dec I0
  #     lt I0, I15, ERR_READ
  #     set P0, P15[I15]
  #     inc I15
  #     ret
  #
  #     # ####################################
  #     # Index you want to restore into in S0
  #     # An invalid "restore X" statement generates
  #     # no error!  It simply does a "restore"
  #RESTORE:set I15, P16[S0]
  #     ret
  #     
  #ERR_READ:
  #     print "Out of data"
  #     branch GEN_ERROR
  
  .sub _READ            # PerlArray READ(void)
        saveall
        .local PerlArray READDATA
        .local int READPOINTER
        find_global READDATA, "READDATA"
        find_global $P0, "READPOINTER"
        set READPOINTER, $P0["value"]
  
        set $I0, READDATA
        dec $I0
        lt $I0, READPOINTER, ERR_READ
  
        set $S1, READDATA[READPOINTER]
        inc READPOINTER
        .return $S1
  
        set $P0["value"], READPOINTER
        store_global "READPOINTER", $P0
  
        restoreall
        ret
  ERR_READ:
        print "Out of data"
        end
  .end
  .sub _RESTORE         # void RESTORE(string where)
        saveall
        .param string where
        .local int READPOINTER
        .local PerlHash RESTOREINFO
        find_global RESTOREINFO, "RESTOREINFO"
        find_global $P0, "READPOINTER"
        set READPOINTER, $P0["value"]
  
        set READPOINTER, RESTOREINFO[where]
        
        set $P0["value"], READPOINTER
        store_global "READPOINTER", $P0
        restoreall
        ret
  .end
  
  .sub _get_little_endian # int get_little_endian(struct, offset, bytes)
        saveall
        .param ManagedStruct    struct
        .param int              offset
        .param int              bytes
        .local int              target
        set target, 0   
        eq bytes, 0, END
        add $I6, offset, bytes
  LOOP:   lt $I6, offset, END
        shl target, target, 8
        set $I3, struct[$I6]
        add target, target, $I3
        dec $I6
        branch LOOP
  END:    .return target
        restoreall
        ret
  .end
  .sub _set_little_endian       # void set_little_endian(struct, offset, bytes, value)
        saveall
        .param ManagedStruct struct
        .param int           offset
        .param int           bytes
        .param int           value
        add $I6, offset, bytes
        eq bytes, 0, END2
  LOOP2:  eq offset, $I6, END2
        band $I1, value, 255
        shr value, value, 8
        set struct[offset], $I1
        inc offset
        branch LOOP2
  END2:   restoreall
        ret
  
  .end
  
  
  

Reply via email to