singrdk/base/Applications/Lisp/Lisp.cs

136 lines
4.9 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Note: Simple Singularity test program.
//
using System;
using ProtoLisp;
using Microsoft.Singularity.Channels;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
2008-11-17 18:29:00 -05:00
namespace Microsoft.Singularity.Applications
{
2008-03-05 09:52:00 -05:00
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
2008-11-17 18:29:00 -05:00
[BoolParameter("d", Default=false, HelpMessage="Dump to debugger, no console pause")]
public bool debugMode;
2008-03-05 09:52:00 -05:00
[StringArrayParameter( "args", HelpMessage="arg bucket")]
internal string[] args;
reflective internal Parameters();
internal int AppMain() {
return Lisp.AppMain(this);
}
}
public class Lisp
{
2008-11-17 18:29:00 -05:00
private static bool debugMode;
2008-03-05 09:52:00 -05:00
// Returns true if the arguments were valid, false for illegal args
private static bool GetLispArgs(string[]! args, out bool helpArg, out bool traceArg, out string exprArg)
{
traceArg = false;
helpArg = false;
exprArg = "";
2008-11-17 18:29:00 -05:00
for (int i = 0; i < args.Length; ++i) {
2008-03-05 09:52:00 -05:00
string! args_i = (!)args[i];
2008-11-17 18:29:00 -05:00
if ((args_i.Length > 0) && (args_i[0] == '/')) {
2008-03-05 09:52:00 -05:00
string arg = args_i.Substring(1);
2008-11-17 18:29:00 -05:00
if (arg.Equals("trace")) {
2008-03-05 09:52:00 -05:00
traceArg = true;
continue;
}
2008-11-17 18:29:00 -05:00
else if (arg.Equals("help") || arg.Equals("?")) {
2008-03-05 09:52:00 -05:00
helpArg = true;
continue;
}
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
// A non-switch must be the last argument
2008-11-17 18:29:00 -05:00
if (i == (args.Length - 1)) {
2008-03-05 09:52:00 -05:00
exprArg = args_i;
continue;
}
}
// If we fall out, we have illegal arguments.
return false;
}
// If we didn't abort, everything was OK
return true;
}
internal static int AppMain(Parameters! config)
{
bool trace, help;
string expr;
2008-11-17 18:29:00 -05:00
debugMode = config.debugMode;
2008-03-05 09:52:00 -05:00
string[] args = config.args;
2008-11-17 18:29:00 -05:00
if (args == null || args.Length <= 0) {
WriteLine("ProtoLisp interpreter.");
WriteLine("Usage: lisp [flags] <lispexpression>");
WriteLine("Run \"lisp /help\" or \"lisp /?\" for more details");
2008-03-05 09:52:00 -05:00
return 0;
}
bool validUsage = GetLispArgs(args, out help, out trace, out expr);
2008-11-17 18:29:00 -05:00
if ((!validUsage) || (help)) {
WriteLine("ProtoLisp is an extremely basic Lisp-like interpreter.\n");
WriteLine("Usage: lisp [flags] LISPEXPRESSION\n");
WriteLine("Flags:");
WriteLine(" /? or /help : Print this message");
WriteLine(" /trace : Print verbose traces from the interpreter\n");
WriteLine("The following classic Lisp primitives are available:\n");
WriteLine(" atom, eq, car, cdr, cons, cond\n");
WriteLine("In addition,");
WriteLine(" - Variables are lexically scoped, not dynamically scoped.");
WriteLine(" - (define X Y) binds the name \"X\" to the value \"Y\"");
WriteLine(" in the global context");
WriteLine(" - (lambda (ARGLIST) (BODYEXPRESSION)) creates a \"closure\" by");
WriteLine(" capturing the ambient lexical scope.");
WriteLine(" - (defun NAME (ARGLIST) (BODYEXPR) is sugar for");
WriteLine(" (define NAME (lambda (ARGLIST) (BODYEXPR)))\n");
WriteLine(" - The arithmetic operators *, +, -, / are available. Math is");
WriteLine(" performed with integers.");
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
ProtoLisp.Engine engine = new ProtoLisp.Engine();
2008-11-17 18:29:00 -05:00
WriteLine(engine.EvalAll(expr, true, trace));
2008-03-05 09:52:00 -05:00
}
return 0;
}
2008-11-17 18:29:00 -05:00
private static void WriteLine(string s)
{
Console.WriteLine(s);
if (debugMode) {
DebugStub.WriteLine(s);
}
}
2008-03-05 09:52:00 -05:00
}
}