public static P5Scalar BitAnd(Runtime runtime, P5Scalar res, P5Scalar a, P5Scalar b) { if (a.IsString(runtime) && b.IsString(runtime)) { string sa = a.AsString(runtime), sb = b.AsString(runtime); System.Text.StringBuilder t; if (sa.Length > sb.Length) { t = new System.Text.StringBuilder(sa); for (int i = 0; i < sb.Length; ++i) t[i] &= sb[i]; } else { t = new System.Text.StringBuilder(sb); for (int i = 0; i < sa.Length; ++i) t[i] &= sa[i]; } res.SetString(runtime, t.ToString()); } else { // TODO take into account signed/unsigned? res.SetInteger(runtime, a.AsInteger(runtime) & b.AsInteger(runtime)); } return res; }
public static IP5Any DoFile(Runtime runtime, Opcode.ContextValues context, P5Scalar file) { var file_s = file.AsString(runtime); var ret = LoadFile(runtime, context, file_s); if (ret == null) return new P5Scalar(runtime); return ret; }
public static P5Scalar BitNot(Runtime runtime, P5Scalar value) { if (value.IsString(runtime)) { string svalue = value.AsString(runtime); var t = new System.Text.StringBuilder(svalue);; for (int i = 0; i < svalue.Length; ++i) t[i] = (char)(~t[i] & 0xff); // only ASCII for now return new P5Scalar(runtime, t.ToString()); } else { // TODO take into account signed/unsigned? return new P5Scalar(runtime, ~value.AsInteger(runtime)); } }
public static IP5Any RequireFile(Runtime runtime, Opcode.ContextValues context, P5Scalar file) { if (file.IsInteger(runtime) || file.IsFloat(runtime)) { var value = file.AsFloat(runtime); var version = runtime.SymbolTable.GetScalar(runtime, "]", false); var version_f = version.AsFloat(runtime); if (version_f >= value) return new P5Scalar(runtime, true); var msg = string.Format("Perl {0:F} required--this is only {1:F} stopped.", value, version_f); throw new P5Exception(runtime, msg); } var file_s = file.AsString(runtime); var inc = runtime.SymbolTable.GetHash(runtime, "INC", true); if (inc.ExistsKey(runtime, file_s)) return new P5Scalar(runtime, 1); var ret = LoadFile(runtime, context, file_s); if (ret == null) { var message = new System.Text.StringBuilder(); var inc_a = runtime.SymbolTable.GetArray(runtime, "INC", true); message.Append(string.Format("Can't locate {0:S} in @INC (@INC contains:", file_s)); foreach (var dir in inc_a) { message.Append(" "); message.Append(dir.AsString(runtime)); } message.Append(")"); throw new P5Exception(runtime, message.ToString()); } return ret; }
public static int Transliterate(Runtime runtime, P5Scalar scalar, string match, string replacement, int flags) { bool complement = (flags & Opcode.FLAG_RX_COMPLEMENT) != 0; bool delete = (flags & Opcode.FLAG_RX_DELETE) != 0; bool squeeze = (flags & Opcode.FLAG_RX_SQUEEZE) != 0; var s = scalar.AsString(runtime); int count = 0, last_r = -1; var new_str = new System.Text.StringBuilder(); for (int i = 0; i < s.Length; ++i) { int idx = match.IndexOf(s[i]); int replace = s[i]; if (idx == -1 && complement) { if (delete) replace = -1; else if (replacement.Length > 0) replace = replacement[replacement.Length - 1]; if (last_r == replace && squeeze) replace = -1; else last_r = replace; count += 1; } else if (idx != -1 && !complement) { if (idx >= replacement.Length && delete) replace = -1; else if (idx >= replacement.Length) replace = replacement[replacement.Length - 1]; else if (idx < replacement.Length) replace = replacement[idx]; if (last_r == replace && squeeze) replace = -1; else last_r = replace; count += 1; } else last_r = -1; if (replace != -1) new_str.Append((char)replace); } scalar.SetString(runtime, new_str.ToString()); return count; }
public static P5Scalar Oct(Runtime runtime, P5Scalar value) { var str = value.AsString(runtime); int start; for (start = 0; start < str.Length; ++start) if (!char.IsWhiteSpace(str[start])) break; // TODO warn about invalid octal digit return new P5Scalar(runtime, ParseBaseInteger(str, start, 8)); }
public static P5Scalar Negate(Runtime runtime, P5Scalar value) { if (value.IsString(runtime)) { string str = value.AsString(runtime); bool word = true; foreach (var c in str) { if (!(c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) { word = false; break; } } if (word) return new P5Scalar(runtime, "-" + str); } if (value.IsFloat(runtime)) return new P5Scalar(runtime, -value.AsFloat(runtime)); return new P5Scalar(runtime, -value.AsInteger(runtime)); }
public static bool IsDerivedFrom(Runtime runtime, P5Scalar value, IP5Any pack) { P5SymbolTable stash = value.BlessedReferenceStash(runtime); if (stash == null) stash = runtime.SymbolTable.GetPackage(runtime, value.AsString(runtime), false); string pack_name = pack.AsString(runtime); P5SymbolTable parent = runtime.SymbolTable.GetPackage(runtime, pack_name, false); if (parent == null || stash == null) return false; return stash.IsDerivedFrom(runtime, parent); }
public static P5Scalar Hex(Runtime runtime, P5Scalar value) { var str = value.AsString(runtime); // TODO warn about invalid hexadecimal digits return new P5Scalar(runtime, ParseBaseInteger(str, 0, 16)); }
public static IP5Regex CompileRegex(Runtime runtime, P5Scalar value, int flags) { if (value.IsReference(runtime)) { var rx = value.DereferenceRegex(runtime); if (rx != null) return rx; } if (runtime.NativeRegex) return new NetRegex(value.AsString(runtime)); else throw new System.Exception("P5: Needs compiler to recompile string expression"); }
public static P5Scalar Open3Args(Runtime runtime, P5Scalar target, string open_mode, P5Scalar value) { FileMode mode; FileAccess access; bool is_read = false, is_write = false, truncate = false; switch (open_mode) { case ">": mode = FileMode.OpenOrCreate; access = FileAccess.Write; is_write = truncate = true; break; case "<": mode = FileMode.Open; access = FileAccess.Read; is_read = true; break; case ">>": mode = FileMode.Append; access = FileAccess.Write; is_write = true; break; case "+>": mode = FileMode.OpenOrCreate; access = FileAccess.ReadWrite; is_read = is_write = truncate = true; break; case "+<": mode = FileMode.OpenOrCreate; access = FileAccess.ReadWrite; is_read = is_write = true; break; default: throw new P5Exception(runtime, string.Format("Unknown open() mode '{0}'", open_mode)); } FileStream filestream; try { filestream = new FileStream(value.AsString(runtime), mode, access); if (truncate) filestream.SetLength(0); } catch (IOException) { // TODO set $! return new P5Scalar(runtime, false); } // TODO handle encoding var handle = new P5Handle( runtime, is_read ? new StreamReader(filestream) : null, is_write ? new StreamWriter(filestream) : null); target.SetHandle(runtime, handle); return new P5Scalar(runtime, true); }