Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Actions pt 2
  • Loading branch information
sorear committed Jun 12, 2012
1 parent 49b8f85 commit 0b585f5
Showing 1 changed file with 49 additions and 10 deletions.
59 changes: 49 additions & 10 deletions lib/Actions.cs
Expand Up @@ -30,9 +30,16 @@ class Actions {
P6any pow(Variable v1,Variable v2) { return (P6any)Builtins.pow(v1,v2); }

// SSTO TODO integrate with parser
void sorry(string fmt, params object[] args) {
void sorry(Cursor m, string fmt, params object[] args) {
throw new NotImplementedException();
}
void trymop(Cursor m, Action a) {
try {
a();
} catch (Exception e) {
sorry(m, e.Message);
}
}

T ast<T>(Variable v) {
return (T)Kernel.UnboxAny<object>(((Cursor)v.Fetch()).ast);
Expand Down Expand Up @@ -62,7 +69,7 @@ class Actions {
// TODO Merge with the corresponding setting/runtime code?
// using p6numbers because we need bignum support here
// TODO Unicode
P6any from_base(Variable str, int based_) {
P6any from_base(Cursor m, Variable str, int based_) {
var acc = mkint(0);
var based = mkint(based_);
int punto = -1;
Expand All @@ -74,16 +81,16 @@ class Actions {
if (punto >= 0) punto++;
var digit = ch >= 'a' ? ((int)ch) - 87 : ((int)ch) - 48;
if (digit >= based_)
sorry("Digit <{0}> too large for radix {1}", ch, based_);
sorry(m, "Digit <{0}> too large for radix {1}", ch, based_);
acc = plus(mkint(digit), mul(based, acc));
}
return punto < 0 ? acc : div(acc, pow(based, mkint(punto)));
}

public void decint(Cursor m) { make(m,from_base(m, 10)); }
public void hexint(Cursor m) { make(m,from_base(m, 16)); }
public void octint(Cursor m) { make(m,from_base(m, 8)); }
public void binint(Cursor m) { make(m,from_base(m, 2)); }
public void decint(Cursor m) { make(m,from_base(m, m, 10)); }
public void hexint(Cursor m) { make(m,from_base(m, m, 16)); }
public void octint(Cursor m) { make(m,from_base(m, m, 8)); }
public void binint(Cursor m) { make(m,from_base(m, m, 2)); }
public void integer(Cursor m) {
Variable v = null;
if (isdef(v = atk(m, "decint")) || isdef(v = atk(m, "octint")) ||
Expand All @@ -101,7 +108,7 @@ class Actions {
// SSTO use the real number parser here
make(m, (P6any)Builtins.MakeFloat(
Utils.S2N(asstr(m).Replace("_",""))));
} else make(m,from_base(m,10));
} else make(m,from_base(m,m,10));
}

public void radint(Cursor m) {
Expand All @@ -121,11 +128,11 @@ class Actions {
new object[] { 10, radix.ToString() }), ast<Op.Op>(f)));
return;
}
var value = istrue(f=atk(m,"int")) ? from_base(f,radix) : mkint(0);
var value = istrue(f=atk(m,"int")) ? from_base(m,f,radix):mkint(0);

if (istrue(f = atk(m,"frac"))) {
var shift = asstr(f).Replace("_","").Length;
value = plus(value, div(from_base(f, radix),
value = plus(value, div(from_base(m, f, radix),
pow(mkint(radix), mkint(shift))));
}
if (istrue(f = atk(m,"base"))) {
Expand All @@ -136,5 +143,37 @@ class Actions {
}
make(m,value);
}

public void number(Cursor m) {
var child = atk(m,"integer");
if (!isdef(child)) child = atk(m,"dec_number");
if (!isdef(child)) child = atk(m,"rad_number");
object val;
if (!isdef(child)) {
val = asstr(m) == "NaN" ? double.NaN : double.PositiveInfinity;
} else {
val = ast<object>(child);
}
make(m, val is Op.Op ? val : new Op.Const(m,(P6any)val));
}

public void charname(Cursor m) {
var radint = atk(m,"radint");
string res;
if (istrue(radint)) {
var ast = ast<P6any>(radint);
int val = (int)Builtins.ToNum(ast);
if (!ast.Isa(Kernel.IntMO) || val < 0 || val > 0x10FFFF) {
res = " ";
sorry(m, "Numeric character identifiers must be integers between 0 and 0x10FFFF");
} else {
res = new string((char) val, 1);
}
} else {
res = " ";
trymop(m, () => { res = Niecza.UCD.DataSet.GetCodepoint(asstr(m)); });
}
make(m, mkstr(res));
}
}
}

0 comments on commit 0b585f5

Please sign in to comment.