1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-04-05 03:37:43 +00:00

Ternary operators for PLASMA! And Floating point string conversion WIP

This commit is contained in:
David Schmenk 2017-11-18 15:27:50 -08:00
parent 09a54be674
commit a9bd3ebbeb
12 changed files with 251 additions and 19 deletions

View File

@ -36,7 +36,7 @@ import cmdsys
//
// CMD exported functions
//
predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1
predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1, toupper(c)#1
predef call(addr,areg,xreg,yreg,status)#1, syscall(cmd,params)#1
predef heapmark()#1, heapallocalign(size, pow2, freeaddr), heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0

View File

@ -753,19 +753,19 @@ end
//
def elemsLoad1(op, dst)#1
if loadElems
return sane[3](op, dst)
return sane[6](op, dst)
fin
return -1
end
def elemsLoad2(op, dst, src)#1
if loadElems
return sane[4](op, dst, src)
return sane[7](op, dst, src)
fin
return -1
end
def elemsLoad3(op, dst, src, src2)#1
if loadElems
return sane[4](op, dst, src, src2)
return sane[8](op, dst, src, src2)
fin
return -1
end

View File

@ -3,14 +3,173 @@
//
include "inc/cmdsys.plh"
include "inc/sane.plh"
struc t_decrecord
word sgn
word exp
byte sig[29]
end
struc t_decformat
word style
word digits
end
//
// Test values
//
word iA, iB, iC, zero, fpEnv
byte xT[t_extended]
word decrec = 0, 0
byte strA[28] = "10"
word decform = 0, 6
byte strNum = "-100.25"
byte strA[16]
//
// Parse string into decrecord
//
def str2ext(str, ext)
byte i, s, d
byte decrec[t_decrecord]
word sgnadj, expadj
decrec:sgn = 0
decrec:exp = 0
decrec.sig = 0
s = 1
i = 1
//
// Skip whitespace
//
while ^(str+i) <= ' ' and i <= ^str; i++; loop
//
// Check for sign
//
if ^(str+i) == '-'
decrec:sgn = 1
i++
elsif ^(str+i) == '+'
i++
fin
//
// Skip leading zeros
//
while i <= ^str and ^(str+i) == '0'
i++
loop
//
// Parse number
//
while i <= ^str
d = toupper(^(str+i))
if d >= '0' and d <= '9'
//
// Parse digit
//
decrec.sig[s] = ^(str+i)
decrec:sig++
s++
elsif d == '.'
//
// Parse decimal point
//
i++
while i <= ^str
d = toupper(^(str+i))
if d >= '0' and d <= '9'
decrec.sig[s] = ^(str+i)
decrec.sig++
decrec:exp--
s++
elsif d == 'E'
i--
break
else
i = ^str
fin
i++
loop
elsif d == 'E'
//
// Parse exponent
//
i++
expadj = 0
sgnadj = 1
if ^(str+i) == '-'
sgnadj = -1
i++
elsif ^(str+i) == '+'
i++
fin
while i <= ^str
d = ^(str+i)
if d >= '0' and d <= '9'
expadj = expadj * 10 + (d - '0')
else
i = ^str
fin
loop
decrec:exp = decrec:exp + (sgnadj * expadj)
else
i = ^str
fin
i++
loop
//
// Strip leading zeros from sig
//
while decrec.sig > 1 and decrec.sig.1 == '0'
decrec.sig--
if decrec:exp < 0
decrec:exp--
fin
memcpy(@decrec.sig.1, @decrec.sig.2, decrec.sig)
loop
//
// Check for zero
//
if !decrec.sig
decrec.sig = 1
decrec.sig.1 = '0'
fin
//putc(decrec.sgn ?? '-' :: '+'); puts(@decrec.sig); putc('e'); puti(decrec:exp); putln
return sane:fpOp2(FFEXT|FOD2B, ext, @decrec)
end
def ext2str(ext, str)
byte d, i, dp
byte decform[t_decformat]
byte decrec[t_decrecord]
decform:style = 1
decform:digits = 4
sane:fpOp3(FFEXT|FOB2D, @decrec, ext, @decform)
//putc(decrec.sgn ?? '-' :: '+'); puts(@decrec.sig); putc('e'); puti(decrec:exp); putln
i = 0
if decrec.sgn
^(str+1) = '-'
i = 1
fin
dp = decrec.sig + decrec:exp
for d = 1 to decrec.sig
i++
^(str+i) = decrec.sig[d]
if d == dp
i++
^(str+i) = '.'
fin
next
^str = i
return ^str
end
def divstri(strNum, denom)#0
byte strResult[16]
byte xResult[t_extended]
//
// Convert string to and from SANE
//
sane:zpSave()
str2ext(strNum, @xResult)
sane:fpOp2(FFINT|FODIV, @xResult, @denom) // Div int denom into ext Result
ext2str(@xResult, @strResult)
sane:zpRestore()
puts(strNum); putc('/'); puti(denom); putc('='); puts(@strResult); putln
end
//
// My custom SANE exception handler
//
@ -27,6 +186,7 @@ def myException(pstatus)
return pstatus=>4
end
iA = 3
iB = 4
iC = -1
@ -73,14 +233,8 @@ sane:fpOp2(FFINT|FOX2Z, @iC, @xT) // Convert ext T to int C
sane:zpRestore()
puti(iA); putc('/'); puti(zero); putc('='); puti(iC); putc('\n')
//
// Convert string to and from SANE
// String conversion tests
//
sane:zpSave()
sane:fpOp2(FFEXT|FOD2B, @xT, @decrec)
//sane:fpOp2(FFINT|FOZ2X, @xT, @iA) // Convert int A to ext T
sane:fpOp2(FFINT|FODIV, @xT, @iB) // Div int B into ext T
sane:fpOp2(FFINT|FOX2Z, @iC, @xT) // Convert ext T to int C
sane:fpOp3(FFEXT|FOB2D, @decrec, @xT, @decform)
sane:zpRestore()
puts("10 / 4 = "); puts(@strA); putc('e'); puti(decrec:2); putc('('); puti(iC); putc(')'); putln
divstri("-100.5", 4)
divstri("00.5", 2)
done

View File

@ -127,6 +127,10 @@ def dummy(zz)#0
return 0
end
def value1
return 1
end
puti(array[0]);putc(' ')
puti(array[1]);putc(' ')
puti(array[2]);putc(' ')
@ -161,4 +165,7 @@ putln
puts(@constr); puti(constval); putln
puts("Signed byte constant:"); puti(-3); putln
puts("Hello from in-line string!\$7F\n")
puts(1 ?? "This is TRUE\n" :: "This is FALSE\n")
puts(0 ?? "This is TRUE\n" :: "This is FALSE\n")
ptr = 0
done

View File

@ -1665,6 +1665,11 @@ int emit_pending_seq()
case BRTRUE_CODE:
emit_brtru(op->tag);
break;
case CODETAG_CODE:
printf("_B%03d%c\n", op->tag, LBL);
break;
case NOP_CODE:
break;
default:
return (0);
}

View File

@ -64,6 +64,8 @@ typedef struct _opseq {
#define BRNCH_CODE 0x031C
#define BRFALSE_CODE 0x031D
#define BRTRUE_CODE 0x031E
#define CODETAG_CODE 0x031F
#define NOP_CODE 0x0320
#define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0)
#define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0)
@ -83,6 +85,9 @@ typedef struct _opseq {
#define gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0)
#define gen_brfls(seq,tag) gen_seq(seq,BRFALSE_CODE,0,tag,0,0)
#define gen_brtru(seq,tag) gen_seq(seq,BRTRUE_CODE,0,tag,0,0)
#define gen_brnch(seq,tag) gen_seq(seq,BRNCH_CODE,0,tag,0,0)
#define gen_codetag(seq,tag) gen_seq(seq, CODETAG_CODE,0,tag,0,0)
#define gen_nop(seq) gen_seq(seq,NOP_CODE,0,0,0,0)
void emit_flags(int flags);
void emit_header(void);

View File

@ -388,6 +388,30 @@ t_token scan(void)
scanpos++;
}
break;
case ':':
if (scanpos[1] == ':')
{
scantoken = TRIELSE_TOKEN;
scanpos += 2;
}
else
{
scantoken = COLON_TOKEN;
scanpos++;
}
break;
case '?':
if (scanpos[1] == '?')
{
scantoken = TERNARY_TOKEN;
scanpos += 2;
}
else
{
scantoken = TERNARY_TOKEN;
scanpos++;
}
break;
default:
/*
* Simple single character tokens.

View File

@ -746,6 +746,32 @@ t_opseq *parse_expr(t_opseq *codeseq, int *stackdepth)
if (stackdepth)
(*stackdepth)--;
}
/*
* Look for ternary operator
*/
if (scantoken == TERNARY_TOKEN)
{
int tag_else, tag_endtri;
int stackdepth1;
if (*stackdepth != 1)
parse_error("Ternary op must evaluate to single value");
tag_else = tag_new(BRANCH_TYPE);
tag_endtri = tag_new(BRANCH_TYPE);
codeseq = gen_brfls(codeseq, tag_else);
codeseq = parse_expr(codeseq, &stackdepth1);
if (scantoken != TRIELSE_TOKEN)
{
parse_error("Missing '::' in ternary op");
return (NULL);
}
codeseq = gen_brnch(codeseq, tag_endtri);
codeseq = gen_codetag(codeseq, tag_else);
codeseq = parse_expr(codeseq, stackdepth);
if (stackdepth1 != *stackdepth)
parse_error("Inconsistent value counts in ternary op");
codeseq = gen_codetag(codeseq, tag_endtri);
}
return (codeseq);
}
t_opseq *parse_set(t_opseq *codeseq)

View File

@ -44,6 +44,11 @@
#define STRUC_TOKEN TOKEN(31)
#define CONTINUE_TOKEN TOKEN(32)
//#define EVAL_TOKEN TOKEN(32)
/*
* Ternary operand operators.
*/
#define TERNARY_TOKEN TOKEN('?')
#define TRIELSE_TOKEN TOKEN('_')
/*
* Double operand operators.
*/

View File

@ -31,7 +31,7 @@ const CFFAEntryPtr = $0B
// Pedefined functions.
//
predef syscall(cmd)#1, call(addr,areg,xreg,yreg,status)#1
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1
@ -74,6 +74,7 @@ byte putsstr[] = "PUTS"
byte putistr[] = "PUTI"
byte getcstr[] = "GETC"
byte getsstr[] = "GETS"
byte toupstr[] = "TOUPPER"
byte sysstr[] = "SYSCALL"
byte callstr[] = "CALL"
byte hpmarkstr[] = "HEAPMARK"
@ -99,6 +100,7 @@ word = @putsstr, @prstr
word = @putistr, @print
word = @getcstr, @cin
word = @getsstr, @rdstr
word = @toupstr, @toupper
word = @hpmarkstr, @markheap
word = @hpallocstr,@allocheap
word = @hpalignstr,@allocalignheap

View File

@ -25,7 +25,7 @@ const modinitkeep = $4000
// Pedefined functions.
//
predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1
@ -53,6 +53,7 @@ byte putsstr = "PUTS"
byte putistr = "PUTI"
byte getcstr = "GETC"
byte getsstr = "GETS"
byte toupstr = "TOUPPER"
byte hpmarkstr = "HEAPMARK"
byte hpalignstr = "HEAPALLOCALIGN"
byte hpallocstr = "HEAPALLOC"
@ -78,6 +79,7 @@ word = @putsstr, @prstr
word = @putistr, @print
word = @getcstr, @cin
word = @getsstr, @rdstr
word = @toupstr, @toupper
word = @hpmarkstr, @markheap
word = @hpallocstr,@allocheap
word = @hpalignstr,@allocalignheap

View File

@ -26,7 +26,7 @@ const O_READ_WRITE = 3
// Pedefined functions.
//
predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1
@ -71,6 +71,7 @@ byte putsstr[] = "PUTS"
byte putistr[] = "PUTI"
byte getcstr[] = "GETC"
byte getsstr[] = "GETS"
byte toupstr[] = "TOUPPER"
byte hpmarkstr[] = "HEAPMARK"
byte hpalignstr[] = "HEAPALLOCALIGN"
byte hpallocstr[] = "HEAPALLOC"
@ -95,6 +96,7 @@ word = @putsstr, @prstr
word = @putistr, @print
word = @getcstr, @cin
word = @getsstr, @rdstr
word = @toupstr, @toupper
word = @hpmarkstr, @markheap
word = @hpallocstr,@allocheap
word = @hpalignstr,@allocalignheap