2016年05月20日 (金) 01:38 | 編集
今日も適当にソースぽい投げ。
jsもモジュール化したし、もう大体使える。
あとはjsから返す値に型変換加えておきたいなぁ。
ただちょっと調べた感じだとtypeofはなかなか面倒臭そうだ。
jsもモジュール化したし、もう大体使える。
あとはjsから返す値に型変換加えておきたいなぁ。
ただちょっと調べた感じだとtypeofはなかなか面倒臭そうだ。
Option Explicit
Sub main()
Dim ask As Variant
ask = Array("hur_", "nara", 100)
Debug.Print nodefn("vbaret", ask, "30*80")
End Sub
Function nodefuncPath() As String
nodefuncPath = ThisWorkbook.Path
End Function
Function nodemain() As String
nodemain = "main.js"
End Function
Function nodefn(func As String, ParamArray args() As Variant) As Variant
Dim WSH As Object
Dim Command As String
Set WSH = CreateObject("WScript.Shell")
Dim i As Long
For i = 0 To UBound(args)
If 0 <= UBound(args) Then
If InStr(TypeName(args(i)), "()") Then
args(i) = Join(Array(Join(args(i), "$Array$"), TypeName(args(i)(0)) & "()"), ":")
Else
args(i) = Join(Array(args(i), TypeName(args(i))), ":")
End If
End If
Next
Const tempfile As String = "Temp$GIy0qPan"
WSH.CurrentDirectory = nodefuncPath
Command = Join(Array( _
"node ", nodemain, " " & func & IIf(0 <= UBound(args), " " & Join(args, " "), "") _
), "")
WSH.Run Join(Array("%ComSpec% /c ", Command, " > ", tempfile, " 2>&1 ", _
" & Echo %ErrorLevel% >>", tempfile), ""), 0, True '
If Dir(nodefuncPath & "\" & tempfile) = "" Then
Debug.Print "Error:結果の未取得"
Exit Function
End If
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim stream As Object
Set stream = fso.OpenTextFile(nodefuncPath & "\" & tempfile, 1)
Dim return_txt As String
return_txt = stream.ReadAll
Set stream = Nothing
Set fso = Nothing
Kill nodefuncPath & "\" & tempfile
Dim return_array As Variant
return_array = Split(Replace(Replace(return_txt, vbCrLf, vbLf), vbCr, vbLf), vbLf)
If return_array(UBound(return_array) - 1) = 0 Then
return_txt = ""
For i = 0 To UBound(return_array) - 2
return_txt = Join(Array(return_txt, return_array(i)), vbLf)
Next
return_txt = Mid(return_txt, 2)
If Not InStr(return_txt, "$ReturnArgs$") Then
nodefn = return_txt
Else
nodefn = Split(return_txt, "$ReturnArgs$")
End If
Else
For i = 0 To UBound(return_array) - 2
Debug.Print return_array(i)
Next
nodefn = Nothing
End If
Set WSH = Nothing
End Function
//process.argv=["","","vbaret", "daba:darr:string", "500:Integer"];
var nf=require("./nodefunc");
eval(nf.func());
function vbaret(x,y){
console.log(x);
console.log(y);
nf.return_VBA("Hello VBA!");
}
module.exports=new function(){
this.func=function(){
process.argv.shift();
process.argv.shift();
var runfunc=process.argv.shift()+"(";
var args="";
if(0<process.argv.length){
for(var i=0;i<process.argv.length;i++){
var arg=process.argv[i].split(/\:/);
var jstype=arg.pop();
var arg_str=arg.join("\:");
args+=","+typearray(jstype,arg_str);
}
args=args.substr(1);
}
runfunc+=args+")";
return runfunc;
};
this.return_VBA=x=>{console.log(""+x);process.exit();};
function typearray(jstype,arg_str){
if(/\(\)/.test(jstype)){
var arg_strs=arg_str.split("$Array$");
for(var i=0;i<arg_strs.length;i++){
arg_strs[i]=typecast(jstype.replace("()",""),arg_strs[i]);
}
return "["+arg_strs.join(",")+"]";
}
else {
return typecast(jstype,arg_str);
}
}
function typecast(jstype,arg_str){
switch(jstype.toLowerCase()){
case "byte":
case "integer":
case "long":
case "decimal":
case "currency":
return "parseInt("+arg_str+",10)";
case "single":
case "double":
return "parseFloat("+arg_str+")";
case "boolean":
return "!(Boolean("+arg_str+")||"+arg_str+".toLowerCase()=='false')";
case "date":
return Parse.date("date");
case "char":
case "string":
case "variant":
default:
return "'"+arg_str+"'";
}
}
};
2016年05月19日 (木) 00:27 | 編集
今日は時間がないので説明は略。
コンソールでてくるの嫌だからExec避けたいけど何かいい方法ないだろうか。
Runで普通にtxtファイル書かせるかなぁ…
なんにせよどうやって返り値を得るかが課題か。
コンソールでてくるの嫌だからExec避けたいけど何かいい方法ないだろうか。
Runで普通にtxtファイル書かせるかなぁ…
なんにせよどうやって返り値を得るかが課題か。
Sub main()
nodefunc "vbaret", "daba:darr:string", "10.54:number"
End Sub
Function nodefunc(func As String, ParamArray args() As Variant) As Variant
Dim WSH, wExec, sCmd As String, Result As String
Set WSH = CreateObject("WScript.Shell")
sCmd = "node C:\nc.js " & func & IIf(0 <= UBound(args), " " & Join(args, " "), "")
Set wExec = WSH.Exec("%ComSpec% /c " & sCmd)
Do While wExec.Status = 0
DoEvents
Loop
Result = wExec.StdOut.ReadAll & "hoge"
Debug.Print Result
Set wExec = Nothing
Set WSH = Nothing
End Function
var return_VBA=x=>{process.stdout.write(""+x);process.exit();};
process.argv.shift();
process.argv.shift();
var runfunc=process.argv.shift()+"(";
var args=""
if(0<process.argv.length){
for(var i=0;i<process.argv.length;i++){
var arg=process.argv[i].split(/\:/);
var jstype=arg.pop();
var arg_str=arg.join("\:");
if(jstype!=null){
switch(jstype.toLowerCase()){
case "int":
case "integer":
case "long":
arg_str="parseInt("+arg_str+",10)";
break;
case "single":
case "double":
case "number":
arg_str="parseFloat("+arg_str+")";
break;
case "bool":
case "boolean":
arg_str="!(Boolean("+arg_str+")||"+arg_str+".toLowerCase()==\"false\")";
break;
case "string":
arg_str="\""+arg_str+"\"";
default:
}
}
args+=","+arg_str;
}
args=args.substr(1);
}
runfunc+=args+")";
eval(runfunc);
function vbaret(x,y){
console.log(x);
console.log("y+30="+(y+30));
return_VBA("Hello VBA!");
}
2016年05月15日 (日) 19:43 | 編集
JavaScriptでよく見る怪しい挙動のこれ→(function(){})()
が他の言語でもどの程度可能なのか調べてみたら意外に出来たのでまとめておく。
まず、JavaScriptのテストケース
var print=console.log;
print((function(x){print(x);return x*x;})(5));
5
25
のように表示される。
ES6以降で、
var print=x=>console.log(x);
print((x=>{print(x);return x*x;})(5));
TypeScript
var puts:any=console.log;
puts(((x:number)=>{puts(x);return x*x;})(5));
Ruby
puts((->(x)do puts(x);return x*x end).(5))
Lua
print((function(x)print(x)return x*x end)(5))
R
print<-function(x)cat(x,"\n")
(function(){print((function(x){print(x);x*x})(5))})()
CommonLisp
(print((lambda(x)(print x)(* x x)) 5))
Clojure
(println((fn[x](println x)(* x x)) 5))
C#(scriptcs版)
Action<int> printi=x=>Console.WriteLine(x);
printi(new Func<int,int>(x=>{printi(x);return x*x;})(5));
VB.NET
module program
dim print as action(of object)=sub(x)Console.WriteLine(x)
sub main
print(ctype((function(x)
print(x):return x*x:end function),func(of long,long))(5))
end sub
end module
C#とVBは大分苦しいけど可能なことは可能らしい。
が他の言語でもどの程度可能なのか調べてみたら意外に出来たのでまとめておく。
まず、JavaScriptのテストケース
var print=console.log;
print((function(x){print(x);return x*x;})(5));
5
25
のように表示される。
ES6以降で、
var print=x=>console.log(x);
print((x=>{print(x);return x*x;})(5));
TypeScript
var puts:any=console.log;
puts(((x:number)=>{puts(x);return x*x;})(5));
Ruby
puts((->(x)do puts(x);return x*x end).(5))
Lua
print((function(x)print(x)return x*x end)(5))
R
print<-function(x)cat(x,"\n")
(function(){print((function(x){print(x);x*x})(5))})()
CommonLisp
(print((lambda(x)(print x)(* x x)) 5))
Clojure
(println((fn[x](println x)(* x x)) 5))
C#(scriptcs版)
Action<int> printi=x=>Console.WriteLine(x);
printi(new Func<int,int>(x=>{printi(x);return x*x;})(5));
VB.NET
module program
dim print as action(of object)=sub(x)Console.WriteLine(x)
sub main
print(ctype((function(x)
print(x):return x*x:end function),func(of long,long))(5))
end sub
end module
C#とVBは大分苦しいけど可能なことは可能らしい。
2016年05月15日 (日) 00:06 | 編集
FizzBuzz
たらい回し関数
構造体定義(クラスは不可)
速度的にはコンパイラとして一般的なくらい。
Node.jsより少し早いかなと言ったところ。
BASICは好きなのでおもちゃにするならいい感じ。
' FreeBasic '
sub main
for i as integer=0 to 100
if i mod 3=0 and i mod 5=0 then
print "Fizz Buzz"
elseif i mod 3=0 then
print "Fizz"
elseif i mod 5=0 then
print "Buzz"
else
print str(i)
end if
next
end sub
main
たらい回し関数
#Include "string.bi"
function tarai(x as long,y as long,z as long) as long
if x<=y then
return y
else
return tarai(tarai(x-1,y,z),tarai(y-1,z,x),tarai(z-1,x,y))
end if
end function
dim atime as double=timer
print tarai(12,6,0)
dim ztime as double=timer
print "Time:"&format(ztime-atime,"0.000")&"[s]"
dim ext as string
line input "",ext
構造体定義(クラスは不可)
type person
dim name as string
dim age as integer
end type
function person(myname as string,myage as integer) as person
dim mytype as person
mytype.name=myname
mytype.age=myage
return mytype
end function
sub main
dim student as person = person("bob",13)
dim teacher as person = person("john",30)
print "名前 : " & student.name
print "年齢 : " & student.age
print "名前 : " & teacher.name
print "年齢 : " & teacher.age
end sub
main
速度的にはコンパイラとして一般的なくらい。
Node.jsより少し早いかなと言ったところ。
BASICは好きなのでおもちゃにするならいい感じ。