.NET DLR 上之IronScheme 语言互操作&&IronScheme控制高输入中文的题目

前言

直接以来对Lisp语言怀有那个敬重的心目,《黑客和画家》对Lisp更是推崇备至,虽然看了成千上万有关Lisp的介绍但都尚未机会错过形容段子先后试试,就比如自己本着C++一样,多少有硌敬畏。这个星期消费了成百上千工夫来钻Lisp。
Lisp是古的函数式语言,跟C,C++等命令式语言完全不相同的编程风格,但Lisp的白很多,最后Lisp标准委员制定了Common
Lisp,但内容非常丰富,有1000几近页,因此功能比较强硬;而Lisp的另外一个重中之重分就是Scheme,它的业内内容只有不顶100页,所以非常简单,适合学术研究和高校计算机语言教学和一般的工应用。目前Lisp有在JVM上的落实,在.NET上之实现即是
IronScheme,于是我就是开摘了IronScheme作为Lisp研究的率先站。

1,下载IronScheme源码

IronScheme在Codeplex上发开源项目, https://ironscheme.codeplex.com/
,可以下载它的源码和编译好的次第,在
https://ironscheme.codeplex.com/SourceControl/latest
可以下载源码,我下载上的文件称是
ironscheme-103684,下载的源码可以为此VS2008开辟。如果没有开条件,直接用
debugbuild.bat 也尽管可一直编译。另外还足以直接运行测试 r6rstest.bat

2,IronScheme控制台

每当网站及下载IronScheme的应用程序后,可以直接观看它们都提供了不同环境下之控制台程序,分别发64各类和32各类,.NET
2.0以及4.0之主次: IronScheme.Console32-v2.exe IronScheme.Console32-v4.exe
IronScheme.Console-v2.exe IronScheme.Console-v4.exe

2.1,执行Scheme程序

招来一个相宜的控制高运行下,输入几单Lisp表达式看看:

Lisp程序来一个原始之执行多个参数运算的特点,所以我们可以尽多独数字相加。也得以用
display 函数显示一个字符串。

2.2,中文乱码问题

写一个略的Hello 程序文件来加载 试试:

 执行是顺序,成功 ,但是乱码,不管是储存成
ANSI格式还是UTF8格式均乱码:

2.3,解决乱码

无奈,只有打开IronScheme源码进行解析,分析了要命悠久很久….

终极索性直接搜索编码格式 Encoding…,好歹涉及这重中之重词的地方只发3只:

于 IronScheme.Console 项目下之 Program 文件中,找到下面的代码:

 Encoding oo = Console.OutputEncoding;

      EnableMulticoreJIT();

      try
      {
          //Console.OutputEncoding = Encoding.UTF8;
        return IronSchemeConsoleHost.Execute(args);
      }
      finally
      {
        Console.OutputEncoding = oo;
      }

将原来的 Console.OutputEncoding =
Encoding.UTF8 注释即可,由于我之微处理器是汉语环境,这样程序即使以GBK的编码运行了,此时即可正常显示Scheme
程序中之
汉字。但是,如果如加载的公文称有字,则悲剧了,控制高无法输入汉字…

再次检查程序中兼有和控制台有关的编码的地方,发现除去前面检查了之编码问题,再为未尝其他地方,最后跟调试代码,发现先后下

Console.ReadKey()

办法来得到屏幕输入的,而以此方式,是心有余而力不足取得中文输入的…%&*….

 既然是收缴了键盘敲,那么我就算交一个特的键,按下其于弹窗出来一个窗口,在中输入中文即好了咔嚓,于是找到文件
SuperConsole.cs ,找到 Insert(ConsoleKeyInfo key)
方法,修改成下面的代码:

 private void Insert(ConsoleKeyInfo key) {
            char c;
            if (key.Key == ConsoleKey.F6)
            {
              Debug.Assert(FinalLineText.Length == 1);

              c = FinalLineText[0];
            }
            else if (key.Modifiers == ConsoleModifiers.Alt && (key.Key >= ConsoleKey.NumPad0 && key.Key <= ConsoleKey.NumPad9))
            {
              c = '?';
            }
            else
            {
              c = key.KeyChar;
            }
            //Ctrl+Z 输入汉字
            if (key.Key == ConsoleKey.Z && key.Modifiers == ConsoleModifiers.Control)
            {
                frmInputString frm = new frmInputString();
                frm.Activate();
                frm.ShowDialog();
                //Console.Write(frm.Text);
                string s = frm.Text;

                _input.Append(s);
                Output.Write(s);
                _rendered += s.Length;
                _current += s.Length;
            }
            else
            {
                Insert(c);
            }
        }

如此尽管可于Scheme控制台弹窗输入中文了,顺便在文件选择功能,方便加载程序文件,如图:

控制台默认的字是
“点阵字体”,这种书在输入中文后,Scheme 定位字符位置会来问题,应该采取非点阵字体,例如如下图的装置(控制高窗口标题–属性–字体):

3,Scheme 调用 .NET

依照
作者官方的传教,IronScheme是可以签入在.NET应用程序里面的,但是单独实施Scheme程序的下,是否可以调用
.net已有的程序也?这个IronScheme也提供了,下面是 https://ironscheme.codeplex.com/wikipage?title=clr-syntax&referringTitle=Documentation
页面的内容:

These macro’s are exported from the (ironscheme clr) library.

Common parameters

type is either:

  • a symbol. Eg: Int32 or System.IO.Stream
  • a list implying a generic type. Eg: (Action Int32)
  • #f (false) meaning the type should try to be inferred

Primary syntax

(clr-namespaces) Returns all the imported at the lexical scope
(clr-reference reference) reference can be a symbol for the
assembly short name (ie System.Web) or a string containing the fully
qualified assembly name.
(clr-using namespace) namespace is a symbol. Eg System.IO .
(clr-call type method instance arg ) method is a
symbol for a simple name, eg ToInt32 or a string to resolve specific
methods, eg “ToInt32(Object)” . instance is a reference to the object
of type . Can be null (‘()) for static
methods. arg is the arguments passed to the method.
(clr-cast type expr) expr is the instance to be cast.
(clr-is type expr) expr is the instance to be tested.
(clr-new type arg ) arg is the arguments passed to
the constructor.
(clr-new-array type size) size is the size of the array. Must
be an integer.
(clr-event-add! type  event instance handler) event is a
symbol for the name of the event. Eg Click . instance is a reference
to the object of type . Can be null (‘()) for static events. handler is a
procedure taking the same number of arguments as the event‘s
delegate.
(clr-event-remove! type  event instance handler) event is
a symbol for the name of the event. Eg Click . instance is a reference
to the object of type . Can be null (‘()) for static events. handler is a
procedure taking the same number of arguments as the event‘s
delegate.
(clr-field-get type field instance) field is a symbol for
the name of the field. Eg m_foo . instance is a reference to the
object of type . Can be null (‘()) for
static fields.
(clr-field-set! type field instance expr) field is a
symbol for the name of the field. Eg m_foo . instance is a reference
to the object of type . Can be null (‘()) for static fields. expr is the value to
set the field.
(pinvoke-call library method arg ) arg is the
arguments passed to the method.

Derived syntax

(clr-indexer-get type instance arg ) instance is a
reference to the object of type . arg is the arguments passed
to the indexer.
(clr-indexer-set! type instance arg expr) instance
is a reference to the object of type . arg is the arguments
passed to the indexer. expr is the value to set the indexer.
(clr-prop-get type property instance) property is the name
of the property. Eg Height . instance is a reference to the object of
type . Can be null (‘()) for static
properties.
(clr-prop-set! type property instance expr) property is
the name of the property. Eg Height . instance is a reference to the
object of type . Can be null (‘()) for
static properties. expr is the value to set the property.
(clr-static-call type method arg ) method is a symbol
for a simple name, eg ToInt32 or a string to resolve specific methods,
eg “ToInt32(Object)” . arg is the arguments passed to the
method.
(clr-static-event-add! type  event handler) event is a
symbol for the name of the event. Eg Click . handler is a procedure
taking the same number of arguments as the event‘s delegate.
(clr-static-event-remove! type  event handler) event is a
symbol for the name of the event. Eg Click . handler is a procedure
taking the same number of arguments as the event‘s delegate.
(clr-static-field-get type field) field is a symbol for the
name of the field. Eg m_foo .
(clr-static-field-set! type field expr) field is a symbol
for the name of the field. Eg m_foo . expr is the value to set the
field.
(clr-static-prop-get type property) property is the name of
the property. Eg Height .
(clr-static-prop-set! type property expr) property is the
name of the property. Eg Height . expr is the value to set the
property.

 

3.1,小试牛刀

看来支持得还老圆,马上写单程序试试看:

(import
  (rnrs)
  (ironscheme clr))

;Define a function write-ln
(define (write-ln fmt . args)
  (clr-static-call System.Console WriteLine (clr-cast System.String fmt)
    (clr-cast System.Object[]
      (list->vector args))))

; And invoke it!
(write-ln "{0}" "Hello World!")
(write-ln "1:{0}" "aaa")
(write-ln "1:{0} 2:{1}" "张三" "李四")

本条次是调用 .net的 Console.WriteLine 方法的,运行此程序试试:

在意程序文件需要保留也 UTF8格式的,IronScheme 才方可正常显示中文。

3.2,为是啊要为此 Scheme调用 .NET?

采取 Lisp的强大表达能力,调用.net强大的类库

Scheme可以作为脚本语言,可以.net程序动态变化一个
Scheme程序,Scheme程序还调用.net。。。。 这个过程的用处,明白了吧?

随工作流程序,调用一个Scheme 脚本..

 

参考资源

双重多之 Lisp,Scheme学习资源,可以参见下面的链接 :

Lisp 的一定的志
http://www.oschina.net/question/28_57183

Scheme语言–简介
http://blog.csdn.net/zzulp/article/details/5547729

学习Scheme
http://blog.csdn.net/ramacess/article/details/570769

 

Scheme 语言概要

http://www.ibm.com/developerworks/cn/linux/l-schm/index1.html

 

Read access to a .NET Assembly
https://ironscheme.codeplex.com/discussions/60977

Playing with IronScheme
http://www.codeproject.com/Articles/33050/Playing-with-IronScheme

尾递归

 http://blog.sina.com.cn/s/blog\_3e5694650100tzqq.html

 

正文程序下载 “IronScheme中文版”

http://pwmis.codeplex.com/releases/view/117822

 

———分界线 —————-

 欢迎使用 PDF.NET SOD
开源框架,框架追求的靶子是简单与频率的平衡,体现于:代码的简要,开发、维护的简单与追求极致之运作效率。

作者简介:

自现任职架构师,求伯乐,联系方式:http://www.pwmis.com/sqlmap