From 3bb280ba1d0686723ed2ac823d0fac0b1f54d976 Mon Sep 17 00:00:00 2001 From: hinus Date: Mon, 13 Jul 2020 19:15:49 +0800 Subject: [PATCH] =?UTF-8?q?Summary:=20=E5=9B=BE=E5=BD=A2=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20Issue:=20https://gitee.com/hinus/HiLang/is?= =?UTF-8?q?sues/I1MP3N=20Description:=201.=20=E5=85=88=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E7=AA=97=E5=8F=A3=EF=BC=8C=E8=BF=99=E4=B8=AA?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E4=BB=80=E4=B9=88=E4=B9=9F=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E5=B9=B2=E3=80=82=202.=20=E5=8F=AA=E6=94=AF=E6=8C=81windows?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F;=20linux=E4=B8=8A=E5=87=86=E5=A4=87=E4=BD=BF?= =?UTF-8?q?=E7=94=A8X11=E6=9D=A5=E5=81=9A=E3=80=82=20LLT:=20win.hi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.sh | 3 +- src/main/parser/parselib/rgmarshal.py | 11 ++- src/main/vm/CMakeLists.txt | 10 +- src/main/vm/extlib/draw_def.hi | 34 +++++++ src/main/vm/extlib/hidraw.cpp | 111 +++++++++++++++++++++ src/main/vm/extlib/hidraw.hpp | 16 +++ src/main/vm/extlib/math.cpp | 34 +++---- src/main/vm/inc/railgun.hpp | 13 ++- src/main/vm/os/windows/hidraw_win.cpp | 129 +++++++++++++++++++++++++ src/main/vm/runtime/functionObject.cpp | 12 +++ src/main/vm/runtime/functionObject.hpp | 1 + src/main/vm/runtime/interpreter.cpp | 6 +- src/main/vm/runtime/module.cpp | 10 +- src/main/vm/runtime/module.hpp | 2 + src/test/hilang/win.hi | 29 ++++++ 15 files changed, 392 insertions(+), 29 deletions(-) create mode 100644 src/main/vm/extlib/draw_def.hi create mode 100644 src/main/vm/extlib/hidraw.cpp create mode 100644 src/main/vm/extlib/hidraw.hpp create mode 100644 src/main/vm/os/windows/hidraw_win.cpp create mode 100644 src/test/hilang/win.hi diff --git a/build.sh b/build.sh index d42758b..9f25f3b 100755 --- a/build.sh +++ b/build.sh @@ -36,7 +36,7 @@ function build_vm() { if [[ $ENV_NAME == "Linux" ]] || [[ $ENV_NAME == "Darwin" ]] ; then cmake ${VM_SRC_PATH} -G "Unix Makefiles" elif [[ $ENV_NAME == "MINGW" ]]; then - cmake ${VM_SRC_PATH} -G "MinGW Makefiles" + cmake ${VM_SRC_PATH} -DCMAKE_BUILD_TYPE=Debug -G "MinGW Makefiles" fi $MAKE all post_make @@ -47,6 +47,7 @@ function post_make() { cd ${VM_BUILD_PATH} mkdir -p lib cp libmath.$DLL_POSTFIX lib/ + cp libdraw.$DLL_POSTFIX lib/ cp ${VM_SRC_PATH}/lib/*.py lib/ $PYTHON2 -m compileall lib/ } diff --git a/src/main/parser/parselib/rgmarshal.py b/src/main/parser/parselib/rgmarshal.py index 858087a..69fba82 100644 --- a/src/main/parser/parselib/rgmarshal.py +++ b/src/main/parser/parselib/rgmarshal.py @@ -66,5 +66,12 @@ def dump_dict(x, data): data.extend(len(x).to_bytes(4, "little")) for k, v in x.items(): - dump_element(k) - dump_element(v) + dump_element(k, data) + dump_element(v, data) + +def dump_list(x, data): + data.append(ord('(')) + data.extend(len(x).to_bytes(4, "little")) + + for item in x: + dump_element(item, data) diff --git a/src/main/vm/CMakeLists.txt b/src/main/vm/CMakeLists.txt index 02fdb28..b5850e2 100644 --- a/src/main/vm/CMakeLists.txt +++ b/src/main/vm/CMakeLists.txt @@ -61,13 +61,21 @@ elseif (WIN32) message(STATUS "cmake for windows") add_definitions(-DRAILGUN_WINDOWS) set(SOURCE_FILE ${SOURCE_FILE} ${WINDOWS_FILE}) + set(DRAW_SRC_MD os/windows/hidraw_win.cpp) endif () # libhivm ADD_LIBRARY(hivm SHARED ${SOURCE_FILE}) # libmath ADD_LIBRARY(math SHARED extlib/math.cpp) +# libdraw +ADD_LIBRARY(draw SHARED extlib/hidraw.cpp + ${DRAW_SRC_MD}) TARGET_LINK_LIBRARIES(hivm -ldl) TARGET_LINK_LIBRARIES(math hivm) -TARGET_LINK_LIBRARIES(railgun hivm math) + +find_package(OpenGL REQUIRED) +TARGET_LINK_LIBRARIES(draw hivm ${OPENGL_LIBRARIES}) + +TARGET_LINK_LIBRARIES(railgun hivm) diff --git a/src/main/vm/extlib/draw_def.hi b/src/main/vm/extlib/draw_def.hi new file mode 100644 index 0000000..28fbf1f --- /dev/null +++ b/src/main/vm/extlib/draw_def.hi @@ -0,0 +1,34 @@ +class Window(object) { + QUIT = 0x12; + + func __init__(self, native_pnt) { + self.native_pnt = native_pnt; + self.events = list(); + } + + func get_canvas(self) { + return Canvas(self); + } + + func add_event(self, evt) { + self.events.append(evt); + } +} + +class Canvas(object) { + func __init__(self, win) { + self.window = win; + } + + # some native methods; + # draw_line; + # update; +} + +class Event(object) { + func __init__(self, etype, eparam1, eparam2) { + self.type = etype; + self.par1 = eparam1; + self.par2 = eparam2; + } +} \ No newline at end of file diff --git a/src/main/vm/extlib/hidraw.cpp b/src/main/vm/extlib/hidraw.cpp new file mode 100644 index 0000000..b89b79c --- /dev/null +++ b/src/main/vm/extlib/hidraw.cpp @@ -0,0 +1,111 @@ +#include "inc/railgun.hpp" +#include "extlib/hidraw.hpp" + +#include +#include + +#ifdef RAILGUN_WINDOWS +#include +#endif + +HiObject* create_window(ObjList args) { + return create_window_md(args); +} + +HiObject* window_get_events(ObjList args) { + HiObject* events = Universe::HiNone; +#ifdef RAILGUN_WINDOWS + MSG msg; + for (int i = 0; i < 100; i++) { + if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if (msg.message == WM_QUIT) { + HiList* lst = HiList::new_instance(1); + lst->append(new HiInteger(WM_QUIT)); + return lst; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else { + return events; + } + } +#endif + return events; +} + +double get_double(HiTuple* args, int index) { + HiObject* x = args->get(index); + double y = 0; + if (x->klass() == IntegerKlass::get_instance()) { + y = ((HiInteger*)x)->value(); + } + else if (x->klass() == DoubleKlass::get_instance()) { + y = ((HiDouble*)x)->value(); + } + return y; +} + + +HiObject* canvas_draw_line(ObjList args) { + HiTuple* p1 = (HiTuple*)args->get(1); + HiTuple* p2 = (HiTuple*)args->get(2); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + // draw a line + glLineWidth(1.0f); //line width + glBegin(GL_LINES); + glVertex2f(get_double(p1, 0), get_double(p1, 1)); + glVertex2f(get_double(p2, 0), get_double(p2, 1)); + glEnd(); + + glFlush(); + + return Universe::HiNone; +} + +HiObject* canvas_update(ObjList args) { + HiObject* canvas = args->get(0); + HiObject* pnt = canvas->getattr(new HiString("window"))->getattr(new HiString("native_pnt")); + +#ifdef RAILGUN_WINDOWS + HWND hwnd = (HWND)((HiLong*)pnt)->value(); + SwapBuffers(GetDC(hwnd)); +#endif + return Universe::HiNone; +} + +RGMethod draw_methods[] = { + { "create_window", new FunctionObject(create_window), 0, "create window", }, + { NULL, NULL, 0, NULL, }, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +SO_PUBLIC ModuleObject* init_libdraw() { + ModuleObject* mod = ModuleObject::init_module(draw_methods); + ModuleObject* draw_def = ModuleObject::import_module(new HiString("draw_def")); + + HiObject* tp_canvas = draw_def->getattr(new HiString("Canvas")); + Klass* canvas_klass = ((HiTypeObject*)tp_canvas)->own_klass(); + HiDict* klass_dict = canvas_klass->klass_dict(); + + klass_dict->put(new HiString("draw_line"), new FunctionObject(canvas_draw_line)); + klass_dict->put(new HiString("update"), new FunctionObject(canvas_update)); + + HiObject* tp_win = draw_def->getattr(new HiString("Window")); + Klass* win_klass = ((HiTypeObject*)tp_win)->own_klass(); + klass_dict = win_klass->klass_dict(); + + klass_dict->put(new HiString("get_events"), new FunctionObject(window_get_events)); + + mod->extend(draw_def); + + return mod; +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/main/vm/extlib/hidraw.hpp b/src/main/vm/extlib/hidraw.hpp new file mode 100644 index 0000000..b6f34d7 --- /dev/null +++ b/src/main/vm/extlib/hidraw.hpp @@ -0,0 +1,16 @@ +#ifndef HIDRAW_HPP +#define HIDRAW_HPP + +#include "inc/railgun.hpp" + +#ifdef RAILGUN_WINDOWS +#include +#endif + +HiObject* create_window(ObjList args); +HiObject* create_window_md(ObjList args); + +// methods definiations for canvas. +HiObject* canvas_draw_line(ObjList args); +HiObject* canvas_update(ObjList args); +#endif \ No newline at end of file diff --git a/src/main/vm/extlib/math.cpp b/src/main/vm/extlib/math.cpp index 3d49e81..ebcbddb 100644 --- a/src/main/vm/extlib/math.cpp +++ b/src/main/vm/extlib/math.cpp @@ -33,29 +33,29 @@ HiObject* arg_two(ObjList args) { RGMethod math_methods[] = { - { "acos", (NativeFuncPointer)(arg_one), 0, "acos(x)", }, - { "asin", (NativeFuncPointer)(arg_one), 0, "asin(x)", }, - { "atan", (NativeFuncPointer)(arg_one), 0, "atan(x)", }, - { "cos", (NativeFuncPointer)(arg_one), 0, "cos(x)", }, - { "ceil", (NativeFuncPointer)(arg_one), 0, "ceil(x)", }, - { "exp", (NativeFuncPointer)(arg_one), 0, "exp(x)", }, - { "fabs", (NativeFuncPointer)(arg_one), 0, "absolute value of x", }, - { "floor", (NativeFuncPointer)(arg_one), 0, "floor(x)", }, - { "hypot", (NativeFuncPointer)(arg_two), 0, "hypotenuse of right-angled triangle" }, - { "log", (NativeFuncPointer)(arg_one), 0, "log(x)", }, - { "pow", (NativeFuncPointer)(arg_two), 0, "pow(x)", }, - { "round", (NativeFuncPointer)(arg_one), 0, "round(x)", }, - { "sin", (NativeFuncPointer)(arg_one), 0, "sin(x)", }, - { "sqrt", (NativeFuncPointer)(arg_one), 0, "square root of x", }, - { NULL, NULL, 0, NULL, }, + { "acos", new FunctionObject(arg_one), 0, "acos(x)", }, + { "asin", new FunctionObject(arg_one), 0, "asin(x)", }, + { "atan", new FunctionObject(arg_one), 0, "atan(x)", }, + { "cos", new FunctionObject(arg_one), 0, "cos(x)", }, + { "ceil", new FunctionObject(arg_one), 0, "ceil(x)", }, + { "exp", new FunctionObject(arg_one), 0, "exp(x)", }, + { "fabs", new FunctionObject(arg_one), 0, "absolute value of x", }, + { "floor", new FunctionObject(arg_one), 0, "floor(x)", }, + { "hypot", new FunctionObject(arg_two), 0, "hypotenuse of right-angled triangle" }, + { "log", new FunctionObject(arg_one), 0, "log(x)", }, + { "pow", new FunctionObject(arg_two), 0, "pow(x)", }, + { "round", new FunctionObject(arg_one), 0, "round(x)", }, + { "sin", new FunctionObject(arg_one), 0, "sin(x)", }, + { "sqrt", new FunctionObject(arg_one), 0, "square root of x", }, + { NULL, NULL, 0, NULL, }, }; #ifdef __cplusplus extern "C" { #endif -SO_PUBLIC RGMethod* init_libmath() { - return math_methods; +SO_PUBLIC ModuleObject* init_libmath() { + return ModuleObject::init_module(math_methods); } #ifdef __cplusplus diff --git a/src/main/vm/inc/railgun.hpp b/src/main/vm/inc/railgun.hpp index 0d4b0ac..4268f4a 100644 --- a/src/main/vm/inc/railgun.hpp +++ b/src/main/vm/inc/railgun.hpp @@ -2,18 +2,25 @@ #define RAILGUN_HPP #include "runtime/functionObject.hpp" +#include "runtime/universe.hpp" +#include "runtime/module.hpp" #include "object/hiInteger.hpp" +#include "object/hiLong.hpp" #include "object/hiDouble.hpp" +#include "object/hiDict.hpp" +#include "object/hiTuple.hpp" +#include "object/hiList.hpp" +#include "object/hiString.hpp" #define SO_PUBLIC __attribute__((visibility("default"))) struct RGMethod { const char* meth_name; - NativeFuncPointer meth; - int meth_info; + HiObject* meth; + int meth_info; const char* meth_doc; }; -typedef RGMethod* (*INIT_FUNC)(); +typedef ModuleObject* (*INIT_FUNC)(); #endif diff --git a/src/main/vm/os/windows/hidraw_win.cpp b/src/main/vm/os/windows/hidraw_win.cpp new file mode 100644 index 0000000..480d869 --- /dev/null +++ b/src/main/vm/os/windows/hidraw_win.cpp @@ -0,0 +1,129 @@ +#include "extlib/hidraw.hpp" +#include "inc/railgun.hpp" + +#ifdef RAILGUN_WINDOWS +#include +#include +#include + +LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); + +void SetupPixelFomat(HWND hWnd, HDC &hDC ) { + hDC = GetDC(hWnd); + + PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), // size + 1, // version + PFD_SUPPORT_OPENGL | // OpenGL window + PFD_DRAW_TO_WINDOW | // render to window + PFD_DOUBLEBUFFER, // support double-buffering + PFD_TYPE_RGBA, // color type + 32, // preferred color depth + 0, 0, 0, 0, 0, 0, // color bits (ignored) + 0, // no alpha buffer + 0, // alpha bits (ignored) + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits (ignored) + 24, // depth buffer + 8, // no stencil buffer + 0, // no auxiliary buffers + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0, // no layer, visible, damage masks + }; + + int pixelFormat = ChoosePixelFormat(hDC, &pfd); + SetPixelFormat(hDC, pixelFormat, &pfd); +} + +bool InitGL(HDC hDC, HGLRC &hRC ) { + hRC = wglCreateContext(hDC); + wglMakeCurrent(hDC, hRC); + + return true; +} + +void DestroyGL( HDC hDC, HGLRC hRC ) { + if (hDC != NULL && hRC != NULL) + { + wglMakeCurrent(hDC, NULL); + wglDeleteContext(hRC); + } +} + +void SceneInit() +{ + +} + +HiObject* create_window_md(ObjList args) { + MSG msg; + HWND hwnd; + WNDCLASS wndclass; + TCHAR szAppName[] = TEXT("HiDraw"); + + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hbrBackground=CreateSolidBrush(RGB(203,202,201)); + wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); + wndclass.hInstance = NULL; + wndclass.lpfnWndProc = WndProc; + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szAppName; + wndclass.style = CS_VREDRAW | CS_HREDRAW; + + if(!RegisterClass(&wndclass)) { + printf("Error in RegisterClass!\n"); + return NULL; + } + + hwnd = CreateWindow(szAppName, + TEXT("HiDraw v0.1"), + WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MINIMIZEBOX ^ WS_MAXIMIZEBOX, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL,NULL, + NULL, + NULL); + + HGLRC g_hRC; + HDC g_hDC; + + SetupPixelFomat(hwnd, g_hDC); + InitGL(g_hDC, g_hRC); + + ShowWindow(hwnd,SW_NORMAL); + UpdateWindow(hwnd); + + return new HiLong((long long)hwnd); +} + +LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { + switch(message) + { + case WM_CLOSE: + DestroyWindow(hwnd); + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + case WM_CREATE: + //PlaySound(TEXT("HG.wav"),NULL ,SND_ASYNC | SND_LOOP);//播放游戏音乐; + return 0; + + case WM_KEYDOWN: + return 0; + + case WM_PAINT: + return 0; + } + return DefWindowProc(hwnd,message,wParam,lParam); +} + +#endif \ No newline at end of file diff --git a/src/main/vm/runtime/functionObject.cpp b/src/main/vm/runtime/functionObject.cpp index f352f83..b5a345b 100644 --- a/src/main/vm/runtime/functionObject.cpp +++ b/src/main/vm/runtime/functionObject.cpp @@ -7,6 +7,10 @@ #include "memory/heap.hpp" #include "memory/oopClosure.hpp" +#ifdef RAILGUN_WINDOWS +#include +#endif + FunctionKlass* FunctionKlass::instance = NULL; FunctionKlass* FunctionKlass::get_instance() { @@ -213,6 +217,14 @@ HiObject* builtin_super(ObjList args) { return NULL; } +HiObject* sleep(ObjList args) { + HiInteger* t = (HiInteger*)(args->get(0)); +#ifdef RAILGUN_WINDOWS + SleepEx(t->value(), true); +#endif + return Universe::HiNone; +} + HiObject* sysgc(ObjList args) { Universe::heap->gc(); return Universe::HiNone; diff --git a/src/main/vm/runtime/functionObject.hpp b/src/main/vm/runtime/functionObject.hpp index fb75c17..0e8cca5 100644 --- a/src/main/vm/runtime/functionObject.hpp +++ b/src/main/vm/runtime/functionObject.hpp @@ -129,6 +129,7 @@ HiObject* type_of(ObjList args); HiObject* isinstance(ObjList args); HiObject* builtin_super(ObjList args); HiObject* sysgc(ObjList args); +HiObject* sleep(ObjList args); HiObject* print(ObjList args); #endif diff --git a/src/main/vm/runtime/interpreter.cpp b/src/main/vm/runtime/interpreter.cpp index 722c6e4..c76bc88 100644 --- a/src/main/vm/runtime/interpreter.cpp +++ b/src/main/vm/runtime/interpreter.cpp @@ -66,6 +66,7 @@ Interpreter::Interpreter() { _builtins->put(new HiString("isinstance"),new FunctionObject(isinstance)); _builtins->put(new HiString("super"), new FunctionObject(builtin_super)); _builtins->put(new HiString("sysgc"), new FunctionObject(sysgc)); + _builtins->put(new HiString("sleep"), new FunctionObject(sleep)); _builtins->put(new HiString("print"), new FunctionObject(print)); _builtins->put(new HiString("open"), new FunctionObject(file_open)); @@ -92,6 +93,7 @@ void Interpreter::build_frame(HiObject* callable, ObjList args, int op_arg) { PUSH(((FunctionObject*)h_callable())->call(args)); } else if (h_callable->klass() == MethodKlass::get_instance()) { + Handle method((MethodObject*) callable); // return value is ignored here, because they are handled // by other pathes. @@ -124,9 +126,9 @@ void Interpreter::build_frame(HiObject* callable, ObjList args, int op_arg) { else { HiObject* m = h_callable->get_klass_attr(ST(call)); if (m != Universe::HiNone) - build_frame(m, args, op_arg); + build_frame(m, h_args(), op_arg); else { - callable->print(); + h_callable->print(); printf("\nError : can not call a normal object.\n"); } } diff --git a/src/main/vm/runtime/module.cpp b/src/main/vm/runtime/module.cpp index 3cc2261..9dc2744 100644 --- a/src/main/vm/runtime/module.cpp +++ b/src/main/vm/runtime/module.cpp @@ -115,11 +115,15 @@ ModuleObject* ModuleObject::import_so(HiString* mod_name) { return NULL; } - RGMethod* ml = init_func(); + return init_func(); +} + +ModuleObject* ModuleObject::init_module(RGMethod* methods) { ModuleObject* mod = new ModuleObject(HiDict::new_instance()); + + RGMethod* ml = methods; for (; ml->meth_name != NULL; ml++) { - mod->put(new HiString(ml->meth_name), - new FunctionObject(ml->meth)); + mod->put(new HiString(ml->meth_name), ml->meth); } return mod; diff --git a/src/main/vm/runtime/module.hpp b/src/main/vm/runtime/module.hpp index 7794b1e..d735c84 100644 --- a/src/main/vm/runtime/module.hpp +++ b/src/main/vm/runtime/module.hpp @@ -5,6 +5,7 @@ class HiDict; class OopClosure; +class RGMethod; class ModuleKlass : public Klass { private: @@ -28,6 +29,7 @@ public: ModuleObject(HiDict* x); static ModuleObject* import_module(HiObject* mod_name); static ModuleObject* import_so (HiString* mod_name); + static ModuleObject* init_module (RGMethod* methods); void put (HiObject* x, HiObject* y); HiObject* get (HiObject* x); diff --git a/src/test/hilang/win.hi b/src/test/hilang/win.hi new file mode 100644 index 0000000..89e50df --- /dev/null +++ b/src/test/hilang/win.hi @@ -0,0 +1,29 @@ +from libdraw import create_window; +from libdraw import Window; + +myWindow = Window(create_window()); +print(myWindow); +canvas = myWindow.get_canvas(); +print(canvas); + +going = True; +y = -0.9; +while(going) { + sleep(200); + + canvas.draw_line((-0.5, y), (0.5, y)); + y += 0.05; + canvas.update(); + + evts = myWindow.get_events(); + + if (evts is None) { + continue; + } + + for evt in evts { + if (evt == myWindow.QUIT) { + going = False; + } + } +} -- Gitee