Folders语言初探

一、Folders语言

1)Folders是一种以文件目录结构来编码的语言,它的编译器是一个C#程序,该C#编译程序通过将目录结构转换为C#代码,再调用C#编译器来实现编译。

2)Folders的详细介绍可以参考这篇资讯:http://www.oschina.net/news/60232/programming-language-folders

3)它翻译自这个页面:http://esoteric.codes/post/109310541818/folders-a-language-with-no-files

4)Folders语言的代码托管地址:https://github.com/rottytooth/Folders

本博客写于2015年3月9日,文中所列举的编译程序源码和内容都以此时间为准

二、语法规则

详细的语法规则可言参考(一)中的链接。

Folders可以用来打印文字,它有6个命令和4种数据类型。按文件夹名称升序执行考察各个文件夹,并根据读取的文件夹名称信息,将目录树的内容转换成C#代码。翻阅程序源码,在程序集“Rottytooth.Esolang.Folders.Runtime”下的文件“SpecialSymbols.cs”中,可以找到下面两个代码规则:

1)6个命令和4种数据类型,文件夹命名,对于这个字典来说,命名成键或命名成值都是等价的。用前后两种方式写的文件夹名称都会被识别。比如有一个文件夹名为“Downloads”,那编译时就会按“let”的规则处理,即赋值。

public static readonly Dictionary<string, string> AltCommandNames =
    new Dictionary<string, string>()
    {
        {"New folder", "if"},
        {"Temp", "while"},
        {"Images", "declare"},
        {"Downloads", "let"},
        {"Setup", "print"},
        {"Logs", "input"},

        {"Vaction photos", "int"},
        {"Lang", "float"},
        {"Img", "string"},
        {"User", "double"}
    };

这段代码定义了6个命令和4种数据类型的别名,需要注意的是:在网站的介绍页面上,int的别名是“Vacation photos”,但从代码来看,int的别名是“Vaction photos”,单词的字母不一样!这是一个很严重的陷阱,在官方给出例子“99 Bottles of Beer”中,使用的是int这种用法,很显然官方目前并没有发现“vacation”被错写成了“Vaction”。

2)转义字符,前者会在编译时被替换成后者。注意,C语言里的转义字符,除了“\n”为“&lf;”外,其他都是将转义字符中的“\”用“%5C;”代替,如“%5C;t”代表“\t”、“%5C;b”代表“\b”。

private static readonly Dictionary<string, string> SymbolList =
    new Dictionary<string, string>()
    {
        {"%2F;", "/"},
        {"%5C;", "\\"},
        {"%2A;", "*"},
        {"&lt;", "<"},
        {"&gt;", ">"},
        {"%20;", " "},
        {"&lf;", "\\n"},
        {"%2E;", "."}
    };

三、示例详解1:打印Hello, World!

从github上下载的代码,经过编译后,会生成一个可执行文件“Folders.exe”和一个动态链接库文件“Rottytooth.Esolang.Folders.Runtime.dll”,使用“Folders.exe”可以把指定的目录作为参数,编译出一个新的exe文件。“Hello, World!”是官方提供的最简单的程序示例,下图中的例子,先用tree命令显示了它的目录结构,再用Folders.exe对之进行编译。

编译完毕后,当前界面会出现两个新文件:“Hello World.exe”和“Hello World.pdb”,运行exe文件就可以看到“Hello, World!”字符了。

使用.NET自带的反编译工具ildasm将上面程序反编译成MSIL代码后可以看到,这个程序是一个标准的.NET程序:

被转化成的等价C#代码为:

using System;
using System.IO;
using Rottytooth.Esolang.Folders.Runtime;
public static class Program 
{
    private static VarManager _varManager;

    static Program() 
    {
        _varManager = new VarManager("Hello World");
    }

                
    public static void Main(string[] args) 
    {
        Console.Write("Hello".ToString() + ", ".ToString() + "World".ToString() + "!".ToString());
    }
}

四、示例详解2:字符串拼接

示例2建立了一个字符串(Img,即string)变量bigguy,并通过连接符“+”把3段文字(Img)拼接到一起并赋值(Downloads,即declare),最后用打印命令(Setup,即print)输出这段文字。目录结构和运行结果如下:

转换后的代码如下:

using System;
using System.IO;
using Rottytooth.Esolang.Folders.Runtime;
public static class Program
{

    private static VarManager _varManager;

    static Program()
    {
        _varManager = new VarManager("Long String");
    }

    public static string bigguy
    {
        get
        {
            return (string)_varManager.GetVariable("bigguy");
        }
        set
        {
            _varManager.SetVariable("bigguy", value);
        }
    }

    public static void Main(string[] args)
    {
        bigguy = "Call me Ishmael. Some years ago - never mind how long precisely - having little or no mon";
        bigguy = bigguy + "ey in my purse, and nothing particular to interest me on shor";
        bigguy = bigguy + "e, I thought I would sail about a little and see the watery part of the world";
        Console.Write(bigguy.ToString());
    }
}

五、示例详解3:使用循环(99个啤酒瓶)

创立一个执行99次的循环,目录“99 Bottles”的结构如下:

这段代码先声明了一个整型变量bottles赋值为99,然后将它放入到while循环中,每次循环它的值减1,当bottles值不再大于1时退出循环,再进行后面的步骤。

程序转换后的C#代码如下:

using System;
using System.IO;
using Rottytooth.Esolang.Folders.Runtime;
public static class Program
{

    private static VarManager _varManager;

    static Program()
    {
        _varManager = new VarManager("99 Bottles");
    }

    public static int bottles
    {
        get
        {
            return (int)_varManager.GetVariable("bottles");
        }
        set
        {
            _varManager.SetVariable("bottles", value);
        }
    }

    public static void Main(string[] args)
    {
        bottles = 99;
        Console.Write("99 bottles of beer on the wall, 99 bottles of beer.\n".ToString() + "Take one down, pass it around, ".ToString());
        while (bottles > 1)
        {
            bottles = bottles - 1;
            Console.Write(bottles.ToString() + " bottles of beer on the wall.\n\n".ToString() + bottles.ToString() + " bottles of beer on the wall, ".ToString() + bottles.ToString() + " bottles of beer.\nTake one down, pass it around, ".ToString());

        }
        Console.Write("1 bottle of beer on the wall.\n\n".ToString() + "1 bottle of beer on the wall, 1 bottle of beer.\n".ToString() + "Take one down, pass it around, no more bottles of beer on the wall.".ToString());
    }
}

六、我自己写的一个程序:打印九九乘法表

打印九九乘法表,我声明了3个变量:i、j、k,k用来存储每次迭代后i*j的值

目录结构为:

文件夹 PATH 列表
卷序列号为 00000002 BE8F:677A
C:\USERS\TSYBIUS\DESKTOP\9-9-TABLE
├─001 declare
│  ├─001 i
│  └─002 int
├─002 let
│  ├─001 i
│  └─1
├─003 declare
│  ├─001 j
│  └─002 int
├─004 let
│  ├─001 j
│  └─1
├─005 declare
│  ├─001 k
│  └─002 int
├─006 let
│  ├─001 k
│  └─1
└─007 while
    ├─001 i &lt; 10
    ├─002 let
    │  ├─001 j
    │  └─1
    ├─003 while
    │  ├─001 j &lt; i + 1
    │  ├─002 let
    │  │  ├─001 k
    │  │  └─002 i %2A; j
    │  ├─003 print
    │  │  ├─001 i
    │  │  ├─002 string
    │  │  │  └─%20;%2A;%20;
    │  │  ├─003 j
    │  │  ├─004 string
    │  │  │  └─%20;=%20;
    │  │  ├─005 k
    │  │  └─006 string
    │  │      └─%5C;t
    │  └─099 let
    │      ├─001 j
    │      └─002 j + 1
    ├─004 print
    │  └─001 string
    │      └─&lf;
    └─099 let
        ├─001 i
        └─002 i + 1

转换成的C#代码为

using System;
using System.IO;
using Rottytooth.Esolang.Folders.Runtime;
public static class Program
{

    private static VarManager _varManager;

    static Program()
    {
        _varManager = new VarManager("9-9-table");
    }

    public static int i
    {
        get
        {
            return (int)_varManager.GetVariable("i");
        }
        set
        {
            _varManager.SetVariable("i", value);
        }
    }

    public static int j
    {
        get
        {
            return (int)_varManager.GetVariable("j");
        }
        set
        {
            _varManager.SetVariable("j", value);
        }
    }

    public static int k
    {
        get
        {
            return (int)_varManager.GetVariable("k");
        }
        set
        {
            _varManager.SetVariable("k", value);
        }
    }

    public static void Main(string[] args)
    {
        i = 1;
        j = 1;
        k = 1;
        while (i < 10)
        {
            j = 1;
            while (j < i + 1)
            {
                k = i * j;
                Console.Write(
                    i.ToString() + " * ".ToString() + 
                    j.ToString() + " = ".ToString() + 
                    k.ToString() + "\t".ToString());
                j = j + 1;

            }
            Console.Write("\n".ToString());
            i = i + 1;
        }
    }
}

运行结果为:

七、Folders代码创作心得

1)最好先用C#代码实现一边想要的效果,将C#代码化减到分支结构仅使用if,循环结构仅使用while

2)创建新文件夹时要有一套自己的编号方式,防止语句顺序出现混乱的情况

END

时间: 2024-12-18 14:27:37

Folders语言初探的相关文章

GO语言初探

1.GO使用UTF-8编码,纯Unicode文本编写. 2.$ go verson (windows) 3.windows下,需要设置go语言的环境变量,新建一个名为 GOROOT的变量,指向go的具体目录,例如:C:\go\bin. 4.构建Go程序,需要进行编译和链接. 5.注释风格与C++相同,//和/**/. 6.main函数为入口,也是唯一的,每个Go程序必须包含的. 7.使用 import 导入相关的包. 8.支持常用的类型和操作符. 9.go语言中不适用分号结束,import导入多

Squirrel语言初探(可以使用VC6或者MinGW编译)

Squirrel语言初探 为啥我要关注Squirrel语言?原来Squirrel就很像我希望设计出的理想中的语言(当然也不完全符合).比如我觉得Lua的语法表述不清晰,累赘,于是想用C系语法来代替Lua语法,于是Squirrel实现了:比如Lua中没有类的结构,我想在我的语言里面加入类(基于表来实现),于是Squirrel实现了:比如我痛恨~=号,–[[–]]号,于是Squirrel也去掉了. 我并不是说Squirrel就是很牛逼的语言,只是感觉对自己有很强的参考价值.之前都不知道有这样一种语言

[java]java语言初探

<<head first java>>

go语言初探--一个helloworld编译出来有2.2M!

1. 安装, 用go的安装包安装好了go,终端敲下go,显示了go的help,看来go是没有交互界面的. 2. 新建个helloworld.go文件,写入 package main import "fmt" func main() { fmt.Println("hello world") } go run helloworld.go运行成功,打出了hello, world 3. 再试试编译,go build一下,helloworld可执行文件出现了, 本来我是很欣喜

Ruby学习之对象模型

这两周工作内容较多,平时自己也有点不在状态,学的东西有点少了,趁着现在还有点状态,赶紧复习一下之前学习的Ruby吧. Ruby是我真正开始接触动态语言魅力的第一个语言,之前虽然也用过且一直用perl.python等脚本语言,但是只是作为unix shell的扩展(和工作有关),没有真正地审视动态语言的哲学.是<Ruby元编程>这本书,好像给我打开了一扇新世界的大门,书中介绍的每一个特性都让我兴奋地几乎跳起来,这就是学习的魅力吧. Ruby语言初探 由于是第一个Ruby的随笔,先简单介绍一下ru

程序员2014精华本

<程序员2014精华本>基本信息作者: 程序员编辑部 出版社:电子工业出版社ISBN:9787121254710上架时间:2015-2-7出版日期:2015 年2月开本:16开页码:458版次:1-1   内容简介<程序员 2014 精华本>紧紧围绕大数据.电商架构.智能硬件.移动开发.团队管理等热门话题,进行了全面而深入的解读.于原有栏目和本年度热点,<程序员 2014 精华本>的结构分为以下七个篇章.专题篇:综合了 2014 年 1-12 月封面报道,内容包括双 1

C: printf参数执行顺序与前置后置自增自减的影响

起源: 今天在了解副作用side-effect的过程中,看到了下面的网页,把我带到了由printf引起的一系列问题,纠结了一整天,勉强弄懂. 第一个代码没什么好解释的.而第二个printf("return of swap is %d\tx=%d,y=%d\n",swap(&x,&y),x,y)居然是"return of swap is 1 x=1,y=0",输出的x和y的值并没有改变! 原因在于C语言函数参数的处理是从右到左的压栈顺序(这个我在看第一

python对象与json相互转换的方法

在网络通信中,json是一种常用的数据格式,对于python来讲,将类转化为json数据以及将json数据转化为对象是一件非常容易的事情. 下面给出两者转化的方法 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 # -*- coding: UTF-8 -*- import json   #自定义类 class MyClass:   #初始

C++中的三种继承方式

1,被忽略的细节: 1,冒号( :)表示继承关系,Parent 表示被继承的类,public 的意义是什么? 1 class Parent 2 { 3 4 }; 5 6 class Child : public Parent 7 { 8 9 }; 2,有趣的问题: 1,是否可以将继承语句中的 public 换成 protected 或者 private?如果可以,与 public 继承有什么区别? 3,有趣的尝试编程实验: 1 #include <iostream> 2 #include &l