Kernel FP已經(jīng)可以運(yùn)行小程序了。現(xiàn)在還處于測(cè)試階段,過(guò)于復(fù)雜的程序估計(jì)是跑不過(guò)的。先簡(jiǎn)單介紹一下如何在C++調(diào)用Kernel FP的代碼。
首先貼出一段Kernel FP的代碼:
1 module startup
2 import system
3
4 data maybe T = return T | error T
5
6 def add a b =
7 let
8 def xadd = iadd a b
9 in xadd
10
11 def foo a =
12 select a of
13 case 0 : return 100
14 case 1 : return 200
15 case 2 : return 300
16 else : error a
17 end
18
19 def translate a =
20 select a of
21 case return t : iadd 10000 t
22 case error t : iadd 1000 t
23 end
24
25 def main = translate (foo (add 1 2))
程序非常直白。add 1 2返回3,經(jīng)過(guò)foo選擇返回error 3,經(jīng)過(guò)translate變成iadd 1000 3,最后輸出1003。現(xiàn)在Kernel FP的對(duì)外api還沒(méi)寫(xiě),只是在調(diào)試內(nèi)核代碼。為什么只有iadd呢?因?yàn)槲抑粚?shí)現(xiàn)了iadd……其他的等以后再說(shuō)。先看看如何調(diào)用一個(gè)main函數(shù)。在沒(méi)有對(duì)外api的情況下,只能對(duì)內(nèi)核的對(duì)象進(jìn)行裸調(diào)……
1 void RunProgram(VL_KfpRuntimeProgram::Ptr Program)
2 {
3 VL_KfpRuntimeEnvironment Environment;
4 Environment.Program=Program;
5
6 MyPlugin Plugin(&Environment);
7 Environment.Plugins.Add(&Plugin);
8
9 VL_KfpRuntimeFunction* Function=&Program->Functions[Program->FunctionIDMap[L"startup.main"][0]];
10
11 VL_KfpRuntimeValueEnvironment ValueEnvironment;
12 ValueEnvironment.Environment=&Environment;
13 ValueEnvironment.SetTable(new VL_KfpRuntimeValueTable(new VL_KfpRuntimeValueTable(0,0),Function->Instance));
14
15 VL_KfpRuntimeExpression* Expression=Function->AssociatedExpression;
16 VL_KfpRuntimeValue* Value=Expression->CreateRuntimeValue(&ValueEnvironment);
17 Value->Increase();
18 VL_KfpRuntimeEvaluateResult Result;
19 Value->EvaluateUntilGetType(&Environment,Result);
20 if(Result.HasError)
21 {
22 GetConsole()->Write(L"發(fā)生錯(cuò)誤:"+Result.ErrorMessage+L"\r\n");
23 }
24 else
25 {
26 if(Result.Value.GetValue()->Kind==VL_KfpRuntimeValue::vkekInteger)
27 {
28 GetConsole()->Write(L"返回值:"+VUnicodeString(((VL_KfpRuntimeIntegerValue*)Result.Value.GetValue())->Data)+L"\r\n");
29 }
30 else
31 {
32 GetConsole()->Write(L"返回值不是整數(shù)。\r\n");
33 }
34 }
35 Value->Decrease();
36 }
首先程序經(jīng)過(guò)先前實(shí)現(xiàn)的類(lèi)型推導(dǎo),得到編譯后的程序VL_KfpRuntimeProgram,然后取出startup.main的函數(shù)指針。得到了函數(shù)指針之后,將函數(shù)的上下文和函數(shù)綁定的表達(dá)式都保存起來(lái),然后將表達(dá)式轉(zhuǎn)換為VL_RuntimeValue。最后對(duì)VL_RuntimeValue與上下文結(jié)合進(jìn)行求值。
當(dāng)然了,程序會(huì)調(diào)用到iadd,這是一個(gè)外部函數(shù),實(shí)現(xiàn)兩個(gè)整數(shù)的加法。所以還得實(shí)現(xiàn)一個(gè)插件來(lái)執(zhí)行iadd:
1 class MyPlugin : public VL_KfpRuntimePlugin
2 {
3 public:
4 VL_KfpRuntimeEnvironment* Environment;
5 VInt External_IAdd;
6
7 MyPlugin(VL_KfpRuntimeEnvironment* aEnvironment)
8 {
9 Environment=aEnvironment;
10
11 External_IAdd=Environment->Program->ExternalIDMap[L"kernelfp::iadd"];
12 }
13
14 VLE_KfpPluginResult Invoke(VInt ExternalID , InParams& In , OutParams& Out)
15 {
16 if(ExternalID==External_IAdd)
17 {
18 if(In.Parameters.GetCount()==2)
19 {
20 VL_KfpRuntimeEvaluateResult r1,r2;
21
22 In.Parameters[0].GetValue()->EvaluateUntilGetType(Environment,r1);
23 if(r1.HasError)
24 {
25 Out.ErrorMessage=r1.ErrorMessage;
26 return vkprFail;
27 }
28 if(r1.Value.GetValue()->Kind!=VL_KfpRuntimeValue::vkekInteger)
29 {
30 Out.ErrorMessage=L"iadd函數(shù)的參數(shù)必須是兩個(gè)int。";
31 return vkprFail;
32 }
33
34 In.Parameters[1].GetValue()->EvaluateUntilGetType(Environment,r2);
35 if(r2.HasError)
36 {
37 Out.ErrorMessage=r2.ErrorMessage;
38 return vkprFail;
39 }
40 if(r2.Value.GetValue()->Kind!=VL_KfpRuntimeValue::vkekInteger)
41 {
42 Out.ErrorMessage=L"iadd函數(shù)的參數(shù)必須是兩個(gè)int。";
43 return vkprFail;
44 }
45
46 VInt Value1=((VL_KfpRuntimeIntegerValue*)r1.Value.GetValue())->Data;
47 VInt Value2=((VL_KfpRuntimeIntegerValue*)r2.Value.GetValue())->Data;
48 Out.Result.SetValue(new VL_KfpRuntimeIntegerValue(Value1+Value2));
49 return vkprSuccess;
50 }
51 else
52 {
53 Out.ErrorMessage=L"iadd函數(shù)的參數(shù)必須是兩個(gè)int。";
54 return vkprFail;
55 }
56 }
57 else
58 {
59 return vkprPass;
60 }
61 }
62
63 VLE_KfpPluginResult GetParameterCount(VInt ExternalID , VInt& Count)
64 {
65 if(ExternalID==External_IAdd)
66 {
67 Count=2;
68 return vkprSuccess;
69 }
70 else
71 {
72 return vkprPass;
73 }
74 }
75 };
這也就是MyPlugin類(lèi)的內(nèi)容了。
posted on 2008-12-10 23:03
陳梓瀚(vczh) 閱讀(1716)
評(píng)論(2) 編輯 收藏 引用 所屬分類(lèi):
腳本技術(shù)