前言

一直以来对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

转载于:https://www.cnblogs.com/bluedoctor/p/3604293.html

.NET DLR 上的IronScheme 语言互操作IronScheme控制台输入中文的问题相关推荐

  1. Java | Java语言在Eclipse控制台输入的三种方法

    写在前面的内容,java控制台输入浅尝辄止即可 >>> 文章目录 三种方法比较一览图 方法一:in/out public static final InputStream in//静 ...

  2. C语言 Clion 解决控制台输出中文乱码问题

    Ctrl + alt + s 调出设置 Editor → File Ecodings 参考 https://blog.csdn.net/zhy29563/article/details/1243591 ...

  3. python是最好的语言 永远二十岁_Python是世界上最好的语言吗?

    编程语言的选择是IT圈子永远的争议.在任意一个程序员聚集的场合,喊一句类似于"PHP是世界上最好的语言"这样的话,肯定会惹来不少人和你争论得面红耳赤.那么,python是世界上最好 ...

  4. 史上第一次,AI能够自学翻译地球上的任何语言了

    结合人工智能神经网络的机器翻译近年来取得了巨大的进步,以谷歌翻译为代表,足以让印象还停留在"生硬死板.破绽百出"的人惊讶万分.但是总体来说,也还是通过人类的已存翻译文本来学习. 结 ...

  5. php 7月世界排名2017,TIOBE2017榜单公布,PHP还会是世界上最好的语言吗?

    TIOBE 2017最新编程榜单 第1:java,第2:C,第3:C++....第6:php 看到这个榜单,我的记忆瞬间回到了十年前. 那时我结识了原配asp,asp代码真的好简单啊,看了遍<十 ...

  6. 为什么说python是世界上最好的语言-Python是世界上最好的语言 吗?

    编程语言的选择是IT圈子永远的争议.在任意一个程序员聚集的场合,喊一句类似于"PHP是世界上最好的语言"这样的话,肯定会惹来不少人和你争论得面红耳赤.那么,Python是世界上最好 ...

  7. JS是世界上最好的语言—— 使用Electron开发桌面应用(一)

    Electron 可以让你使用纯 JavaScript 调用丰富的原生(操作系统) APIs 来创造桌面应用. 你可以把它看作一个专注于桌面应用的 Node. js 的变体,而不是 Web 服务器. ...

  8. 用Visual Studio Code Debug世界上最好的语言(Mac篇)

    用Visual Studio Code Debug世界上最好的语言(Mac篇) 首先,你要有台Macbook Pro,接着才继续看这个教程. PS:Windows用户看这里用Visual Studio ...

  9. 在mac上安装Go语言初体验

    我将在mac os x的开发机器上安装go语言的开发环境. go语言运行包下载地址:http://code.google.com/p/go/downloads/list 这里我选择安装 go1.0.3 ...

最新文章

  1. KRIA SOM,赛灵思自适应计算最近一发“王炸”!
  2. 人工智能写的散文之白色月光下
  3. python类装饰器详解-Python 装饰器详解
  4. 【错误记录】GitHub 提交代码失败、获取代码失败、连接超时、权限错误、ping 请求连接超时 ( 查找域名对应 IP | 设置 host 文件 )
  5. Django1.6 用Form实现注册登录注销修改密码(含代码!)
  6. html 页面中的 base href 和 target
  7. 机器学习笔记(七)贝叶斯分类器
  8. Java设计模式透析之 —— 策略(Strategy)
  9. DevExpress VCL Controls v15.1.5正式发布[附下载]
  10. P7887-「MCOI-06」Existence of Truth【构造】
  11. mysql show db_mysql show操作
  12. 点钞视频软件测试,模拟银行综合实验
  13. 分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据
  14. C++ Code_StatusBar
  15. HDU 3732 Ahui Writes Word
  16. Alex 的 Hadoop 菜鸟教程: 第12课 Sqoop1 安装/导入/导出教程
  17. 用Java的swing递归画画谢尔宾斯基三角形
  18. 苹果开发者技术支持电话方式改变
  19. 洗牌-牛客 第一行一个数T(T ≤ 100),表示数据组数。对于每组数据,第一行两个数n,k(1 ≤ n,k ≤ 100),接下来一行有2n个数a1,a2,...,a2n(1 ≤ ai ≤ 1000
  20. cocos中如何让背景模糊_Cocos Creator Shader Effect 系列 - 8 - 高斯模糊

热门文章

  1. 约瑟夫环之循环链表实现
  2. 数据结构---各种树模板
  3. java HelloWorld 编程风格实践
  4. 临时整形变量溢出的问题
  5. 剑指offer九:变态跳台阶
  6. WebApi数据验证——编写自定义数据注解(Data Annotations)
  7. 【Nodejs篇一】Node js 简介
  8. 2017.5.23 -- 学习记录
  9. 分享:一个简单的线程池的实现
  10. 2009年的强悍流行语~