Extending Small Basic

The Small Basic compiler is designed to allow external libraries to be plugged in that enable it to be extended in interesting ways.  These libraries can be built using any .Net based language and compiled to a .Net assembly.  There are a few rules that the Small Basic compiler expects for a type to be identified as a Small Basic “object.” 

  1. The Type should be declared static
  2. The Type should be adorned with SmallBasicTypeAttribute
  3. Properties should be of type Microsoft.SmallBasic.Library.Primitive
  4. All the input and output parameters for Methods should be of type Microsoft.SmallBasic.Library.Primitive
  5. All events should be of type Microsoft.SmallBasic.Library.SmallBasicCallback

Once these conditions are met, you can compile your assembly and put it in a folder named “lib” in the Small Basic’s install location.  For example, if Small Basic was installed on your “c:” drive and your library was called “myextensions”, you’d have to put myextensions.dll inside “c:\program files\microsoft\small basic\lib” folder.

Optionally, you can enable XML documentation in your build and copy over the Doc Xml file along with the library.  This will automatically enable the help text inside Intellisense and the context help pane.

Here’s a sample extension (written in C#) that exposes a Settings object to Small Basic and lets you store and retrieve name value pairs specific to a program.

using System.Collections.Generic;

using System.IO;

using System.Reflection;

using System.Runtime.Serialization.Formatters;

using System.Runtime.Serialization.Formatters.Binary;

using Microsoft.SmallBasic.Library;

namespace MyExtensions

{

    /// <summary>

    /// The Settings library consists of helpers that allow programs to

    /// store and retrieve user settings.

    /// </summary>

    [SmallBasicType]

    public static class Settings

    {

        static Primitive _filePath = new Primitive();

        /// <summary>

        /// Gets the file path for the settings file.

        /// </summary>

        public static Primitive FilePath

        {

            get

            {

                if (string.IsNullOrEmpty(_filePath))

                {

                    _filePath = Path.ChangeExtension(

                                    Assembly.GetEntryAssembly().Location,

         ".settings");

                }

                return _filePath;

            }

        }

        /// <summary>

        /// Gets the value for the setting identified by the specified name.

        /// </summary>

        /// <param name="name">

        /// The Name of the setting.

        /// </param>

        /// <returns>

        /// The Value of the setting.

      /// </returns>

        public static Primitive GetValue(Primitive name)

        {

            if (System.IO.File.Exists(FilePath))

            {

                using (Stream stream = System.IO.File.Open(FilePath,

                                                           FileMode.Open))

                {

                    Dictionary<string, string> contents = ReadContents(stream);

                    if (contents.ContainsKey (name)) { return contents[name]; }

                }

            }

            return "";

        }

        /// <summary>

      /// Sets a value for a setting identified by the specified name.

        /// </summary>

        /// <param name="name">

        /// The Name of the setting.

        /// </param>

        /// <param name="value">

        /// The Value of the setting.

        /// </param>

        public static void SetValue(Primitive name, Primitive value)

        {

            Dictionary<string, string> contents = null;

            if (System.IO.File.Exists(FilePath))

            {

                using (Stream stream = System.IO.File.Open(FilePath,

                                                           FileMode.Open))

                {

                    contents = ReadContents(stream);

                }

            }

            else

            {

                contents = new Dictionary<string, string>();

            }

            contents[name] = value;

            using (Stream stream = System.IO.File.Open(FilePath,
                                                       FileMode.Create))

            {

                WriteContents(stream, contents);

            }

        }

        static Dictionary<string, string> ReadContents(Stream stream)

        {

            BinaryFormatter formatter = new BinaryFormatter();

            formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;

            return (Dictionary<string, string>)formatter.Deserialize(stream);

        }

        static void WriteContents(Stream stream, Dictionary<string, string> map)

        {

            BinaryFormatter formatter = new BinaryFormatter();

            formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;

            formatter.Serialize(stream, map);

        }

    }

}

 

Share your extensions in our forum.