前言到此为止,确实做到了,首页地址:https://gscript.crossoverjie.top/index说是网站真的有点舍不得,不过它也是一个动态网页。因为返回的是HTML,所以只要现阶段不太麻烦,其实可以写出一个“合格”的网站,有点像我们以前学Java时的servlet。这个页面的源代码地址在这里:https://github.com/crossoverjie/gscript-homepage其实总共只有40行代码:classGScript{stringauthor;字符串[]特征;字符串自;GScript(字符串a,字符串[]f,字符串s){作者=a;特征=f;因为=小号;}}func(HttpContext)index(HttpContextctx){string[]features={"statically","strongly"};GScriptgs=GScript("crossoverJie",features,"2022");字符串j=JSON(gs);打印(j);stringlocal=getCurrentTime("亚洲/上海","2006-01-0215:04:05");println("本地="+本地);stringhtml=^
GScript______________|_|___||_|.|_-|_|_||.|_||_|___|___|_||_|_|_||___||_|v0.0.7^+j+^
当前^+local+^
^;ctx.HTML(200,html);}httpHandle("GET","/index",index);string[]args=getOSArgs();if(len(args)==3){httpRun(":"+args[2]);}else{httpRun(":8000");}都是使用GScript提供的标准库实现的,后面会详细讲到内置HTTP包的更新内容。下面重点说一下这个版本v0.0.8相比上一版本有哪些更新。因为我站在开发者的角度实现了一个http服务,还用GScript刷了两个简单的LeetCode;为了让这个过程更顺畅,更符合现代语言的使用方式,所以这次我真的更新了不少东西。刷题源码:https://github.com/crossoverJie/gscript/tree/main/example/leetcode大致如下:任意类型支持,简化了标准库的实现。可以用^^来声明多行字符串,方便声明复杂的字符串。更完整的类型推导,修复了上一版本某些情况下无法推导类型的bug。支持运算符重载。http基础包可以开发http服务,目前响应JSON和HTML。新增内置功能:根据时区获取当前时间、获取应用程序启动参数等。JSON序列表和查询,语法级别适配XJSON。修复嵌套多个块时无法正确返回的错误。其实从这些更新可以看出,之前的版本只是简单可用的状态,而现在这个版本可以用来写复杂的逻辑了。当然,还有一些比较友好的编译提示和运行时错误。让我们详细谈谈一些更新。any类型首先是any通用类型,类似于Java中的Object,Go中的interface{},极大的方便了我们编写一些标准库。以内置的hash和len函数为例,每个类型都实现一次,非常繁琐,没必要;现在只需要定义一次,代码量可以直接节省几倍。同样,之前实现的Map只支持string类型的存储,现在可以存储任意类型的数据。对any的实现过程感兴趣的朋友以后可以单独分享。运算符重载写go或者java的朋友应该知道,这两种语言都不能对两个对象进行操作,编译器会直接报错。但是在一些特殊的场景下还是比较好用的,所以我参考了C#的语法,用GScript来实现。人类{intage;Person(inta){年龄=a;}}Person运算符+(Personp1,Personp2){Personpp=Person(p1.age+p2.age);returnpp;}Personoperator-(Personp1,Personp2){Personpp=Person(p1.age-p2.age);returnpp;}Personp1=Person(10);Personp2=Person(20);Personp3=p1+p2;println("p3.age="+p3.age);assertEqual(p3.age,30);声明的函数名必须是operator,然后可以重载operator。支持的运算符有:+-*/<>=<=>==。JSON支持当前版本支持对象和基本类型的序列化,暂时不支持反序列化为对象,但可以根据JSON字符串通过一定的语法查询数据。两个内置的JSON相关函数://returnJSONstringstringJSON(anya){}//JSONquerywithpathanyJSONGet(stringjson,stringpath){}classPerson{intage;字符串名称;浮重;布尔人;Person(stringn,inta,floatw,boolm){name=n;年龄=一个;重量=w;男人=米;}}Personp1=Person("abc",10,99.99,true);Personp2=Person("a",11,999.99,false);stringjson=JSON(p1);println(json);//输出:{"age":10,"man":true,"name":"abc","weight":99.99}以这段代码为例,调用JSON函数将对象序列化为JSON字符串。人类{intage;字符串名称;浮重;布尔人;Person(stringn,inta,floatw,boolm){name=n;年龄=一个;重量=w;男人=米;}}Personp1=Person("abc",10,99.99,true);stringjson=JSON(p1);println(json);intage=JSONGet(json,"age");println(age);assertEqual(年龄,10);使用JSONGet函数查询JSON字符串中的任意数据。该功能是通过适配XJSON实现的,所以XJSON支持的所有查询语法都可以实现。stringj=^{"age":10,"abc":{"def":"def"},"list":[1,2,3]}^;Stringdef=JSONGet(j,"abc.def");println(def);assertEqual(def,"def");intl1=JSONGet(j,"list[0]");println(l1);assertEqual(l1,1);stringstr=^{"name":"bob","age":20,"skill":{"lang":[{"go":{"feature":["goroutine","channel","simple",true]}}]}}^;Stringg=JSONGet(str,"skill.lang[0].go.feature[0]");println(g);assertEqual(g,"goroutine");如此复杂的嵌套JSON,也可以通过查询语法获取数据。HTTP包HTTP包是本次升级的重点。标准库中提供了以下函数和类://httplib//ResponsejsonFprintfJSON(intcode,stringpath,stringjson){}//ResonsehtmlFprintfHTML(intcode,stringpath,stringhtml){}//路径(相对路径可以省略前导斜线)stringQueryPath(字符串路径){}stringFormValue(字符串路径,字符串键){}classHttpContext{字符串路径;JSON(intcode,anyv){stringjson=JSON(v);FprintfJSON(代码,路径,json);}HTML(intcode,anyv){stringhtml=v;FprintfHTML(代码,路径,html);}stringqueryPath(){stringp=QueryPath(路径);返回p;}stringformValue(stringkey){stringv=FormValue(path,key);返回v;}}//BindroutehttpHandle(stringmethod,stringpath,func(HttpContext)handle){//println("path="+path);HttpContextctx=HttpContext();handle(ctx);}//Runhttpserver.httpRun(stringaddr){}具体使用过程:通过定义一个函数变量自己的业务逻辑来实现。注册路线。启动HTTP服务。在自己的句柄中,可以通过HttpContext对象获取请求上下文,可以获取请求参数和响应数据。具体使用示例请参考此代码。总结一下,这次更新比我预想的要顺利,因为语法树和编译器已经基本实现了,不会有什么变化。现在的新特性无非是在运行时实现一些语法糖,大部分是手工劳动;可能是新奇感带来的兴奋作用,大部分时候是痛并快乐着的。比如这两天在修复多层块嵌套时遇到了return语句无法正确返回的bug。折腾了两个晚上;分析了无数次AST,终于找到了解决办法。现在想想,还是自己相关经验太少了。.对这个bug感兴趣的朋友可以点个赞,稍后分享。下一阶段的重点是整理好编译信息,让开发体验更好。然后花时间实现SQL标准库,这样你就可以享受CURD了。v0.0.8下载地址:https://github.com/crossoverJie/gscript/releases/tag/v0.0.8