-------------------- VC to Lua converter: an idea by Overkill! -------------------- Make sure word wrap is OFF, and you're preferably viewing with monospace font. This converter is essentially a compiler which takes VergeC code, and generates Lua code which uses the v3 namespace as a result. Its purpose is to allow people to salvage old VC code, while converting to a more modern language. Its eventual intent is to be able to automate conversion of Sully into a LuaVerge game without massive rewriting. This converter assumes the same limitations as the VC compiler. This makes it more reliable to convert. Single line comments: // blah blah blah In Lua: -- blah blah blah Multiline comments: /* a */ In Lua: --[[ a ]] Builtin Compatibility: Constant variables: FILE_READ => v3.FILE_READ Functions: ShowPage() => v3.ShowPage(); Variable accessors: entity.x[i] => v3.get_entity_x(i); Variable mutators: entity.x[i] = 6; => v3.set_entity_x(i, 6); Future: Convert into the more complicated syntax sugar'd wrappings. Much, much, more tedious since these don't follow quite so simplistic general conversion patterns. entity.x[i] = 6; => v3.entity[i].x VC Type Compatibility: struct PlayerType { string name; int hp; int max_hp; int abilities[30]; } PlayerType player; What would be generated in Lua: -- (I've actually already written code that will properly run the following Lua!) PlayerType = Structure { name = StringField; hp = IntField; max_hp = IntField; abilities = Array(IntField, 30); } player = PlayerType(); Bitwise operator compatibility: ~a => v3.bitnot(a) a ^ b => v3.bitxor(a, b) a | b => v3.bitor(a, b) a & b => v3.bitand(a, b) a << b => v3.bitshl(a, b) a >> b => v3.bitshr(a, b) String operator compatibility: s1 + s2 => s1 .. s2 str(s) => tostring(s) mid(s, 1, 2) => v3.strmid(s, 1, 2) left(s, 1) => v3.strleft(s, 1) right(s, 2) => v3.strright(s, 2) Assignment operator compatibility: a += b; => a = a + b; a -= b; => a = a - b; a++; => a = a + 1; a--; => a = a - 1; Logical operator compatibility: a && b => a and b a || b => a or b !a => not a Comparison operator compatibility: a != b => a ~= b String-calling compatibility: "MyString"(); => v3.CallFunction("MyString"); -- Varargs are, for now, unsupported! -- Until I feel like adding type-safe argument mechanisms inspection for LuaVerge. -- Builtins Log("Hello world!"); => v3.Log("Hello World") Conditional statements: VC: if(x && y == 5) {} // 1 if(x) {} // 2 if(x != 0 && y == 5) // 3 Literal translation to Lua (bad considering 0 is true in Lua): if x and y == 5 then end -- 1 if x then end -- 2 if x ~= 0 and y == 5 then end -- 3 Future Fix Option 1: Adding implicit coercion: if x ~= 0 and y == 5 then end -- 1 if x ~= 0 then end -- 2 if x ~= 0 and y == 5 then end -- 3 Future Fix Option 2: Adding explicit erroring: -- 1: ERROR: Expected a boolean expression got an int instead. Use comparisons to convert to boolean. -- 2: ERROR: Expected a boolean expression got an int instead. Use comparisons to convert to boolean. if x ~= 0 and y == 5 then end -- 3 Precedence Fixes: VC definition: int a = 5 * 2 + 4 * 2; What Lua would normally interpret if literally translated: a = (5 * 2) + (4 * 2); To emulate VC precedence: a = ((5 * 2) + 4) * 2; VC definition: int a = 2 * 1 + 4 / 3; What Lua would normally interpret if literally translated: a = (2 * 1) + (4 / 3); Future Fix: Emulate VC precedence: a = ((2 * 1) + 4) / 3; Future Fix: Emulate integer division: a = math.floor(((2 * 1) + 4) / 3); Converting if statements: VC: if(condition) { A; } else if(condition) { B; } else { C; } Lua: if condition then A; elseif condition then B; else C; end For loops: VC: for(i = 0; i < 5; i++) { statements; } Simple Lua: i = 0; while i < 5 do statements; i = i + 1; end Smarter Lua (undecided), comes with side-effect that loop variable escapes scope after block: for i = 0, 5 do statements; end Function compatibility: VC: int myfunc() { int a = 42; return a; } Lua: function myfunc() local a = 42; return a; end Preprocessor coercion: #include "filename" => require "filename" #define X 5 => X = 5 Trickier-yet-doable compatibility: Reflection capabilities: v3.GetInt(arrname, idx); v3.SetInt(arrname, idx, value); v3.GetString(arrname, idx); v3.SetString(arrname, idx, value); v3.GetIntArray(arrname, idx); v3.SetIntArray(arrname, idx, value); v3.GetStringArray(arrname, idx); v3.SetStringArray(arrname, idx, value); Varargs compatibility. Doable with a bit of mucking around: args.length => v3.ArgumentLength(args) args.is_int[i] => v3.ArgumentIsInt(args, i) args.is_string[i] => v3.ArgumentIsString(args, i) args.int[i] => v3.ArgumentGetInt(args, i) args.string[i] => v3.ArgumentGetInt(args, i)