static int Main(string[] args) { Env env = CreateTopLevelEnv(); List <Value> malArgs = new List <Value>(); for (int i = 1; i < args.Length; i++) { malArgs.Add(new Str(args[i])); } env.Set(Reader.AddSymbol("*ARGV*") as Symbol, new List(malArgs)); if (args.Length == 0) { return(Repl(env)); } #if NATIVE_LOAD_FILE FileInfo fi = new FileInfo(args[0]); if (fi.Exists) { using (Stream stream = fi.OpenRead()) LoadStream(stream, env); } else { Console.Error.WriteLine("ERROR: unable open file '{0}'", args[0]); return(1); } #else List loaderArgs = new List(new List <Value>() { new Str(args[0]) }); try { var val = env.Get(Reader.Load_file); if (val is Closure cls) { EVAL(cls.Body, cls.CreateEnv(loaderArgs)); } else if (val is Func_Native fn) { fn.Apply(loaderArgs); } else { throw new MalException("unknown function to evaluate file"); } } catch (MalException ex) { Console.Error.WriteLine("ERROR: {0}", ex.Message); return(1); } #endif return(0); }
protected override Value Apply_OneArg(Value arg) { if (arg is Str str) { string cstr = str.Value; if (string.IsNullOrEmpty(cstr)) { throw Error("non empty string is required"); } if (cstr.StartsWith(':')) { throw Error("invalid first character: ':'"); } for (int i = 0; i < cstr.Length; i++) { if (Reader.IsNonAtomChar(cstr[i])) { throw Error($"invalid character: '{cstr[i]}'"); } } if (Reader.IsInteger(cstr) || Reader.IsReal(cstr) || cstr == "true" || cstr == "false" || cstr == "nil") { throw Error($"invalid name for symbol: '{cstr}'"); } return(Reader.AddSymbol(cstr)); } throw Expected("string"); }
protected override Value Apply_OneArg(Value arg) { if (arg is Str str) { string cstr = str.Value; if (string.IsNullOrEmpty(cstr)) { throw Error("non empty string is required"); } for (int i = 0; i < cstr.Length; i++) { if (Reader.IsNonAtomChar(cstr[i])) { throw Error($"invalid character: '{cstr[i]}'"); } } return(cstr.StartsWith(':') ? Reader.AddSymbol(cstr) : Reader.AddSymbol(':' + cstr)); } if (arg is Keyword) { return(arg); } throw Expected("string/keyword"); }
static Env CreateTopLevelEnv() { Env env = new Env(); env.Set(Reader.AddSymbol("+") as Symbol, new Func_Add()); env.Set(Reader.AddSymbol("-") as Symbol, new Func_Sub()); env.Set(Reader.AddSymbol("*") as Symbol, new Func_Mul()); env.Set(Reader.AddSymbol("/") as Symbol, new Func_Div()); return(env); }