Skip to content

Repository files navigation

#jslike JavaScript-like "var" (Number/String/Array/Object/function) for C++

jslike let's you create objects, assign properties, use arrays and strings a JavaScript way right in your C++ code by exposing the single var class.

###Currently implemented

  • Number, String, Array, Object, Boolean.
  • Pass by value for Numbers/Boolean, pass by reference for Array/Object.

####Functions and properties:

  • var = var, int, double, char*, wchar_t*, bool -- construct var from basic types
  • var.toString()
  • var[#] -- Array index access
  • var[key] -- Object property access
  • var[#] -- String character access
  • var + var -- Arithmetic/logic operators ++--+-/*%&|&&||==!=<>
  • var + var -- String concatenation, comparison <>==
  • var.round()
  • var.charAt()
  • var.charCodeAt()
  • var.toNumber()
  • var::fromCharCode() -- static function
  • var.split()
  • var.objectKeys() -- JavaScript's Object.keys()
  • var.indexOf() -- Array/String
  • var.push()
  • var.pop()
  • var.Push() -- JavaScript unshift() (shift is a reserved word in C++).
  • var.Pop() -- JavaScript shift()
  • var.length()
  • var.splice()
  • var.slice()
  • var.join()
  • var.typeOf()
  • var.del() -- delete key/value pairs from Object
  • var.has() -- check if key is set (exists) in the Object.
  • undefined -- set and compare vars with undefined or Undefined().
  • JSON.stringify()
  • JSON.parse()

Conversion to basic C++ types:

  • wchar_t* getStringPointer()
  • char* getStringAllocUtf()
  • char* getStringAllocAscii()
  • int toDouble()
  • int toInt()

Experimental complex literals:

  • var::arr() = a,b,c,d,....
  • var::obj() = a,b,c,d,....
  • ARR(1,2,3,4)
  • OBJ("a", 2, "b", 4)
  • log(...) -- function to conveniently output to console

###Not yet implemented

  • mark&sweep GC
  • functions, lambdas, closures
  • map, sort, filter etc...

##Examples

The library is included by source, so you simply add these two lines:

#include "jslike.h"usingnamespacejslike;

jslike tries not to pollute your namespace as much as possible, so everything is inside the "namespace jslike".

###Minimal program

// hello.cpp
#include"stdio.h"
#include"jslike.h"usingnamespacejslike;intmain() {
var hello = "hello world привет мир 你好世界";
log(hello)
}

output:

hello world привет мир 你好世界

###Undefined variables, number variables

varx;vary=42;log(x,x.typeOf());log(y,y.typeOf());x=3,y=4;log(x+y);log(x-4,x+5,x/y,x*y);

output:

undefined undefined42 number7-1 8 0.75 12

###Strings

varhello="hello";varworld;world="world";log(hello+"-"+world+"!");// string concatenationlog(hello,world);// log can accept unlimited number or argumentslog(hello.indexOf("ll"));

output:

hello-world!hello world2
vars="Nuke the entire site from orbit";log("Sentence length:",s.length());log(s.slice(0,4),s.slice(-10));for(inti=0;i<4;i++)log(s.charAt(i),s.charCodeAt(i));

output:

Sentence length: 31Nuke from orbitN 78u 117k 107e 101

###Mix numbers and strings

vara="A",b=1;// 'string + number' implies conversion to stringlog(a+b);log((var)"Received #"+12+" from "+2+" planets");log((var)"2 + 2 = "+(2+2));// explicit var constructor

output:

A1Received #12 from 2 planets2 + 2 = 4

###Arrays

Declare empty array and push something into it.

varA=Array;A.push("planet");A.push("LV");A.push(426);log(A);

Array toString() is called before output.

output:

planet, LV, 426

log()

log() is console.log() of JavaScript.

log can print any var or anything that a var constructor accepts.

vara=1;varb="hello";varc=Array;c.push(100);c.push(200);log(a,b,c,500,"world");

output:

1 hello 100, 200 500 world

###Array.slice()

varfruits;fruits=(Arr"Banana","Orange","Lemon","Apple","Mango");varcitrus=fruits.slice(1,3);log(citrus);

The contents of citrus will be:

Orange, Lemon

###Array splice()

Unlike JavaScript you cannot insert more than one item in splice().

varfruits=(Arr"Banana","Orange","Apple","Mango");fruits.splice(2,0,"Kiwi");fruits.splice(2,0,"Lemon");log(fruits);

output:

Banana, Orange, Lemon, Kiwi, Apple, Mango 

###Array indexOf() and String indexOf()

varq;q=(Arr0,1,2,3,4,5,6);varj=q.indexOf(3);log(q);log(j);vara="hello world";log(a.indexOf("wo"));

output:

0, 1, 2, 3, 4, 5, 6 3 6 

###Array literal notation

The closest syntax we could achieve in C++ to cozy JavaScript Array literal notation is this: var x = (Arr list-of-items). This syntax is achieved with overloading operator= and operator, for a temporary class arrset. And then hiding it under the macro Arr.

Arr is a #define macro that expands to var::arr() =.

varplanets=(Arr"Earth","Venus","Mars","Jupiter");varstars=(Arr"Vega","Aldebaran","Altair","Decrux");for(vari=0;i<planets.length();i++)log((var)"Planet #"+(i+1),planets[i]);log("Stars:",stars);log("Space objects:",planets.concat(stars));

output:

Planet #1 Earth Planet #2 Venus Planet #3 Mars Planet #4 Jupiter Stars: Vega, Aldebaran, Altair, Decrux Space objects: Earth, Venus, Mars, Jupiter, Vega, Aldebaran, Altair, Decrux 

###concatAll()

Unfortunately there is no way use varargs/stdargs with class constructors, so we cannot haveconcat(a,...) syntax. Instead var.concatAll() is provided.

vara=Array;a.push((Arr1,2,3));a.push((Arr4,5,6));a.push((Arr7,8,9));log(JSON.stringify(a));varb=a.concatAll();log(JSON.stringify(b));

output:

[[1,2,3],[4,5,6],[7,8,9]] [1,2,3,4,5,6,7,8,9] 

###Objects

varxy=Object;// Declare empty objectxy["x"]=100;xy["y"]=200;log(JSON.stringify(xy));log(xy["z"]);

output:

{x:100,y:200} undefined 

Object literal notation:

varo=(Obj"x",100,"y",400);log(JSON.stringify(o));

output:

{x:100,y:400} 

Property access. Unfortunately there is no way to enable "o.x" style notation in C++. So we have to use var[key] syntax.

o["x"]++;o["y"]=o["x"]*2;log(JSON.stringify(o));

output:

{x:101,y:202} 

Delete existing propery specified by the key name:

if(o.has("x"))o.del("x");log(JSON.stringify(o));

output:

{ y: 202 }

###Converting between var and basic types

vara=123.456;inti=a.toInt();doubled=a.toDouble();printf("Basic types, integer=%i, double=%f\n",i,d);

output:

Basic types, integer=123, double=123.456000

###Getting a pointer to a character buffer of a String. Internally strings are stored as UTF16/32 AKA wchar_t. You can either get a pointer to a internal wchar_t* buffer, or get a pointer to a char* copy of that buffer, allocated and copied for you in either ascii or utf8.

wchar_t* var::getStringPointer() returns a pointer to an internal data, it is valid until the var exists. Do not delete the pointer returned from this function.

When function name has Alloc() in it, it means you are responsible for the deallocation of the returned data. Use C++ delete operator when you are done.

var var::getStringAllocUtf() and var var::getStringAllocUtf() alloc and copy the contents.

varhello="world,мир,世界";char*str=hello.getStringAllocUtf();printf("char* = %s\n",str);deletestr;str=hello.getStringAllocAscii();printf("char* = %s\n",str);deletestr;wchar_t*w=hello.getStringPointer();for(inti=0;i<hello.length().toInt();i++){printf("%i: char code: %i\n",i,(int)w[i]);}

output:

char* = world,мир,世界char* = world,<8@,�L0: char code: 1191: char code: 1112: char code: 1143: char code: 1084: char code: 1005: char code: 446: char code: 10847: char code: 10808: char code: 10889: char code: 4410: char code: 1999011: char code: 30028

###Passing var as an argument

Arrays and Objects are passed by reference, just like in JavaScript. Strings, Numbers, Booleans are passed by value. This example illustrates this principle:

#include "stdio.h"
#include "jslike.h"usingnamespacejslike;varsum10(vara,varb){a=a*10;b=b*10;returna+b;}voidpopAndPrint(vara){log(a.pop());}intmain(){varx=400,y=500;log(sum10(x,y));log(x,y);varb;b=(Arr100,200,300);popAndPrint(b);popAndPrint(b);log("What remains in b:",b);}

output:

9000 400 500 300 200 What remains in b: 100 

##Implementation details.

###Operator overloading jslike intensively relies on C++ operator overloading. var is declared as struct var, hence all members are public.

The code is C++98 compatible. No modern C++2015 features are used.

###Amalgamated header jslike is header-only library, there is no object file involved. You just include it in your source and it includes other files. The complete size of all files together is about 1700 LOC at the moment of this writing.

jslike.h includes few more headers, but for your convenience _jslike.h is also provided, which is an amalgamation or basically concatenation of all headers into one single file. You can just grab it and copy to your project directory if you need.

About

JavaScript-like "var" (Number/String/Array/Object/function) for C++

Resources

Stars

19 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages