OSDN Git Service

This is the initial alpha version of localJS.
authorYoshi <Yoshi@MBPTM.local>
Wed, 27 Oct 2010 03:00:33 +0000 (14:00 +1100)
committerYoshi <Yoshi@MBPTM.local>
Wed, 27 Oct 2010 03:00:33 +0000 (14:00 +1100)
.DS_Store [new file with mode: 0644]
X11.c [new file with mode: 0644]
interpreter.c [new file with mode: 0644]
js.c [new file with mode: 0644]
js.h [new file with mode: 0644]
main.c [new file with mode: 0644]
makefile [new file with mode: 0644]
new.c [new file with mode: 0644]
test.js [new file with mode: 0644]
xaw.c [new file with mode: 0644]
xaw.h [new file with mode: 0644]

diff --git a/.DS_Store b/.DS_Store
new file mode 100644 (file)
index 0000000..05c330c
Binary files /dev/null and b/.DS_Store differ
diff --git a/X11.c b/X11.c
new file mode 100644 (file)
index 0000000..de5697e
--- /dev/null
+++ b/X11.c
@@ -0,0 +1,112 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/Command.h>
+
+typedef struct  /* XawのWidetを構造体として定義 */
+{
+       XtAppContext* Context;
+       int argc;
+       char **argv;
+       char* Name;
+       XtOrientation Direction;
+//     void (*CallbackFunction)( Widget w, XtPointer client, XtPointer called );
+} xawWindow;
+
+
+typedef struct  /* XawのWidetを構造体として定義 */
+{
+       char* Name;
+       WidgetClass Type;
+       Widget Parent;
+       char* Text;
+       int Width;//x
+       int Height;//y
+       int Left;//x
+       int Top;//y
+       int Border;
+       void (*CallbackFunction)( Widget w, XtPointer client, XtPointer called );
+} xawWidet;
+
+
+/* コールバック関数 */
+void Quit( Widget w, XtPointer client, XtPointer called )
+{
+       exit( 0 );
+}
+
+Widget createForm(Widget* form, xawWindow window)
+{
+       Widget top;
+
+       /* ツールキットの初期化 */
+       top = XtVaAppInitialize( window.Context, window.Name, NULL, 0, &window.argc, window.argv, NULL, NULL );
+       /*  クラス名       引数のリソース指定を解釈*/
+       /* 台紙ウィジットの作成 */            /* ウィジットクラス */
+       *form = XtVaCreateManagedWidget( "form", formWidgetClass, top, 
+                                   /* ウィジット名 */      /* 親ウィンドウ */
+                                                                  /* リソースの指定 */                XtNorientation, window.Direction,
+                                                                  /* いくつでもOKなので最後はNULL */  NULL );
+       return top;
+}
+
+Widget createControl(xawWidet widget)
+{
+       Widget control;
+       control = XtVaCreateManagedWidget( widget.Name, widget.Type, widget.Parent,
+                                                                  XtNlabel, widget.Text,
+                                                                  XtNwidth, widget.Width, XtNheight, widget.Height,
+                                                                       /* 縁取り */             XtNborderWidth, widget.Border,
+                                                                  /* 配置方法 */           XtNfromHoriz, NULL,
+                                                                  /* ウィンドウの左端から */  XtNhorizDistance, widget.Left,
+                                                                  /* ウィンドウの上端から */  XtNfromVert, NULL,
+                                                                                                                  XtNvertDistance, widget.Top,
+                                                                  NULL );
+       XtAddCallback( control, XtNcallback, widget.CallbackFunction, NULL );
+       return control;
+}
+
+int main( int argc, char **argv )
+{
+       
+       XtAppContext app_con;
+       Widget this, form, lab;
+       
+       //Windowのプロパティを設定
+       xawWindow window;
+       window.Context = &app_con;
+       window.argc = argc;
+       window.argv = argv;
+       window.Name = "Window";
+       window.Direction = XtorientVertical;
+       //Windowを指定したプロパティを基に作成
+       this = createForm(&form,window);
+
+       
+       xawWidet myLabel;
+       myLabel.Name = "lab";
+       myLabel.Type = labelWidgetClass;
+       myLabel.Parent = form;
+       myLabel.Text = "Athena Widget";
+       myLabel.Width = 150;//x
+       myLabel.Height = 20;//y
+       myLabel.Left = 0;//x
+       myLabel.Top = 0;//y
+       myLabel.Border = 0;
+       
+       createControl(myLabel);
+
+
+       xawWidet quit = {"quit",commandWidgetClass,form,"Quit",50,20,53,105,1,Quit};
+    createControl(quit);
+       /* 対象ウィンドウ     関数名 */
+       
+       XtRealizeWidget( this ); /* ウィンドウの具現化。これを呼ばないと表示もしない */
+       XtAppMainLoop( app_con ); /* メインループに突入 */
+       return 0;
+}
+
diff --git a/interpreter.c b/interpreter.c
new file mode 100644 (file)
index 0000000..19aa030
--- /dev/null
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ARG_ERR_MSG "Wrong argument. Aborting…\n"
+
+#include <JavascriptCore/JavascriptCore.h>//-framework JavaScriptCoreオプションを使用の事
+
+extern void functionLoader(JSGlobalContextRef ctx, JSObjectRef jobjGlobal);
+void classWrapper(JSGlobalContextRef ctx, JSObjectRef jobjGlobal, char* name, JSObjectRef* classObject);
+void functionWrapper(JSGlobalContextRef ctx, JSObjectRef parentObj, char* name, JSObjectCallAsFunctionCallback jsGlobalFunction);
+
+int interpreter(char* code)
+{
+#ifdef DEBUG
+    printf("JavaScript interpreter has been started.\n");
+#endif
+       
+#ifdef DEBUG
+    printf("Creating Global context..");
+#endif
+       
+    JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);
+       
+#ifdef DEBUG
+    printf("Done!\n");
+#endif
+       
+    // グローバル実行コンテキストが持つグローバルオブジェクトを取得する
+    // ブラウザでいうところの window オブジェクトのようなもの
+    JSObjectRef jobjGlobal = JSContextGetGlobalObject(ctx);
+       
+    functionLoader(ctx, jobjGlobal);
+       
+    // JavaScript のソースを JS の文字列にする
+    JSStringRef jstrSource = JSStringCreateWithUTF8CString(code);
+       
+#ifdef DEBUG
+    printf("JavaScript source is now ready to execute. Starting ..\n\n");
+#endif
+       
+    // 実行、 this を NULL とするとグローバルオブジェクトが this になるらしい
+    JSEvaluateScript(ctx, jstrSource, NULL, NULL, 1, NULL); 
+    // 文字列のリファレンスカウンタをデクリメント
+    JSStringRelease(jstrSource);
+       
+#ifdef DEBUG
+    printf("Script execution has came to the end. Terminating JavaScript instance ..\n");
+#endif
+       
+    // 解放許可?
+    JSGlobalContextRelease(ctx);
+    // 解放実行?EXC_BAD_ACCESSが来る。
+    //JSGarbageCollect(ctx);
+    return 0;
+       
+}
+
+void classWrapper(JSGlobalContextRef ctx, JSObjectRef jobjGlobal, char* name, JSObjectRef* classObject)
+{
+       //クラスの定義を保持する変数を作成
+       JSClassDefinition classDefinition       = kJSClassDefinitionEmpty;
+       //クラス型の変数を作成
+       JSClassRef classSubstance;
+       //クラスの名前を決定
+       classDefinition.className = name;
+       // プロトタイプ は 手動 で作成という事にする
+       classDefinition.attributes = kJSClassAttributeNoAutomaticPrototype; 
+       //クラス型を作成
+       classSubstance = JSClassCreate(&classDefinition);
+       //クラスをオブジェクト化
+       *classObject = JSObjectMakeConstructor(ctx, classSubstance, NULL);
+       //プロトタイプ継承
+       JSObjectSetPrototype(ctx, *classObject, JSObjectGetPrototype(ctx, jobjGlobal));
+       //クラスを持ったオブジェクトの名前を作る
+       JSStringRef jstr = JSStringCreateWithUTF8CString(name);
+       //クラスのオブジェクトをCTXに公開
+       JSObjectSetProperty(ctx, jobjGlobal, jstr, *classObject, kJSPropertyAttributeNone, NULL);
+       // 文字列のリファレンスカウンタをデクリメント
+    JSStringRelease(jstr);
+}
+
+void functionWrapper(JSGlobalContextRef ctx, JSObjectRef parentObj, char* name, JSObjectCallAsFunctionCallback jsGlobalFunction)
+{
+    // JavaScript で扱える文字列を作る
+    JSStringRef jstr = JSStringCreateWithUTF8CString(name);
+    // C の関数を JS の関数オブジェクトにする
+    JSObjectRef jfunc = JSObjectMakeFunctionWithCallback(ctx, jstr, jsGlobalFunction);
+       //プロトタイプ継承
+       JSObjectSetPrototype(ctx, jfunc, JSObjectGetPrototype(ctx, parentObj));
+    // オブジェクトのPrototypeのプロパティとして追加
+    JSObjectSetProperty(ctx, JSObjectGetPrototype(ctx, parentObj), jstr, jfunc, kJSPropertyAttributeNone, NULL);
+    // 文字列のリファレンスカウンタをデクリメント
+    JSStringRelease(jstr);
+}
\ No newline at end of file
diff --git a/js.c b/js.c
new file mode 100644 (file)
index 0000000..f4f0dd0
--- /dev/null
+++ b/js.c
@@ -0,0 +1,279 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "js.h"
+#ifdef ENABLE_GUI
+extern void functionLoader_Gui(JSGlobalContextRef ctx, JSObjectRef jobjGlobal);
+#endif
+
+/*+++++++++++宣言部ここまで+++++++++++++*/
+
+//-----関数登録機構-----
+
+void functionLoader(JSGlobalContextRef ctx, JSObjectRef jobjGlobal)
+{      
+       JSObjectRef Console;
+       classWrapper(ctx, jobjGlobal, "Console", &Console);
+//     functionWrapper(ctx, Console, "Write", (JSObjectCallAsFunctionCallback)jsGlobalPrint);
+       functionWrapper(ctx, Console, "Read", (JSObjectCallAsFunctionCallback)jsGlobalScan);
+#ifdef ENABLE_GUI
+    functionLoader_Gui(ctx, jobjGlobal);//(xaw.cを参照のこと。)
+#endif
+       functionWrapper(ctx, jobjGlobal, "print", (JSObjectCallAsFunctionCallback)jsGlobalPrint);
+       functionWrapper(ctx, jobjGlobal, "fopen", (JSObjectCallAsFunctionCallback)jsGlobalF_Open);
+       functionWrapper(ctx, jobjGlobal, "exec", (JSObjectCallAsFunctionCallback)jsGlobalExec);
+       functionWrapper(ctx, jobjGlobal, "call", (JSObjectCallAsFunctionCallback)jsGlobalCaller);
+       functionWrapper(ctx, jobjGlobal, "exit", (JSObjectCallAsFunctionCallback)jsGlobalExit);
+       functionWrapper(ctx, jobjGlobal, "test", (JSObjectCallAsFunctionCallback)jsGlobalTest);
+
+}
+
+//-------------------
+
+
+static JSValueRef jsGlobalCaller(
+                        JSContextRef        ctx,
+                        JSObjectRef         jobj,
+                        JSObjectRef         jobjThis,
+                        size_t              argLen,
+                        const JSObjectRef   args[],
+                        JSValueRef*         jobjExp) {
+
+
+       if (argLen) {
+        // 第一引数を JS の文字列としてコピー
+        JSStringRef     jstrArg = JSValueToStringCopy(ctx, args[0], jobjExp);
+        // 長さを取得
+        size_t          len     = JSStringGetMaximumUTF8CStringSize(jstrArg);
+        // 領域の確保
+        char*           szArg   =  (char*)malloc(len);
+        
+        JSStringGetUTF8CString(jstrArg, szArg, len);
+
+               callJsFunction(ctx, szArg);
+               
+        JSStringRelease(jstrArg);
+        // 解放
+        free(szArg);
+    }
+       
+    // undefined を作って返す
+    return JSValueMakeUndefined(ctx);
+}
+
+void callJsFunction(JSContextRef ctx, const char* func)
+{
+       JSStringRef jstrSource = JSStringCreateWithUTF8CString(func);
+       JSEvaluateScript(ctx, jstrSource, NULL, NULL, 1, NULL); 
+}
+
+char* execCmd(const char* cmd)
+{
+    char* buffer;
+    
+    size_t buffer_size = 0;
+    size_t buffer_capacity = 1024;
+    buffer = (char*)malloc(buffer_capacity);
+    
+    FILE* f = popen(cmd, "r");
+    if (!f) {
+        fprintf(stderr, "Err: %s\n", cmd);
+        return 0;
+    }
+    
+    while (!feof(f) && !ferror(f)) {
+        buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
+        if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
+            buffer_capacity *= 2;
+            buffer = (char*)realloc(buffer, buffer_capacity);
+        }
+    }
+    pclose(f);
+    buffer[buffer_size] = '\0';
+    
+    return buffer;
+}
+
+char* loadFile(const char* fileName)
+{
+    char* buffer;
+    
+    size_t buffer_size = 0;
+    size_t buffer_capacity = 1024;
+    buffer = (char*)malloc(buffer_capacity);
+    
+    FILE* f = fopen(fileName, "r");
+    if (!f) {
+        fprintf(stderr, "Could not open file: %s\n", fileName);
+        return 0;
+    }
+    
+    while (!feof(f) && !ferror(f)) {
+        buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
+        if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
+            buffer_capacity *= 2;
+            buffer = (char*)realloc(buffer, buffer_capacity);
+        }
+    }
+    fclose(f);
+    buffer[buffer_size] = '\0';
+    
+    return buffer;
+}
+/////////////////////TEST/////////////////////////
+static JSValueRef jsGlobalTest(
+                                                          JSContextRef        ctx,
+                                                          JSObjectRef         jobj,
+                                                          JSObjectRef         jobjThis,
+                                                          size_t              argLen,
+                                                          const JSObjectRef   args[],
+                                                          JSValueRef*         jobjExp)
+{
+    //dialogtest(g_argc, g_argv);
+    return JSValueMakeUndefined(ctx);
+}
+
+//////////////////////////////////////////////////
+
+static JSValueRef jsGlobalScan(
+                                                          JSContextRef        ctx,
+                                                          JSObjectRef         jobj,
+                                                          JSObjectRef         jobjThis,
+                                                          size_t              argLen,
+                                                          const JSObjectRef   args[],
+                                                          JSValueRef*         jobjExp) 
+{
+       //puts("avoid unknow error");
+    char*  str =  (char*)malloc(sizeof(char[256]));
+    scanf("%s",str);
+    JSStringRef mystring = JSStringCreateWithUTF8CString(str);
+    JSValueRef result = JSValueMakeString(ctx, mystring);
+    JSStringRelease(mystring);
+       free(str);
+       
+    return result;
+}
+
+static JSValueRef jsGlobalF_Open(
+                                                               JSContextRef        ctx,
+                                                               JSObjectRef         jobj,
+                                                               JSObjectRef         jobjThis,
+                                                               size_t              argLen,
+                                                               const JSObjectRef   args[],
+                                                               JSValueRef*         jobjExp) {
+
+    if (argLen) {
+        // 第一引数を JS の文字列としてコピー
+        JSStringRef     jstrArg = JSValueToStringCopy(ctx, args[0], jobjExp);
+        // 長さを取得
+        size_t          len     = JSStringGetMaximumUTF8CStringSize(jstrArg);
+        // 領域の確保
+        char*           szArg   =  (char*)malloc(len);
+        // 領域に UTF8 をコピー
+        JSStringGetUTF8CString(jstrArg, szArg, len);
+        // ファイル読み込み
+        JSStringRef mystring = JSStringCreateWithUTF8CString(loadFile(szArg));
+        JSValueRef result = JSValueMakeString(ctx, mystring);
+        //全て解放
+        free(szArg);
+        JSStringRelease(jstrArg);
+        JSStringRelease(mystring);
+
+        return result;
+    }
+
+    // undefined を作って返す
+    return JSValueMakeUndefined(ctx);
+}
+
+static JSValueRef jsGlobalExec(
+                                                                JSContextRef        ctx,
+                                                                JSObjectRef         jobj,
+                                                                JSObjectRef         jobjThis,
+                                                                size_t              argLen,
+                                                                const JSObjectRef   args[],
+                                                                JSValueRef*         jobjExp) {
+       
+    if (argLen) {
+        // 第一引数を JS の文字列としてコピー
+        JSStringRef     jstrArg = JSValueToStringCopy(ctx, args[0], jobjExp);
+        // 長さを取得
+        size_t          len     = JSStringGetMaximumUTF8CStringSize(jstrArg);
+        // 領域の確保
+        char*           szArg   =  (char*)malloc(len);
+        // 領域に UTF8 をコピー
+        JSStringGetUTF8CString(jstrArg, szArg, len);
+        // コマンド実行、結果読み取り
+        JSStringRef mystring = JSStringCreateWithUTF8CString(execCmd(szArg));
+        JSValueRef result = JSValueMakeString(ctx, mystring);
+        //全て解放
+        free(szArg);
+        JSStringRelease(jstrArg);
+        JSStringRelease(mystring);
+               
+        return result;
+    }
+       
+    // undefined を作って返す
+    return JSValueMakeUndefined(ctx);
+}
+
+
+static JSValueRef jsGlobalPrint(
+                                                               JSContextRef        ctx,
+                                                               JSObjectRef         jobj,
+                                                               JSObjectRef         jobjThis,
+                                                               size_t              argLen,
+                                                               const JSObjectRef   args[],
+                                                               JSValueRef*         jobjExp) {
+       
+    if (argLen) {
+        // 第一引数を JS の文字列としてコピー
+        JSStringRef     jstrArg = JSValueToStringCopy(ctx, args[0], jobjExp);
+        // 長さを取得
+        size_t          len     = JSStringGetMaximumUTF8CStringSize(jstrArg);
+        // 領域の確保
+        char*           szArg   =  (char*)malloc(len);
+        // 領域に UTF8 をコピー
+        JSStringGetUTF8CString(jstrArg, szArg, len);
+        // 出力
+        puts(szArg);
+        // 文字列のリファレンスカウンタをデクリメント
+        JSStringRelease(jstrArg);
+        // 解放
+        free(szArg);
+    }
+       
+    // undefined を作って返す
+    return JSValueMakeUndefined(ctx);
+}
+
+
+static JSValueRef makeException(JSGlobalContextRef ctx, char* ename)
+{
+       if (ename) {
+       JSStringRef jstrEx = JSStringCreateWithUTF8CString(ename);
+       
+       JSValueRef argumentsErrorValues[] = { JSValueMakeString(ctx, jstrEx) };
+       
+       JSObjectRef e = JSObjectMakeError(ctx, 1, argumentsErrorValues, NULL);
+       printf("Error: %s",ename);
+       
+       JSStringRelease(jstrEx);
+               return e;
+       }
+       
+       return JSValueMakeUndefined(ctx);
+}
+
+static JSValueRef jsGlobalExit(
+                                                                JSContextRef        ctx,
+                                                                JSObjectRef         jobj,
+                                                                JSObjectRef         jobjThis,
+                                                                size_t              argLen,
+                                                                const JSObjectRef   args[],
+                                                                JSValueRef*         jobjExp) {
+       
+       exit(0);
+    // undefined を作って返す
+    return JSValueMakeUndefined(ctx);
+}
diff --git a/js.h b/js.h
new file mode 100644 (file)
index 0000000..8646878
--- /dev/null
+++ b/js.h
@@ -0,0 +1,73 @@
+#ifndef JS_CONSOLE
+#define JS_CONSOLE
+
+#define ARG_ERR_MSG "Wrong argument. Aborting…\n"
+
+#include <JavascriptCore/JavascriptCore.h>//-framework JavaScriptCoreオプションを使用の事
+
+
+static JSValueRef jsGlobalPrint(
+                                                               JSContextRef        ctx,
+                                                               JSObjectRef         jobj,
+                                                               JSObjectRef         jobjThis,
+                                                               size_t              argLen,
+                                                               const JSObjectRef   args[],
+                                                               JSValueRef*         jobjExp);
+static JSValueRef jsGlobalScan(
+                                                          JSContextRef        ctx,
+                                                          JSObjectRef         jobj,
+                                                          JSObjectRef         jobjThis,
+                                                          size_t              argLen,
+                                                          const JSObjectRef   args[],
+                                                          JSValueRef*         jobjExp);
+static JSValueRef jsGlobalF_Open(
+                                                                JSContextRef        ctx,
+                                                                JSObjectRef         jobj,
+                                                                JSObjectRef         jobjThis,
+                                                                size_t              argLen,
+                                                                const JSObjectRef   args[],
+                                                                JSValueRef*         jobjExp);
+static JSValueRef jsGlobalExec(
+                                                          JSContextRef        ctx,
+                                                          JSObjectRef         jobj,
+                                                          JSObjectRef         jobjThis,
+                                                          size_t              argLen,
+                                                          const JSObjectRef   args[],
+                                                          JSValueRef*         jobjExp);
+/////TEST/////
+static JSValueRef jsGlobalTest(
+                                                          JSContextRef        ctx,
+                                                          JSObjectRef         jobj,
+                                                          JSObjectRef         jobjThis,
+                                                          size_t              argLen,
+                                                          const JSObjectRef   args[],
+                                                          JSValueRef*         jobjExp);
+/////////////
+static JSValueRef jsGlobalCaller(
+                                                                JSContextRef        ctx,
+                                                                JSObjectRef         jobj,
+                                                                JSObjectRef         jobjThis,
+                                                                size_t              argLen,
+                                                                const JSObjectRef   args[],
+                                                                JSValueRef*         jobjExp);
+static JSValueRef jsGlobalExit(
+                                                                JSContextRef        ctx,
+                                                                JSObjectRef         jobj,
+                                                                JSObjectRef         jobjThis,
+                                                                size_t              argLen,
+                                                                const JSObjectRef   args[],
+                                                                JSValueRef*         jobjExp);
+
+extern int interpreter(char* code);
+extern void functionWrapper(JSGlobalContextRef ctx, JSObjectRef jobjGlobal, char* name, JSObjectCallAsFunctionCallback jsGlobalFunction);
+extern void classWrapper(JSGlobalContextRef ctx, JSObjectRef jobjGlobal, char* name, JSObjectRef* classObject);
+extern int dialogtest( int argc, char **argv );
+extern int g_argc;
+extern char** g_argv;
+char* loadFile(const char* fileName);
+char* execCmd(const char* cmd);
+void callJsFunction(JSContextRef ctx, const char* func);
+void functionLoader(JSGlobalContextRef ctx, JSObjectRef parentObj);
+static JSValueRef makeException(JSGlobalContextRef ctx, char* ename);
+#endif
+
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..c375abf
--- /dev/null
+++ b/main.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ARG_ERR_MSG "Wrong argument. Aborting…\n"
+
+int interpreter(char* code);
+extern char* loadFile(const char* fileName);
+int g_argc;
+char** g_argv;
+/*+++++++++++宣言部ここまで+++++++++++++*/
+
+int main(int argc, char** argv)
+{
+       g_argc = argc;
+       g_argv = argv;
+    #ifdef DEBUG
+    printf("Program loaded.\n");
+    #endif
+
+    switch(argc)
+    {
+        case 1:
+            exit(0);
+            break;
+        case 2:
+            interpreter(loadFile(*(argv+1)));
+            break;
+        case 3:
+            if (!strcmp( argv[1], "-x" )){return interpreter(*(argv+2)); }
+            else{
+puts(ARG_ERR_MSG); return -1;}
+            break;
+        default:
+            puts(ARG_ERR_MSG);
+            break;
+    }
+       
+       return 0;
+
+}
+
diff --git a/makefile b/makefile
new file mode 100644 (file)
index 0000000..73d5edc
--- /dev/null
+++ b/makefile
@@ -0,0 +1,22 @@
+# Makefile
+CC = gcc
+TARGET = js_gui
+OBJECT = main.c js.c interpreter.c xaw.c
+DEBUG = no
+
+ifeq ($(DEBUG),yes)
+       DEF := -DDEBUG
+else
+       DEF :=
+endif
+
+LIB     = -L/usr/X11R6/lib -lXaw -lXmu -lXt -lX11
+FRAEMEWORK = -framework JavaScriptCore
+
+$(TARGET) : $(OBJECT)
+       @echo "*** Making $(TARGET) ***"
+       $(CC) -Wall -Os $(FRAEMEWORK) $(LIB) -DENABLE_GUI $(DEF) -g -o $(TARGET) $(OBJECT)
+
+
+js : main.c js.c interpreter.c
+       $(CC) -Wall -O3 $(FRAEMEWORK) $(LIB) $(DEF) $^ -o $@
\ No newline at end of file
diff --git a/new.c b/new.c
new file mode 100644 (file)
index 0000000..2c578ed
--- /dev/null
+++ b/new.c
@@ -0,0 +1,56 @@
+#include <string.h>
+
+
+static JSValueRef myWindowGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyNameJS, JSValueRef* exception)
+{
+       size_t          len     = JSStringGetMaximumUTF8CStringSize(propertyNameJS);
+       char*           propertyName   =  (char*)malloc(len);
+       JSStringGetUTF8CString(propertyNameJS, propertyName, len);
+       
+       JSValueRef returningValue = JSValueMakeUndefined(ctx);
+       
+       if (strcmp(propertyName, "Test") == 0)
+       {
+               return JSValueMakeNumber(ctx,  123);
+       }else if (strcmp(propertyName, "propertyName") == 0) {
+               return JSValueMakeNumber(ctx,  456);
+       }else {//不明な値の場合
+               JSStringRef string = JSStringCreateWithUTF8CString("Property not found.");
+               JSValueRef exceptionString =    JSValueMakeString(ctx, string);
+               JSStringRelease(string);
+               *exception = JSValueToObject(ctx, exceptionString, NULL);
+               return NULL;
+       }
+
+       free(propertyName);
+       return JSValueMakeUndefined(ctx);
+}
+
+void classMywindow(JSGlobalContextRef ctx, JSObjectRef jobjGlobal, JSObjectRef* classObject)
+{
+       //クラスの定義を保持する変数を作成
+       JSClassDefinition classDefinition       = kJSClassDefinitionEmpty;
+       //クラス型の変数を作成
+       JSClassRef classSubstance;
+       //クラスの名前を決定
+       classDefinition.className = name;
+       //クラスのコールバック関数
+       classDefinition.getProperty = myWindowGetProperty;
+       
+       
+       //プロトタイプは手動で作成という事にする
+       //classDefinition.attributes = kJSClassAttributeNoAutomaticPrototype; 
+       //クラス型を作成
+       classSubstance = JSClassCreate(&classDefinition);
+       //クラスをオブジェクト化
+       *classObject = JSObjectMakeConstructor(ctx, classSubstance, NULL);
+       //クラスを持ったオブジェクトの名前を作る
+       JSStringRef jstr = JSStringCreateWithUTF8CString(name);
+       //関数にしちゃう
+       JSValueRef jconst = JSObjectCallAsConstructor(ctx, *classObject, 0, NULL, NULL);
+       //クラスのオブジェクトをCTXに公開
+       JSObjectSetProperty(ctx, jobjGlobal, jstr, jconst, kJSPropertyAttributeNone, NULL);
+       //JSObjectCallAsConstructor(ctx,*classObject,0,NULL,NULL);
+       // 文字列のリファレンスカウンタをデクリメント
+    JSStringRelease(jstr);
+}
\ No newline at end of file
diff --git a/test.js b/test.js
new file mode 100644 (file)
index 0000000..a46576e
--- /dev/null
+++ b/test.js
@@ -0,0 +1,40 @@
+var quit = function(){
+exit();
+}
+var d = new Date();
+
+var mywindow = new xawWindow;
+
+mywindow.Name = "form";
+mywindow.Direction = 0;
+mywindow.SetProperty();
+
+
+var label = new xawControl;
+
+label.Type=0;
+label.Parent=mywindow;
+label.Text=d.toString();
+label.Width=150;
+label.Height=20;
+label.Left=0;
+label.Top=0;
+label.Border=0;
+label.Create();
+
+var label2 = new xawControl;
+
+label2.Type=1;
+label2.Parent=mywindow;
+label2.Text="Quit";
+label2.Width=150;
+label2.Height=20;
+label2.Left=0;
+label2.Top=20;
+label2.Border=0;
+label2.Callback = quit;
+
+label2.Create();
+
+
+mywindow.Show();
\ No newline at end of file
diff --git a/xaw.c b/xaw.c
new file mode 100644 (file)
index 0000000..72f2539
--- /dev/null
+++ b/xaw.c
@@ -0,0 +1,253 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "xaw.h"
+
+//***  Strong suggetion for mac users to overwrite Intrinsic.h  ***
+//***  Define Boolean as unsigned char  ***
+
+void functionLoader_Gui(JSGlobalContextRef ctx, JSObjectRef jobjGlobal);
+XtAppContext app_con;
+WidgetClass xawWidetTypes[] = {};
+XtOrientation xawOrientationDirection[]={XtorientHorizontal, XtorientVertical};
+
+
+Widget *myWidgets;
+xawWidet *myCtrls;
+int objIDc = 0;
+
+char* winName;
+
+/* コールバック関数 */
+void xawJsCallbackFunction( Widget w, XtPointer client, XtPointer called )
+{
+       int* myID;
+       winName = (char*)malloc(sizeof(char)*16);
+       winName = XtName(w);
+       
+       sscanf(winName,"%d",myID);
+       printf("%d",*myID);
+       JSObjectCallAsFunction(*(myCtrls[*myID].Context), *(myCtrls[*myID].CallbackFunction), NULL, 0,NULL,NULL);
+}
+
+Widget createForm(Widget* form, xawWindow window)
+{
+       Widget top;
+
+       /* ツールキットの初期化 */
+       top = XtVaAppInitialize( window.Context, window.Name, NULL, 0, &window.argc, window.argv, NULL, NULL );
+       /*  クラス名       引数のリソース指定を解釈*/
+       /* 台紙ウィジットの作成 */            /* ウィジットクラス */
+       *form = XtVaCreateManagedWidget( "form", formWidgetClass, top, 
+                                   /* ウィジット名 */      /* 親ウィンドウ */
+                                                                  /* リソースの指定 */                XtNorientation, window.Direction,
+                                                                  /* いくつでもOKなので最後はNULL */  NULL );
+       return top;
+}
+
+Widget createControl(xawWidet widget)
+{
+       myWidgets = (Widget *)realloc( myWidgets, sizeof(Widget)*(objIDc+2) );
+       if( myWidgets == NULL )//ポインタが空っぽだったら実行停止。
+       {
+               printf( "Memory re-allocation failed!\n" );
+               exit( 1 );
+       }
+       
+       
+       myWidgets[objIDc+2] = XtVaCreateManagedWidget( widget.Name, widget.Type, widget.Parent,
+                                                                  XtNlabel, widget.Text,
+                                                                  XtNwidth, widget.Width, XtNheight, widget.Height,
+                                                                       /* 縁取り */             XtNborderWidth, widget.Border,
+                                                                  /* 配置方法 */           XtNfromHoriz, NULL,
+                                                                  /* ウィンドウの左端から */  XtNhorizDistance, widget.Left,
+                                                                  /* ウィンドウの上端から */  XtNfromVert, NULL,
+                                                                                                                  XtNvertDistance, widget.Top,
+                                                                  NULL );
+       XtAddCallback( myWidgets[objIDc+2], XtNcallback, xawJsCallbackFunction, NULL );
+       objIDc++;
+       return myWidgets[objIDc+2];
+}
+
+static JSValueRef jsControlCreate(
+                                                                JSContextRef        ctx,
+                                                                JSObjectRef         jobj,
+                                                                JSObjectRef         jobjThis,
+                                                                size_t              argLen,
+                                                                const JSObjectRef   args[],
+                                                                JSValueRef*         jobjExp)
+{
+       JSValueRef r = JSValueMakeNumber(ctx,  -1);
+       
+       //name
+       //JSStringRef     jstrName = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Name"), jobjExp), jobjExp);
+       //size_t          len     = JSStringGetMaximumUTF8CStringSize(jstrName);
+       //char*           name   =  (char*)malloc(len);
+       //JSStringGetUTF8CString(jstrName, name, len);
+       //**********
+       
+       
+       //type
+       int typenum     = (int)JSValueToNumber(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Type"), jobjExp),NULL);   
+       WidgetClass type;
+       switch(typenum)
+       {
+                       case 0:
+                               type = labelWidgetClass;
+                               break;
+                       case 1:
+                               type = commandWidgetClass;
+                               break;
+       }
+       //*********
+       
+       //parent
+       int parentID    = (int)JSValueToNumber(ctx, 
+                                                                                  JSObjectGetProperty(ctx,
+                                                                                                                          JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Parent"), jobjExp),
+                                                                                                                       JSStringCreateWithUTF8CString("ID"),
+                                                                                                                       jobjExp),NULL); 
+       //-------
+       parentID++;
+       
+       //text
+       JSStringRef     jstrText = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Text"), jobjExp), jobjExp);
+       size_t len     = JSStringGetMaximumUTF8CStringSize(jstrText);
+       char*           text   =  (char*)malloc(len);
+       JSStringGetUTF8CString(jstrText, text, len);
+       //**********
+       
+       int W   = (int)JSValueToNumber(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Width"), jobjExp),NULL);  
+       int H   = (int)JSValueToNumber(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Height"), jobjExp),NULL); 
+       int L   = (int)JSValueToNumber(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Left"), jobjExp),NULL);   
+       int T   = (int)JSValueToNumber(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Top"), jobjExp),NULL);
+       int B   = (int)JSValueToNumber(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Border"), jobjExp),NULL);
+       
+
+       JSStringRef     jstrCallback = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Callback"), jobjExp), jobjExp);
+       len     = JSStringGetMaximumUTF8CStringSize(jstrCallback);
+       char*           func   =  (char*)malloc(len);
+       JSStringGetUTF8CString(jstrCallback, func, len);
+
+       myCtrls = (xawWidet *)realloc( myCtrls, sizeof(xawWidet)*(objIDc+2) );
+       if( myCtrls == NULL )//ポインタが空っぽだったら実行停止。
+       {
+               printf( "Memory re-allocation failed!\n" );
+               exit( 1 );
+       }
+       
+       char*           name   =  (char*)malloc(sizeof(char)*16);
+       sprintf(name, "%d", objIDc+2);
+       myCtrls[objIDc+2].Name = name;
+       //myCtrl.Name = name;
+       myCtrls[objIDc+2].Type = type;
+       myCtrls[objIDc+2].Parent = myWidgets[parentID];
+       myCtrls[objIDc+2].Text = text;
+       myCtrls[objIDc+2].Width = W;//x
+       myCtrls[objIDc+2].Height = H;//y
+       myCtrls[objIDc+2].Left = L;//x
+       myCtrls[objIDc+2].Top = T;//y
+       myCtrls[objIDc+2].Border = B;
+       myCtrls[objIDc+2].Context = ctx;
+       
+       
+       if(!JSValueIsUndefined(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Callback"), NULL)))
+       {
+               myCtrls[objIDc+2].CallbackFunction = JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Callback"), NULL);
+       }
+       
+       
+       
+       createControl(myCtrls[objIDc+2]);
+       r = JSValueMakeNumber(ctx,  objIDc);
+       JSObjectSetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("ID"), r, kJSPropertyAttributeNone, NULL);
+       return r;
+}
+
+static JSValueRef jsWindowCreate(
+                                JSContextRef        ctx,
+                                JSObjectRef         jobj,
+                                JSObjectRef         jobjThis,
+                                size_t              argLen,
+                                const JSObjectRef   args[],
+                                JSValueRef*         jobjExp)
+{
+       myWidgets = (Widget *)malloc( sizeof(Widget)*2 );
+       if( myWidgets == NULL )//ポインタが空っぽだったら実行停止。
+       {
+               printf( "Memory alloc failed!\n" );
+               exit( 1 );
+       }
+       xawWindow myWindow;
+       
+       JSValueRef r = JSValueMakeNumber(ctx,  -1);
+       //if(JSObjectIsConstructor(ctx, jobj))
+       
+        JSStringRef     jstrName = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Name"), jobjExp), jobjExp);
+        size_t          len     = JSStringGetMaximumUTF8CStringSize(jstrName);
+        char*           name   =  (char*)malloc(len);
+        JSStringGetUTF8CString(jstrName, name, len);
+               
+               myWindow.Context = &app_con;
+               myWindow.argc = g_argc;
+               myWindow.argv = g_argv;
+               myWindow.Name = name;
+               myWindow.Direction = (JSValueToBoolean(ctx, JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("Name"), jobjExp)))?XtorientVertical:XtorientHorizontal;
+               
+               myWidgets[objIDc] = createForm(&myWidgets[objIDc + 1], myWindow);
+               
+               
+               r = JSValueMakeNumber(ctx,  objIDc);
+               JSObjectSetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("ID"), r, kJSPropertyAttributeNone, NULL);
+       
+       objIDc ++;
+       
+       return r;
+}
+
+static JSValueRef jsWindowShow(
+                                                 JSContextRef        ctx,
+                                                 JSObjectRef         jobj,
+                                                 JSObjectRef         jobjThis,
+                                                 size_t              argLen,
+                                                 const JSObjectRef   args[],
+                                                 JSValueRef*         jobjExp)
+{
+       //jobjThis.ID
+       JSValueRef objID = JSObjectGetProperty(ctx, jobjThis, JSStringCreateWithUTF8CString("ID"), jobjExp);
+       
+       int windowID = (int)JSValueToNumber(ctx,objID,jobjExp);
+       XtRealizeWidget( myWidgets[windowID] );
+       XtAppMainLoop( app_con ); 
+}
+
+
+void functionLoader_Gui(JSGlobalContextRef ctx, JSObjectRef jobjGlobal)
+{
+       JSObjectRef Window, Widget;
+       printf("GUI has been enabled with this version.\nEnjoy!\n");
+       classWrapper(ctx, jobjGlobal, "xawWindow", &Window);
+       
+       JSObjectRef Window_Name, Window_Direction;
+       Window_Name = JSValueMakeString(ctx, JSStringCreateWithUTF8CString("undefined"));
+       JSObjectSetProperty(ctx, Window, JSStringCreateWithUTF8CString("Name"), Window_Name, kJSPropertyAttributeNone, NULL);   
+       JSObjectSetProperty(ctx, Window, JSStringCreateWithUTF8CString("Direction"), Window_Direction, kJSPropertyAttributeNone, NULL);
+       
+       functionWrapper(ctx, Window, "SetProperty", (JSObjectCallAsFunctionCallback)jsWindowCreate);
+       functionWrapper(ctx, Window, "Show", (JSObjectCallAsFunctionCallback)jsWindowShow);     
+       
+       classWrapper(ctx, jobjGlobal, "xawControl", &Widget);
+       functionWrapper(ctx, Widget, "Create", (JSObjectCallAsFunctionCallback)jsControlCreate);
+       JSObjectRef Control_Name, Control_Type, Control_Parent, Control_Text, Control_Width, Control_Height, Control_Left, Control_Top, Control_Border, Control_Callback;
+       Control_Name = JSValueMakeString(ctx, JSStringCreateWithUTF8CString("undefined"));
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Name"), Control_Name, kJSPropertyAttributeNone, NULL);  
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Type"), Control_Type, kJSPropertyAttributeNone, NULL);
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Parent"), Control_Parent, kJSPropertyAttributeNone, NULL);
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Text"), Control_Text, kJSPropertyAttributeNone, NULL);
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Width"), Control_Width, kJSPropertyAttributeNone, NULL);
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Height"), Control_Height, kJSPropertyAttributeNone, NULL);
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Left"), Control_Left, kJSPropertyAttributeNone, NULL);
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Top"), Control_Top, kJSPropertyAttributeNone, NULL);
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Border"), Control_Border, kJSPropertyAttributeNone, NULL);
+       JSObjectSetProperty(ctx, Widget, JSStringCreateWithUTF8CString("Callback"), Control_Callback, kJSPropertyAttributeNone, NULL);
+//     dialogtest(g_argc,g_argv);
+}
diff --git a/xaw.h b/xaw.h
new file mode 100644 (file)
index 0000000..da66342
--- /dev/null
+++ b/xaw.h
@@ -0,0 +1,46 @@
+#ifndef JS_XAW
+#define JS_XAW
+
+#include <X11/StringDefs.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/Command.h>
+#include "js.h"
+
+typedef struct  /* XawのWindowを構造体として定義 */
+{
+       XtAppContext* Context;
+       int argc;
+       char **argv;
+       char* Name;
+       XtOrientation Direction;
+} xawWindow;
+
+
+typedef struct  /* XawのWidetを構造体として定義 */
+{
+       char* Name;
+       WidgetClass Type;
+       Widget Parent;
+       char* Text;
+       int Width;//x
+       int Height;//y
+       int Left;//x
+       int Top;//y
+       int Border;
+       JSContextRef* Context;
+       JSValueRef* CallbackFunction;
+} xawWidet;
+
+typedef struct  /* XawのWidetを構造体として定義 */
+{
+       XtAppContext* Context;
+       int argc;
+       char **argv;
+       char* Name;
+       
+} jsXawContext;
+
+#endif