#region Copyright
// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (C) 2015 Ian Horswill
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in the
// Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// --------------------------------------------------------------------------------------------------------------------
#endregion
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace Prolog
{
///
/// A Lisp Symbol
///
[Documentation("The class of LISP symbols.")]
public sealed class Symbol : Term
{
#region Fields and Properties
///
/// The printed representation of the symbol
///
[SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
[Documentation("Printed representation of the symbol.")]
public readonly string Name;
///
/// The keyword name without the trailing colon.
///
[Documentation("The keyword name without the trailing colon.")]
public string KeywordName
{
get
{
return Name.TrimEnd(':');
}
}
///
/// True if this is a keyword symbol. Keywords are self-evaluating.
///
[Documentation("True if this is a keyword symbol, i.e. ends with a colon. Keywords are self-evaluating.")]
public bool IsKeyword
{
get
{
return Name.EndsWith(":");
}
}
///
/// True if this is a pattern variable.
///
[Documentation("True if this is a pattern variable, either in traditional lisp format (starts with a '?') or Prolog format (starts with a captial letter or '_').")]
public bool IsPatternVariable
{
get
{
return Name.StartsWith("?") || Name[0] == '_' || char.IsUpper(Name[0]);
}
}
#endregion
#region Printing
///
/// Prints the name of the symbol.
///
public override string ToString()
{
return Name;
}
#endregion
#region Interning and symbol table
static readonly Dictionary SymbolTable = new Dictionary();
///
/// Returns the symbol with the specified name.
/// Creates a new symbol if necessary, but always returns the same object
/// when called with the same string.
///
[Documentation("Returns the unique symbol iwth the specified name.")]
public static Symbol Intern(string name)
{
Symbol s;
SymbolTable.TryGetValue(name, out s);
if (s != null)
return s;
// Constructor adds to symbol table automatically
return new Symbol(name);
}
///
/// True if the string names a symbol in the symbol table. Does not intern a new symbol.
///
/// Name of the symbol to search for
/// True if there is a symbol by that name.
public static bool IsInterned(string name)
{
return SymbolTable.ContainsKey(name);
}
#endregion
#region Constructor - private -
Symbol(string name)
{
//Prolog allows null atoms, alas.
//System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(name));
Name = name;
SymbolTable[name] = this;
}
#endregion
#region Unification
internal override IEnumerable UnifyWithTerm(Term value)
{
return value.UnifyWithAtomicConstant(this);
}
internal override bool UnifyWithTerm(Term value, PrologContext context)
{
return value.UnifyWithAtomicConstant(this, context);
}
#endregion
#region Symbol constants
///
/// The symbol 'quote
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Quote = Intern("quote");
///
/// The symbol 'quasiquote
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Quasiquote")]
public static readonly Symbol Quasiquote = Intern("quasiquote");
///
/// The symbol 'unquote
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Unquote = Intern("unquote");
///
/// The symbol 'unquote-splicing
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol UnquoteSplicing = Intern("unquote-splicing");
///
/// The symbol 'lambda
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Lambda = Intern("lambda");
///
/// The symbol 'member
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Member = Intern("member");
///
/// The symbol 'macroexpand
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Macroexpand")]
public static readonly Symbol Macroexpand = Intern("macroexpand");
///
/// The symbol 'else
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Else = Intern("else");
///
/// The symbol 'if
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol If = Intern("if");
///
/// The symbol 'begin
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Begin = Intern("begin");
///
/// The symbol 'set!
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol SetBang = Intern("set!");
///
/// The symbol 'define
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Define = Intern("define");
///
/// The symbol 'let
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Let = Intern("let");
///
/// The symbol 'new
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol New = Intern("new");
///
/// The symbol 'not
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Not = Intern("not");
///
/// The symbol 'list
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol List = Intern("list");
///
/// The symbol 'append
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Append = Intern("append");
///
/// The symbol 'this
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol This = Intern("this");
///
/// The symbol 'stack
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Stack = Intern("stack");
///
/// The symbol '...
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Ellipsis = Intern("...");
///
/// The symbol 'Object
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Object = Intern("Object");
///
/// The Prolog symbol ','
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Comma = Intern(",");
///
/// The symbol '='
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol EqualSign = Intern("=");
///
/// The Prolog symbol '|'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol VerticalBar = Intern("|");
///
/// The Prolog symbol ':-'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Implication = Intern(":-");
///
/// The Prolog symbol '.'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol PrologListConstructor = Intern("cons");
///
/// The Prolog symbol '.'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Dot = Intern(".");
///
/// The Prolog symbol '!'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Cut = Intern("!");
///
/// The Prolog symbol 'call'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Call = Intern("call");
///
/// The Prolog symbol 'fail'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Fail = Intern("fail");
///
/// The Prolog symbol 'true'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol True = Intern("true");
///
/// The Prolog symbol '{}'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol CurlyBrackets = Intern("{}");
///
/// The Prolog symbol '-->'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol GrammarRule = Intern("-->");
///
/// The Prolog symbol '$'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol DollarSign = Intern("$");
///
/// The Prolog symbol 'end_of_file'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol EndOfFile = Intern("end_of_file");
///
/// The division symbol, '/'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Slash = Intern("/");
///
/// The grammar rule predicate indicator symbol, '//'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol SlashSlash = Intern("//");
///
/// The symbol 'maplist'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol MapList = Intern("maplist");
///
/// The Prolog symbol ';'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Semicolon = Intern(";");
///
/// The Prolog symbol '->'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol IfThenArrow = Intern("->");
///
/// The Prolog symbol ':'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Colon = Intern(":");
///
/// The Prolog symbol 'global'
///
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Symbol Global = Intern("global");
///
/// The Prolog symbol '-'
///
public static readonly Symbol Minus = Intern("-");
///
/// The Prolog symbol '::'
///
public static readonly Symbol ColonColon = Intern("::");
///
/// The Prolog symbol '::'
///
public static readonly Symbol Text = Intern("text");
#endregion
}
}