diff --git a/compiler/cgen.v b/compiler/cgen.v index 004e864c9b..89659269da 100644 --- a/compiler/cgen.v +++ b/compiler/cgen.v @@ -35,6 +35,7 @@ mut: file string line int line_directives bool + cut_pos int } fn new_cgen(out_name_c string) *CGen { @@ -126,6 +127,23 @@ fn (g mut CGen) add_placeholder() int { return g.cur_line.len } +fn (g mut CGen) start_cut() { + g.cut_pos = g.add_placeholder() +} + +fn (g mut CGen) cut() string { + pos := g.cut_pos + g.cut_pos = 0 + if g.is_tmp { + res := g.tmp_line.right(pos) + g.tmp_line = g.tmp_line.left(pos) + return res + } + res := g.cur_line.right(pos) + g.cur_line = g.cur_line.left(pos) + return res +} + fn (g mut CGen) set_placeholder(pos int, val string) { if g.nogen || g.pass != .main { return @@ -246,3 +264,28 @@ fn build_thirdparty_obj_file(flag string) { println(res) } +fn os_name_to_ifdef(name string) string { + switch name { + case 'windows': return '_WIN32' + case 'mac': return '__APPLE__' + case 'linux': return '__linux__' + case 'freebsd': return '__FreeBSD__' + case 'openbsd': return '__OpenBSD__' + case 'netbsd': return '__NetBSD__' + case 'dragonfly': return '__DragonFly__' + case 'msvc': return '_MSC_VER' + } + panic('bad os ifdef name "$name"') +} + +fn platform_postfix_to_ifdefguard(name string) string { + switch name { + case '.v': return '' // no guard needed + case '_win.v': return '#ifdef _WIN32' + case '_nix.v': return '#ifndef _WIN32' + case '_lin.v': return '#ifdef __linux__' + case '_mac.v': return '#ifdef __APPLE__' + } + panic('bad platform_postfix "$name"') +} + diff --git a/compiler/comptime.v b/compiler/comptime.v index 10c330316a..ddba606a79 100644 --- a/compiler/comptime.v +++ b/compiler/comptime.v @@ -269,3 +269,9 @@ return strings__Builder_str(sb); } ' } +fn (p mut Parser) parse_t() { + +} + + + diff --git a/compiler/fn.v b/compiler/fn.v index 4282c12478..64d1d73cf5 100644 --- a/compiler/fn.v +++ b/compiler/fn.v @@ -606,11 +606,15 @@ fn (p mut Parser) fn_call(f Fn, method_ph int, receiver_var, receiver_type strin if p.tok == .lt { p.check(.lt) gen_type = p.check_name() + // run => run_App + if gen_type == 'T' && p.cur_gen_type != '' { + gen_type = p.cur_gen_type + } // `foo()` // If we are in the first pass, we need to add `Bar` type to the generic function `foo`, // so that generic `foo`s body can be generated for each type in the second pass. if p.first_pass() { - //println('registering $gen_type in $f.name') + println('registering $gen_type in $f.name fname=$f.name') p.table.register_generic_fn_type(f.name, gen_type) // Function bodies are skipped in the first passed, we only need to register the generic type here. return diff --git a/compiler/parser.v b/compiler/parser.v index 36b1b6d316..92de6254d2 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -83,6 +83,8 @@ mut: cur_gen_type string // "App" to replace "T" in current generic function is_vweb bool is_sql bool + sql_i int // $1 $2 $3 + sql_params string // ("select * from users where id = $1", ***"100"***) } const ( @@ -94,17 +96,6 @@ const ( MaxModuleDepth = 4 ) -fn platform_postfix_to_ifdefguard(name string) string { - switch name { - case '.v': return '' // no guard needed - case '_win.v': return '#ifdef _WIN32' - case '_nix.v': return '#ifndef _WIN32' - case '_lin.v': return '#ifdef __linux__' - case '_mac.v': return '#ifdef __APPLE__' - } - panic('bad platform_postfix "$name"') -} - fn (v mut V) new_parser(path string, pass Pass) Parser { v.log('new_parser("$path")') v.cgen.pass = pass @@ -185,7 +176,7 @@ fn (p mut Parser) parse() { } p.fgenln('\n') p.builtin_mod = p.mod == 'builtin' - p.can_chash = p.mod == 'freetype' || p.mod == 'glfw' || p.mod=='glfw2' || p.mod=='ui' // TODO tmp remove + p.can_chash = p.mod == 'freetype' || p.mod=='ui' // TODO tmp remove // Import pass - the first and the smallest pass that only analyzes imports // fully qualify the module name, eg base64 to encoding.base64 fq_mod := p.table.qualify_module(p.mod, p.file_path) @@ -1403,7 +1394,17 @@ fn (p mut Parser) bterm() string { p.gen(tok.str()) } p.next() - p.check_types(p.expression(), typ) + // `id == user.id` => `id == $1`, `user.id` + if p.is_sql { + p.sql_i++ + p.gen('$' + p.sql_i.str()) + p.cgen.start_cut() + p.check_types(p.expression(), typ) + p.sql_params = p.sql_params + p.cgen.cut() + ',' + //println('sql params = "$p.sql_params"') + } else { + p.check_types(p.expression(), typ) + } typ = 'bool' if is_str { //&& !p.is_sql { p.gen(')') @@ -2951,20 +2952,6 @@ fn (p mut Parser) get_tmp_counter() int { return p.tmp_cnt } -fn os_name_to_ifdef(name string) string { - switch name { - case 'windows': return '_WIN32' - case 'mac': return '__APPLE__' - case 'linux': return '__linux__' - case 'freebsd': return '__FreeBSD__' - case 'openbsd': return '__OpenBSD__' - case 'netbsd': return '__NetBSD__' - case 'dragonfly': return '__DragonFly__' - case 'msvc': return '_MSC_VER' - } - panic('bad os ifdef name "$name"') -} - fn (p mut Parser) if_st(is_expr bool, elif_depth int) string { if is_expr { //if p.fileis('if_expr') { diff --git a/compiler/query.v b/compiler/query.v index 9dd4da872b..4be03cf22b 100644 --- a/compiler/query.v +++ b/compiler/query.v @@ -102,14 +102,23 @@ $table_name $tmp; ${obj_gen.str()} ') - p.cgen.resetln(tmp) -} + p.cgen.resetln(tmp) + } // Array else { - p.cgen.insert_before(' + q += ' order by id' + mut params_gen := '' + params := p.sql_params.split(',') + for i, param in params { + params_gen += 'params[$i] = int_str($param).str;' + } + + p.cgen.insert_before('char* params[$p.sql_i]; +$params_gen + +void* res = PQexecParams(db.conn, "$q", $p.sql_i, 0, params, 0, 0, 0) ; +array_pg__Row rows = pg__res_to_rows(res); -array_pg__Row rows = pg__DB_exec(db, tos2("$q")); -//printf("ROWS LEN=%d\\n", rows.len); // TODO preallocate array arr_$tmp = new_array(0, 0, sizeof($table_name)); for (int i = 0; i < rows.len; i++) { diff --git a/vlib/glfw/glfw.v b/vlib/glfw/glfw.v index 0598fdb293..b3d30b479b 100644 --- a/vlib/glfw/glfw.v +++ b/vlib/glfw/glfw.v @@ -98,7 +98,6 @@ const ( KeyDown = 264 ) -// TODO COPY PASTA struct WinCfg { width int height int @@ -136,10 +135,10 @@ type clickpubfn fn (window voidptr, button, action, mods int) pub fn init() { C.glfwInit() - # glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - # glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - # glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - # glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + C.glfwWindowHint(C.GLFW_CONTEXT_VERSION_MAJOR, 3) + C.glfwWindowHint(C.GLFW_CONTEXT_VERSION_MINOR, 3) + C.glfwWindowHint(C.GLFW_OPENGL_FORWARD_COMPAT, C.GL_TRUE) + C.glfwWindowHint(C.GLFW_OPENGL_PROFILE, C.GLFW_OPENGL_CORE_PROFILE) } pub fn (w &Window) destroy() { @@ -172,12 +171,8 @@ pub fn create_window(c WinCfg) *Window { println('failed to create glfw window') C.glfwTerminate() } - // # glfwSetCursorPosCallback(cwindow, glfw__mouse_move) ; - // C.glfwSetCursorPosCallback(cwindow, mouse_move) C.printf('create window wnd=%p ptr==%p\n', cwindow, c.ptr) C.glfwSetWindowUserPointer(cwindow, c.ptr) - // # void *a =glfwGetWindowUserPointer(cwindow); - // # printf("aaaaaa=%p d=%d\n", a,a); window := &Window { data: cwindow, title: c.title, @@ -190,9 +185,6 @@ pub fn (w &Window) set_title(title string) { } pub fn (w &Window) make_context_current() { - // ChatsRepo - kkk := 0 - // println('making context current' ) C.glfwMakeContextCurrent(w.data) } @@ -213,7 +205,6 @@ pub fn set_should_close(w voidptr, close bool) { } pub fn (w &Window) should_close() bool { - // ChatsRepo return C.glfwWindowShouldClose(w.data) } @@ -258,12 +249,10 @@ pub fn get_time() f64 { } pub fn key_pressed(wnd voidptr, key int) bool { - # return glfwGetKey(wnd, key) == GLFW_PRESS; - return false + return int(C.glfwGetKey(wnd, key)) == C.GLFW_PRESS } -// TODO not mut -pub fn (w mut Window) get_clipboard_text() string { +pub fn (w &Window) get_clipboard_text() string { return string(byteptr(C.glfwGetClipboardString(w.data))) } @@ -289,18 +278,17 @@ pub fn (w &Window) set_user_ptr(ptr voidptr) { C.glfwSetWindowUserPointer(w.data, ptr) } -pub fn C.glfwGetVideoMode() C.GLFWvideoMode +struct C.GLFWvidmode { + width int + height int +} + +pub fn C.glfwGetVideoMode() *C.GLFWvidmode pub fn get_monitor_size() Size { - # GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); - // window_width = mode->width; - // window_height = mode->height; - // monitor := C.glfwGetPrimaryMonitor() - res := Size{} - # res.width=mode->width; - # res.height=mode->height; - // C.glfwGetMonitorPhysicalSize(monitor, &res.width, &res.height) - return res + //# GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + mode := C.glfwGetVideoMode(C.glfwGetPrimaryMonitor()) + return Size{mode.width, mode.height} } pub fn (size Size) str() string { diff --git a/vlib/vweb/vweb.v b/vlib/vweb/vweb.v index abf8abe4a2..1be444de8c 100644 --- a/vlib/vweb/vweb.v +++ b/vlib/vweb/vweb.v @@ -81,6 +81,7 @@ pub fn run(port int) { conn := l.accept() or { panic('accept() failed') } + foobar() // TODO move this to handle_conn(conn, app) s := conn.read_line() if s == '' { @@ -159,6 +160,9 @@ pub fn run(port int) { } +pub fn foobar() { +} + fn (ctx mut Context) parse_form(s string) { if !(ctx.req.method in methods_with_form) { return