* rename "microbit" package to "core" #414 * shouldn't edit the package id. * updating package.json * updated the wrong version * missed updating pxt.json of tests
This commit is contained in:
committed by
Peli de Halleux
parent
80131f2928
commit
277d5a721c
393
libs/core/core.cpp
Normal file
393
libs/core/core.cpp
Normal file
@ -0,0 +1,393 @@
|
||||
#include "ksbit.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
namespace String_ {
|
||||
//%
|
||||
StringData *charAt(StringData *s, int pos) {
|
||||
return ManagedString((char)ManagedString(s).charAt(pos)).leakData();
|
||||
}
|
||||
|
||||
//%
|
||||
int charCodeAt(StringData *s, int index) {
|
||||
return ManagedString(s).charAt(index);
|
||||
}
|
||||
|
||||
//%
|
||||
StringData *concat(StringData *s, StringData *other) {
|
||||
ManagedString a(s), b(other);
|
||||
return (a + b).leakData();
|
||||
}
|
||||
|
||||
//%
|
||||
int compare(StringData *s, StringData *that) {
|
||||
return strcmp(s->data, that->data);
|
||||
}
|
||||
|
||||
//%
|
||||
int length(StringData *s) { return s->len; }
|
||||
|
||||
//%
|
||||
StringData *fromCharCode(int code)
|
||||
{
|
||||
return ManagedString((char)code).leakData();
|
||||
}
|
||||
|
||||
//%
|
||||
int toNumber(StringData *s) {
|
||||
return atoi(s->data);
|
||||
}
|
||||
|
||||
//%
|
||||
StringData *mkEmpty()
|
||||
{
|
||||
return ManagedString::EmptyString.leakData();
|
||||
}
|
||||
|
||||
//%
|
||||
StringData *substr(StringData *s, int start, int length)
|
||||
{
|
||||
if (length <= 0)
|
||||
return mkEmpty();
|
||||
if (start < 0)
|
||||
start = max(s->len + start, 0);
|
||||
length = min(length, s->len - start);
|
||||
ManagedString x(s);
|
||||
return x.substring(start, length).leakData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace Boolean_ {
|
||||
// Cache the string literals "true" and "false" when used.
|
||||
// Note that the representation of booleans stays the usual C-one.
|
||||
|
||||
static const char sTrue[] __attribute__ ((aligned (4))) = "\xff\xff\x04\x00" "true\0";
|
||||
static const char sFalse[] __attribute__ ((aligned (4))) = "\xff\xff\x05\x00" "false\0";
|
||||
|
||||
//%
|
||||
StringData* toString(bool v)
|
||||
{
|
||||
if (v) {
|
||||
return (StringData*)(void*)sTrue;
|
||||
} else {
|
||||
return (StringData*)(void*)sFalse;
|
||||
}
|
||||
}
|
||||
|
||||
//%
|
||||
bool bang(bool v) { return !v; }
|
||||
}
|
||||
|
||||
namespace Number_ {
|
||||
//%
|
||||
StringData* toString(int n)
|
||||
{
|
||||
return ManagedString(n).leakData();
|
||||
}
|
||||
|
||||
// +, - and friends are handled directly by assembly instructions
|
||||
// The comparisons are here as they are more code-size efficient
|
||||
|
||||
//%
|
||||
bool lt(int x, int y) { return x < y; }
|
||||
//%
|
||||
bool le(int x, int y) { return x <= y; }
|
||||
//%
|
||||
bool neq(int x, int y) { return x != y; }
|
||||
//%
|
||||
bool eq(int x, int y) { return x == y; }
|
||||
//%
|
||||
bool gt(int x, int y) { return x > y; }
|
||||
//%
|
||||
bool ge(int x, int y) { return x >= y; }
|
||||
|
||||
// These in fact call into C runtime on Cortex-M0
|
||||
//%
|
||||
int div(int x, int y) { return x / y; }
|
||||
//%
|
||||
int mod(int x, int y) { return x % y; }
|
||||
}
|
||||
|
||||
namespace Math_ {
|
||||
//%
|
||||
int pow(int x, int y)
|
||||
{
|
||||
if (y < 0)
|
||||
return 0;
|
||||
int r = 1;
|
||||
while (y) {
|
||||
if (y & 1)
|
||||
r *= x;
|
||||
y >>= 1;
|
||||
x *= x;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
//%
|
||||
int random(int max) {
|
||||
if (max == INT_MIN)
|
||||
return -microbit_random(INT_MAX);
|
||||
else if (max < 0)
|
||||
return -microbit_random(-max);
|
||||
else if (max == 0)
|
||||
return 0;
|
||||
else
|
||||
return microbit_random(max);
|
||||
}
|
||||
|
||||
//%
|
||||
int sqrt(int x)
|
||||
{
|
||||
return ::sqrt(x);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Array_ {
|
||||
//%
|
||||
RefCollection *mk(uint32_t flags)
|
||||
{
|
||||
return new RefCollection(flags);
|
||||
}
|
||||
//%
|
||||
int length(RefCollection *c) { return c->length(); }
|
||||
//%
|
||||
void push(RefCollection *c, uint32_t x) { c->push(x); }
|
||||
//%
|
||||
uint32_t getAt(RefCollection *c, int x) { return c->getAt(x); }
|
||||
//%
|
||||
void removeAt(RefCollection *c, int x) { c->removeAt(x); }
|
||||
//%
|
||||
void setAt(RefCollection *c, int x, uint32_t y) { c->setAt(x, y); }
|
||||
//%
|
||||
int indexOf(RefCollection *c, uint32_t x, int start) { return c->indexOf(x, start); }
|
||||
//%
|
||||
int removeElement(RefCollection *c, uint32_t x) { return c->removeElement(x); }
|
||||
}
|
||||
|
||||
|
||||
// Import some stuff directly
|
||||
namespace pxt {
|
||||
//%
|
||||
void registerWithDal(int id, int event, Action a);
|
||||
//%
|
||||
uint32_t runAction3(Action a, int arg0, int arg1, int arg2);
|
||||
//%
|
||||
uint32_t runAction2(Action a, int arg0, int arg1);
|
||||
//%
|
||||
uint32_t runAction1(Action a, int arg0);
|
||||
//%
|
||||
uint32_t runAction0(Action a);
|
||||
//%
|
||||
Action mkAction(int reflen, int totallen, int startptr);
|
||||
//%
|
||||
RefRecord* mkClassInstance(int offset);
|
||||
//%
|
||||
void RefRecord_destroy(RefRecord *r);
|
||||
//%
|
||||
void RefRecord_print(RefRecord *r);
|
||||
//%
|
||||
void debugMemLeaks();
|
||||
//%
|
||||
int incr(uint32_t e);
|
||||
//%
|
||||
void decr(uint32_t e);
|
||||
//%
|
||||
uint32_t *allocate(uint16_t sz);
|
||||
//%
|
||||
int templateHash();
|
||||
//%
|
||||
int programHash();
|
||||
//%
|
||||
void *ptrOfLiteral(int offset);
|
||||
//%
|
||||
int getNumGlobals();
|
||||
}
|
||||
|
||||
namespace pxtrt {
|
||||
//%
|
||||
uint32_t ldloc(RefLocal *r) {
|
||||
return r->v;
|
||||
}
|
||||
|
||||
//%
|
||||
uint32_t ldlocRef(RefRefLocal *r) {
|
||||
uint32_t tmp = r->v;
|
||||
incr(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//%
|
||||
void stloc(RefLocal *r, uint32_t v) {
|
||||
r->v = v;
|
||||
}
|
||||
|
||||
//%
|
||||
void stlocRef(RefRefLocal *r, uint32_t v) {
|
||||
decr(r->v);
|
||||
r->v = v;
|
||||
}
|
||||
|
||||
//%
|
||||
RefLocal *mkloc() {
|
||||
return new RefLocal();
|
||||
}
|
||||
|
||||
//%
|
||||
RefRefLocal *mklocRef() {
|
||||
return new RefRefLocal();
|
||||
}
|
||||
|
||||
// All of the functions below unref() self. This is for performance reasons -
|
||||
// the code emitter will not emit the unrefs for them.
|
||||
|
||||
//%
|
||||
uint32_t ldfld(RefRecord *r, int idx) {
|
||||
auto tmp = r->ld(idx);
|
||||
r->unref();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//%
|
||||
uint32_t ldfldRef(RefRecord *r, int idx) {
|
||||
auto tmp = r->ldref(idx);
|
||||
r->unref();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//%
|
||||
void stfld(RefRecord *r, int idx, uint32_t val) {
|
||||
r->st(idx, val);
|
||||
r->unref();
|
||||
}
|
||||
|
||||
//%
|
||||
void stfldRef(RefRecord *r, int idx, uint32_t val) {
|
||||
r->stref(idx, val);
|
||||
r->unref();
|
||||
}
|
||||
|
||||
// Store a captured local in a closure. It returns the action, so it can be chained.
|
||||
//%
|
||||
RefAction *stclo(RefAction *a, int idx, uint32_t v)
|
||||
{
|
||||
//DBG("STCLO "); a->print(); DBG("@%d = %p\n", idx, (void*)v);
|
||||
a->stCore(idx, v);
|
||||
return a;
|
||||
}
|
||||
|
||||
//%
|
||||
void panic(int code)
|
||||
{
|
||||
microbit_panic(code);
|
||||
}
|
||||
|
||||
//%
|
||||
int stringToBool(StringData *s) {
|
||||
if (s == NULL) return 0;
|
||||
if (s->len == 0) {
|
||||
s->decr();
|
||||
return 0;
|
||||
}
|
||||
s->decr();
|
||||
return 1;
|
||||
}
|
||||
|
||||
//%
|
||||
StringData* emptyToNull(StringData *s) {
|
||||
if (!s || s->len == 0)
|
||||
return NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
//%
|
||||
int ptrToBool(uint32_t p) {
|
||||
if (p) {
|
||||
decr(p);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//%
|
||||
RefMap *mkMap() {
|
||||
return new RefMap();
|
||||
}
|
||||
|
||||
//%
|
||||
uint32_t mapGet(RefMap *map, uint32_t key) {
|
||||
int i = map->findIdx(key);
|
||||
if (i < 0) {
|
||||
map->unref();
|
||||
return 0;
|
||||
}
|
||||
uint32_t r = map->data[i].val;
|
||||
map->unref();
|
||||
return r;
|
||||
}
|
||||
|
||||
//%
|
||||
uint32_t mapGetRef(RefMap *map, uint32_t key) {
|
||||
int i = map->findIdx(key);
|
||||
if (i < 0) {
|
||||
map->unref();
|
||||
return 0;
|
||||
}
|
||||
uint32_t r = incr(map->data[i].val);
|
||||
map->unref();
|
||||
return r;
|
||||
}
|
||||
|
||||
//%
|
||||
void mapSet(RefMap *map, uint32_t key, uint32_t val) {
|
||||
int i = map->findIdx(key);
|
||||
if (i < 0) {
|
||||
map->data.push_back({
|
||||
key << 1,
|
||||
val
|
||||
});
|
||||
} else {
|
||||
if (map->data[i].key & 1) {
|
||||
decr(map->data[i].val);
|
||||
map->data[i].key = key << 1;
|
||||
}
|
||||
map->data[i].val = val;
|
||||
}
|
||||
map->unref();
|
||||
}
|
||||
|
||||
//%
|
||||
void mapSetRef(RefMap *map, uint32_t key, uint32_t val) {
|
||||
int i = map->findIdx(key);
|
||||
if (i < 0) {
|
||||
map->data.push_back({
|
||||
(key << 1) | 1,
|
||||
val
|
||||
});
|
||||
} else {
|
||||
if (map->data[i].key & 1) {
|
||||
decr(map->data[i].val);
|
||||
} else {
|
||||
map->data[i].key = (key << 1) | 1;
|
||||
}
|
||||
map->data[i].val = val;
|
||||
}
|
||||
map->unref();
|
||||
}
|
||||
|
||||
//
|
||||
// Debugger
|
||||
//
|
||||
|
||||
//%
|
||||
void* getGlobalsPtr() {
|
||||
return globals;
|
||||
}
|
||||
|
||||
//%
|
||||
void runtimeWarning(StringData *s) {
|
||||
// noop for now
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user