/* Wyvern API. Copyright (C) 2019 Ariel Ortiz, ITESM CEM To compile this module as a DLL: mcs /t:library wyvernlib.cs To link this DLL to a program written in C#: mcs /r:wyvernlib.dll someprogram.cs This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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 along with this program. If not, see . */ using System; using System.Text; using System.Collections.Generic; namespace Wyvern { public class Utils { private static int currentHandleID = 0; private static Dictionary> handles = new Dictionary>(); //---------------------------------------------------------------------- // Prints i to stdout as a decimal integer. Does not print a new line // at the end. Returns 0. public static int Printi(int i) { Console.Write(i); return 0; } //---------------------------------------------------------------------- // Prints a character to stdout, where c is its Unicode code point. // Does not print a new line at the end. Returns 0. public static int Printc(int c) { Console.Write(char.ConvertFromUtf32(c)); return 0; } //---------------------------------------------------------------------- // Prints s to stdout as a string. s must be a handle to an array list // containing zero or more Unicode code points. Does not print a new // line at the end. Returns 0. public static int Prints(int s) { CheckHandle(s); StringBuilder builder = new StringBuilder(); for (int i = 0, n = Size(s); i < n; i++) { builder.Append(char.ConvertFromUtf32(Get(s, i))); } Console.Write(builder.ToString()); return 0; } //---------------------------------------------------------------------- // Prints a newline character to stdout. Returns 0. public static int Println() { Console.WriteLine(); return 0; } //---------------------------------------------------------------------- // Reads from stdin a signed decimal integer and return its value. Does // not return until a valid integer has been read. public static int Readi() { string input; int result; do { input = Console.ReadLine(); } while (!int.TryParse(input, out result)); return result; } //---------------------------------------------------------------------- // Reads from stdin a string (until the end of line) and returns a // handle to a newly created array list containing the Unicode code // points of all the characters read, excluding the end of line. public static int Reads() { string input = Console.ReadLine(); int handle = New(0); foreach (int i in AsCodePoints(input)) { Add(handle, i); } return handle; } //---------------------------------------------------------------------- // Creates a new array list object with n elements and returns its // handle. All the elements of the array list are set to zero. Throws // an exception if n is less than zero. public static int New(int n) { if (n < 0) { throw new Exception("Can't create a negative size array."); } int handle = currentHandleID++; handles.Add(handle, new List()); for (int i = 0; i < n; i++) { Add(handle, 0); } return handle; } //---------------------------------------------------------------------- // Returns the size (number of elements) of the array list referenced // by handle h. Throws an exception if h is not a valid handle. public static int Size(int h) { CheckHandle(h); return handles[h].Count; } //---------------------------------------------------------------------- // Adds x at the end of the array list referenced by handle h. // Returns 0. Throws an exception if h is not a valid handle. public static int Add(int h, int x) { CheckHandle(h); handles[h].Add(x); return 0; } //---------------------------------------------------------------------- // Returns the value at index i from the array list referenced by // handle h. Throws an exception if i is out of bounds or if h is not // a valid handle. public static int Get(int h, int i) { CheckHandle(h); return handles[h][i]; } //---------------------------------------------------------------------- // Sets to x the element at index i of the array list referenced by // handle h. Returns 0. Throws an exception if i is out of bounds or // if h is not a valid handle. public static int Set(int h, int i, int x) { CheckHandle(h); handles[h][i] = x; return 0; } //---------------------------------------------------------------------- // Local function that checks if h is a valid array list handle. private static void CheckHandle(int h) { if (!handles.ContainsKey(h)) { throw new Exception("Invalid array handle."); } } //---------------------------------------------------------------------- // Local function that allows obtaining all the individual Unicode code // points of a given string. private static IEnumerable AsCodePoints(string str) { for(int i = 0; i < str.Length; i++) { yield return char.ConvertToUtf32(str, i); if (char.IsHighSurrogate(str, i)) { i++; } } } } }