About this application
This application takes a subset of Javascript and allows it to be used at the programming langauge for MIT's App Inventor.
Why does this exist?
- Australia curriculum asks students to use a text based general purpose programming language
- I teach a lot of Javascript
- I was interested in how compilation worked so had been reading about how it is done for a year or so
- I found out that MIT App Inventor blocks and interface eventually end up as Scheme code through reading a journal article. Coincidently I now know how to write basic scheme code.
- I found out that whilst others had attempted to write a text language for App Inventor blocks, they had not really had much success (that I could find). Interesting articles those.
- I thought it would be fun (probably the most important reason)
Usage
Device connection status
- Emulator - works reasonably well Android over USB - no known issues - works really well Android over wifi - no known issues - works really well Apple over wifi - significant issues - expect problems
Installation
- Emulator and Android over USB reqquire MIT App Inventor AIStarter https://appinventor.mit.edu/explore/ai2/setup-emulator.html
- Android device and Apple device require MIT App Inventor companion app installed
- npm install @mapbox/node-pre-gyp
- npm install telephonejs
How to use: (this really needs better notes.)
- Create XML file for the layout
- Create a linked JS file for the code
- Run the app
- Connect to device
- Hopefully see what you made
Information on components - properties, methods and events
Please visit this url - https://telephonejs.com/ Eventually this will have sample code examples for each of these.
JavaScript General Notes:
- Variables are only assigned with 'let'. No 'const' or 'var'
- To select a component use
getComponent(componentName)
where componentName was the name given in the XML declaration for the component
Strings
String Properties Implemented | String Properties Not Implemented |
---|---|
.length |
String Methods Implemented | String Methods Not Implemented |
---|---|
.at() | .codePointAt(0) |
.charAt() | .fromCodePoint() |
.charCodeAt() | .localeCompare() |
.concat() | .match() //regex |
.endsWith() | .matchAll() //regex |
.fromcharCode() | .normalize() |
.includes() | .raw |
.indexOf() | |
.lastIndexOf() | |
.padEnd() | |
.padStart() | |
.repeat() | |
.replace() acts slightly differently. When you add an object it flattens the object and prints it as opposed to printing [OBJECT object]. | |
.replaceAll() | |
.slice() | |
.split() | |
.startsWith() | |
.substring() | |
.toLowerCase() | |
.toUpperCase() | |
.trim() | |
.trimEnd() | |
.trimStart() |
Arrays
Array Properties Implemented | Array Properties Not Implemented |
---|---|
.length |
Array Methods Implemented | Array Methods Not Implemented |
---|---|
.at() | .copyWithin() |
.concat() | .entries() |
.includes() | .every() |
.indexOf() | .fill() |
Array.isArray() | .filter() |
.join() | .find() |
.shift() | .findIndex() |
.pop() | .findLast() |
.unshift() | .findLastIndex() |
.shift() | ... and all the other ones |
.reverse() | - |
.map() (except for the optional assignment of a 'this' value) | - |
Objects
Object Methods Implemented | Object Methods Not Implemented |
---|---|
.assign(target, source) | .defineProperties() |
.create(source) | .defineProperty() |
.entries() | .freeze(0) |
.fromEntries() | .getOwnPropertyDescriptor() |
.hasOwn() | .getOwnPropertyDescriptors() |
.keys() | .getOwnPropertyNames() |
.values() | .getOwnPropertySymbols() |
- | .getPrototypeOf() |
- | .hasOwnProperty() |
- | .is() |
- | .isExtensible() |
- | .isFrozen() |
- | .isPrototypeOf() |
- | .isSealed() |
- | .preventExtensions() |
- | .propertyIsEnumerable() |
- | .seal() |
- | .setPropertyOf() |
- | .toLocaleString() |
- | .toString() |
- | .valueOf(0) |
Keywords
Keywords Implemented | Keywords Not Implemented | ||
---|---|---|---|
break | continue | ||
while (){} | var | ||
for(;;){} For loops are transformed into while loops during transpilation. |
const | ||
if, else if, else | - | ||
function name(){} Function expressions ( let name = function(){} )are transpiled into declarations ( function name(){} ) |
- | ||
let (for declaring variables) | - | ||
Logical operators && and \ | \ | - | |
Member expressions | - | ||
Return | - | ||
Template Literals | - | ||
Unary Expressions (! and -) | - | ||
Postfix and prefix decrement and increment ++a, a++ , --a and a-- | - |
Math
Math Methods Implemented | Math Methods Not Implemented |
---|---|
sqrt() | - |
abs() | - |
log() | - |
exp() | - |
round() | - |
ceil() | - |
floor() | - |
sin() | - |
cos() | - |
tan() | - |
asin() | - |
acos() | - |
atan() | - |
atan2() | - |
random() | - |
min() | - |
max() | - |
range() | - |
mod() | - |
quot() | - |
toDegrees() | - |
toRadians() | - |
randomSeed() | - |
Stat (statistics methods)
Stat Methods Implemented | Stat Methods Not Implemented |
---|---|
avg() | - |
min() | - |
max() | - |
gm() | - |
stddev() | - |
stderr() | - |
mode() | - |
Color (color methods)
Color Methods Implemented | Color Methods Not Implemented |
---|---|
make() | - |
split() | - |
Things Not Included in the current iteration
- EV3 lego robotics components
- FirebaseDb - there are some fixed default values so would require special processing code for this component and I am a bit over adding components at the moment (being doing it every day for a week)
Known Issues
Texting component can't send or recieve - it is the same problem in the offical app inventor to do with google permission. https://community.appinventor.mit.edu/t/error-908-permission-receive-sms/7426/5
camera and camcorder throw errors on console but seem to work
Need to fail gracefully but not terminate on xml and js errors in code
xml hinting for properties via dtd or xmlschema
emulatorUSb needs to have better file on device checking - at moment seems to upload everything each time (which works and is fine but annoying)
New functions for math (now mostly implemented as a Stat.method)
Compilation from generated scheme file to apk (because that would be cool)
declaring the correct scope for function declarations - currently defaults to "global" but this is not always correct
Testing required for:
- Charts
- Chartline2d
- Barometer
- GyroscopeSensor
- Hygrometer
New Features in App Inventor 2.66 (This will be a lot more work, sigh.....)
- Add functional list operators like map, filter, reduce, and sort (@siyaoL1) (map now done)
- Add new math stats blocks like average, standard deviation, min/max over lists (mostly completed)
- Add custom font typeface support (@preetvadaliya)
- Add new Bluetooth permissions to permission helper block
- Add “every component” block (@Vishwas-Adiga) (no idea what this does yet)
- Add functions to Chart to set domain and range of charts and to fix the origin at 0, 0 (done)
Need to add feature to application to build a template app
Need to add option to menu to select for iOS device to pick up the correct header info (or do this another way). This implies testing with iOS devices.
Add support for arrow function code style (probably just treat it like a normal function - this will break 'this' scoping for these functions but oh well, some sacrifices need to be made, and as I haven't actually acounted for the 'this' it is not going to be an issue hopefully)
Need to test getting images from subfolders rather than just uploading from root folder and any issues this may have
Need an option to upload a pre-made 'file manager' app to device to view and clear out App Inventor App memory.
(This list keeps growing for some reason. It's like one of those plants that the more you trim it back the better it grows.)
Observations
component heights and widths can only be read after a screen is initialized, otherwise they return zero InstantInTime means milliseconds since epoch (1,1,1970 midnight)
TODO
- CSS type external styling
- Programming language documentation for functionality
- Validate components for the 'setComponent' function
- Complete this readme
- Compilation to android app (unlikely)