Array.includes on Narrow Types - TypeScript

The Array.prototype.includes function allows searching for a value within an array. If this value is present, the function returns true! How handy! Of course, TypeScript has proper typings for this JavaScript functionality.

#typescript 

What is GEEK

Buddha Community

Array.includes on Narrow Types - TypeScript
Joel  Hawkins

Joel Hawkins

1632538163

Elk: A Low Footprint JavaScript Engine for Embedded Systems

Elk: a tiny JS engine for embedded systems

Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6. It is designed for microcontroller development. Instead of writing firmware code in C/C++, Elk allows to develop in JavaScript. Another use case is providing customers with a secure, protected scripting environment for product customisation.

Elk features include:

  • Cross platform. Works anywhere from 8-bit microcontrollers to 64-bit servers
  • Zero dependencies. Builds cleanly by ISO C or ISO C++ compilers
  • Easy to embed: just copy elk.c and elk.h to your source tree
  • Very small and simple embedding API
  • Can call native C/C++ functions from JavaScript and vice versa
  • Does not use malloc. Operates with a given memory buffer only
  • Small footprint: about 20KB on flash/disk, about 100 bytes RAM for core VM
  • No bytecode. Interprets JS code directly

Below is a demonstration on a classic Arduino Nano board which has 2K RAM and 30K flash (see full sketch):

Elk on Arduino Nano

JavaScript on ESP32

The Esp32JS Arduino sketch is an example of Elk integration with ESP32. Flash this sketch on your ESP32 board, go to http://elk-js.com, and get a JavaScript development environment instantly! Reloading your script takes a fraction of a second - compare that with a regular reflashing.. Here how it looks like:

The example JS firmware implements:

  • Blinks an LED periodically
  • Connects to the HiveMQ MQTT server
  • Subscribes to the elk/rx topic
  • When an MQTT message is received, sends some stats to the elk/tx topic:

That's screenshot is taken from the MQTT server which shows that we sent a hello JS! message and received stats in response:

Call JavaScript from C

#include <stdio.h>
#include "elk.h"

int main(void) {
  char mem[200];
  struct js *js = js_create(mem, sizeof(mem));  // Create JS instance
  jsval_t v = js_eval(js, "1 + 2 * 3", ~0);     // Execute JS code
  printf("result: %s\n", js_str(js, v));        // result: 7
  return 0;
}

Call C from JavaScript

This demonstrates how JS code can import and call existing C functions:

#include <stdio.h>
#include "elk.h"

// C function that adds two numbers. Will be called from JS
int sum(int a, int b) {
  return a + b;
}

int main(void) {
  char mem[200];
  struct js *js = js_create(mem, sizeof(mem));  // Create JS instance
  jsval_t v = js_import(js, sum, "iii");        // Import C function "sum"
  js_set(js, js_glob(js), "f", v);              // Under the name "f"
  jsval_t result = js_eval(js, "f(3, 4);", ~0); // Call "f"
  printf("result: %s\n", js_str(js, result));   // result: 7
  return 0;
}

Supported features

  • Operations: all standard JS operations except:
    • !=, ==. Use strict comparison !==, ===
    • No ternary operator a ? b : c
    • No computed member access a[b]
  • Typeof: typeof('a') === 'string'
  • While: while (...) { ... }
  • Conditional: if (...) ... else ...
  • Simple types: let a, b, c = 12.3, d = 'a', e = null, f = true, g = false;
  • Functions: let f = function(x, y) { return x + y; };
  • Objects: let obj = {f: function(x) { return x * 2}}; obj.f(3);
  • Every statement must end with a semicolon ;
  • Strings are binary data chunks, not Unicode strings: 'Київ'.length === 8

Not supported features

  • No var, no const. Use let (strict mode only)
  • No do, switch, for. Use while
  • No => functions. Use let f = function(...) {...};
  • No arrays, closures, prototypes, this, new, delete
  • No standard library: no Date, Regexp, Function, String, Number

Performance

Since Elk parses and interprets JS code on the fly, it is not meant to be used in a performance-critical scenarios. For example, below are the numbers for a simple loop code on a different architectures.

let a = 0;        // 97 milliseconds on a 16Mhz 8-bit Atmega328P (Arduino Uno and alike)
while (a < 100)   // 16 milliseconds on a 48Mhz SAMD21
  a++;            //  5 milliseconds on a 133Mhz Raspberry RP2040
                  //  2 milliseconds on a 240Mhz ESP32

Build options

Available preprocessor definitions:

NameDefaultDescription
JS_EXPR_MAX20Maximum tokens in expression. Expression evaluation function declares an on-stack array jsval_t stk[JS_EXPR_MAX];. Increase to allow very long expressions. Reduce to save C stack space.
JS_DUMPundefinedDefine to enable js_dump(struct js *) function which prints JS memory internals to stdout

Note: on ESP32 or ESP8266, compiled functions go into the .text ELF section and subsequently into the IRAM MCU memory. It is possible to save IRAM space by copying Elk code into the irom section before linking. First, compile the object file, then rename .text section, e.g. for ESP32:

$ xtensa-esp32-elf-gcc $CFLAGS elk.c -c elk.tmp
$ xtensa-esp32-elf-objcopy --rename-section .text=.irom0.text elk.tmp elk.o

API reference

js_create()

struct js *js_create(void *buf, size_t len);

Initialize JS engine in a given memory block. Elk will only use that memory block to hold its runtime, and never use any extra memory. Return: a non-NULL opaque pointer on success, or NULL when len is too small. The minimum len is about 100 bytes.

The given memory buffer is laid out in the following way:

  | <-------------------------------- len ------------------------------> |
  | struct js, ~100 bytes  |   runtime vars    |    free memory           | 

js_eval()

jsval_t js_eval(struct js *, const char *buf, size_t len);

Evaluate JS code in buf, len and return result of the evaluation. During the evaluation, Elk stores variables in the "runtime" memory section. When js_eval() returns, Elk does not keep any reference to the evaluated code: all strings, functions, etc, are copied to the runtime.

Important note: the returned result is valid only before the next call to js_eval(). The reason is that js_eval() triggers a garbage collection. A garbage collection is mark-and-sweep, run before every top-level statement gets executed.

The runtime footprint is as follows:

  • An empty object is 8 bytes
  • Each object property is 16 bytes
  • A string is 4 bytes + string length, aligned to 4 byte boundary
  • A C stack usage is ~200 bytes per nested expression evaluation

js_str()

const char *js_str(struct js *, jsval_t val);

Stringify JS value val and return a pointer to a 0-terminated result. The string is allocated in the "free" memory section. If there is no enough space there, an empty string is returned. The returned pointer is valid until the next js_eval() call.

js_import()

jsval_t js_import(struct js *js, uintptr_t funcaddr, const char *signature);

Import an existing C function with address funcaddr and signature signature. Return imported function, suitable for subsequent js_set().

  • js: JS instance
  • funcaddr: C function address: (uintptr_t) &my_function
  • signature: specifies C function signature that tells how JS engine should marshal JS arguments to the C function. First letter specifies return value type, following letters - parameters:
    • b: a C bool type
    • d: a C double type
    • i: a C integer type: char, short, int, long
    • s: a C string, a 0-terminated char *
    • j: a jsval_t
    • m: a current struct js *. In JS, pass null
    • p: any C pointer
    • v: valid only for the return value, means void

The imported C function must satisfy the following requirements:

  • A function must have maximum 6 parameters
  • C double parameters could be only 1st or 2nd. For example, function void foo(double x, double y, struct bar *) could be imported, but void foo(struct bar *, double x, double y) could not
  • C++ functions must be declared as extern "C"
  • Functions with float params cannot be imported. Write wrappers with double

Here are some example of the import specifications:

  • int sum(int) -> js_import(js, (uintptr_t) sum, "ii")
  • double sub(double a, double b) -> js_import(js, (uintptr_t) sub, "ddd")
  • int rand(void) -> js_import(js, (uintptr_t) rand, "i")
  • unsigned long strlen(char *s) -> js_import(js, (uintptr_t) strlen, "is")
  • char *js_str(struct js *, js_val_t) -> js_import(js, (uintptr_t) js_str, "smj")

In some cases, C APIs use callback functions. For example, a timer C API could specify a time interval, a C function to call, and a function parameter. It is possible to marshal JS function as a C callback - in other words, it is possible to pass JS functions as C callbacks.

A C callback function should take between 1 and 6 arguments. One of these arguments must be a void * pointer, that is passed to the C callback by the imported function. We call this void * parameter a "userdata" parameter.

The C callback specification is enclosed into the square brackets [...]. In addition to the signature letters above, a new letter u is available that specifies userdata parameter. In JS, pass null for u param. Here is a complete example:

#include <stdio.h>
#include "elk.h"

// C function that invokes a callback and returns the result of invocation
int f(int (*fn)(int a, int b, void *userdata), void *userdata) {
  return fn(1, 2, userdata);
}

int main(void) {
  char mem[500];
  struct js *js = js_create(mem, sizeof(mem));
  js_set(js, js_glob(js), "f", js_import(js, f, "i[iiiu]u"));
  jsval_t v = js_eval(js, "f(function(a,b,c){return a + b;}, 0);", ~0);
  printf("result: %s\n", js_str(js, v));  // result: 3
  return 0;
}

js_set(), js_glob(), js_mkobj()

jsval_t js_glob(struct js *);   // Return global object
jsval_t js_mkobj(struct js *);  // Create a new object
void js_set(struct js *, jsval_t obj, const char *key, jsval_t val);  // Assign property to an object

These are helper functions for assigning properties to objects. The anticipated use case is to give names to imported C functions.

Importing a C function sum into the global namespace:

  jsval_t global_namespace = js_glob(js);
  jsval_t imported_function = js_import(js, (uintptr_t) sum, "iii");
  js_set(js, global_namespace, "f", imported_function);

Use js_mkobj() to create a dedicated object to hold groups of functions and keep a global namespace tidy. For example, all GPIO related functions can go into the gpio object:

  jsval_t gpio = js_mkobj(js);              // Equivalent to:
  js_set(js, js_glob(js), "gpio", gpio);    // let gpio = {};

  js_set(js, gpio, "mode",  js_import(js, (uintptr_t) func1, "iii");  // Create gpio.mode(pin, mode)
  js_set(js, gpio, "read",  js_import(js, (uintptr_t) func2, "ii");   // Create gpio.read(pin)
  js_set(js, gpio, "write", js_import(js, (uintptr_t) func3, "iii");  // Create gpio.write(pin, value)

js_usage()

int js_usage(struct js *);

Return memory usage percentage - a number between 0 and 100.

Download Details:
Author: cesanta
Download Link: Download The Source Code
Official Website: https://github.com/cesanta/elk 
License: GPLv2

#javascript

 

Verdie  Murray

Verdie Murray

1636240140

What Is The Main Difference Of TYPES Vs INTERFACES in TypeScript

TypeScript has two ways of declaring structures of your objects in the form of  #types (type aliases) and #interfaces.

In this lesson we will look at the technical differences between these two, when you should use which, along with real world #TypeScript code analysis, and community thoughts

#typescript 

Array.includes on Narrow Types - TypeScript

The Array.prototype.includes function allows searching for a value within an array. If this value is present, the function returns true! How handy! Of course, TypeScript has proper typings for this JavaScript functionality.

#typescript 

Cでのエスケープシーケンス

このチュートリアルでは、エスケープシーケンスとは何か、およびそれをcプログラミングで使用する方法を学習します。

エスケープシーケンスは  文字または文字列リテラル内で使用された場合はそれ自体を表さないが、直接表すことが困難または不可能な別の文字または文字のシーケンスに変換される文字のシーケンスです。

Cのエスケープシーケンスのリスト

エスケープシーケンス意味
\NSアラームまたはビープ音
\NSバックスペース
\NSフォームフィード
\NS改行
\NSキャリッジリターン
\NSタブ(水平)
\ v垂直タブ
\\バックスラッシュ
\ '一重引用
\」二重引用符
\?疑問符
\ nnn8進数
\ xhh16進数
\ 0ヌル

cのエスケープシーケンス文字の基本的な例を次に示します。以下に示すように:

  • \ n エスケープシーケンス
  • \ t エスケープシーケンス
  • \ b エスケープシーケンス
  • \ aエスケープシーケンス

\ n エスケープシーケンス

#include <stdio.h>
int main()
{
printf("Hello \nProgrammer ");
return 0;
}

出力

Hello
Programmer

\ t エスケープシーケンス

#include <stdio.h>
int main()
{
printf("Hello\tProgrammer ");
return 0;
}

出力

Hello        Programmer

\ b エスケープシーケンス

#include <stdio.h>
int main()
{
printf("Hello\b Programmer ");
return 0;
}

出力

Hell Programmer

:- \ b は文字をバックスペースすることに注意してください。

\ a エスケープシーケンス

#include <stdio.h>
int main()
{
printf("This will make a bell sound\a ");
return 0;
}

出力

This will make a bell sound

注意:- \ a はベルの音を鳴らします🔔

結論

したがって、この記事では、cで利用可能なさまざまなエスケープシーケンスについて詳しく説明しました。また、この記事では、いくつかを適切な例で説明することにより、さまざまなエスケープシーケンスについて説明しました。

リンク: https://www.tutsmake.com/escape-sequence-in-c/

#csharp 

Cloudy tech

Cloudy tech

1637160169

Pattern Programs in C

Here in this article, we will cover the top example programs in C. Also, the rationale is all-inclusive and can be applied to various programming dialects, like C++, Java, and Python.

List of pattern programs in c:

Inverted Hollow Half Pyramid in C

height = 5

Preview

* * * * * *
*        *
*     *
*  *
*

Program

#include<stdio.h>   
  
int main()  
{  
    int height,i,j;  
    printf("Enter the height of Pyramid: ");  
    scanf("%d",&height);  
    for(i=height;i>=1;i--)  
    {  
      for( j=1;j<=i;j++)  
      {  
         if(j==1 || j==i || i==height)  
          printf("*");  
          else  
          printf(" ");  
      }  
      printf("\n");  
    }  
    return 0;  
}

Output

Enter the height of Pyramid: 7
*******
*    *
*   *
*  *
* *
**
*

 Full Hollow Inverted Pyramid in C

height: 5

Preview

* * * * * * * 
 *         *
  *       *
   *    *
     *

Program

#include <stdio.h>  
  
int main()  
{  
    int height,space=1,i,j,k;  
    printf("Enter the height of pyramid: ");  
    scanf("%d",&height);  
  
   for( i=height;i>=1;i--)  
   {  
       for( j=1;j<space;j++)  
       {  
           printf(" ");  
       }  
       for( k=1;k<=2*i-1;k++)  
       {  
          if(k==1 || k==2*i-1 || i==height)  
           printf("*");  
           else  
           printf(" ");  
       }  
       space++;  
     
      printf("\n");  
    }  
    return 0;  
}

Output

Enter the height of pyramid: 6
***********
 *       *
  *     *
   *   *
    * *
     *

Half Diamond Star Pattern in C

max stars: 7

Preview

*
**
***
****
*****
******
*******
******
*****
****
***
**
*

Program

#include<stdio.h>
  
int main()  
{  
    int max_stars,i,j;  
    printf("Enter the width of diamond: ");  
    scanf("%d",&max_stars);  
for( i=1;i<=max_stars;i++)  
{  
  for( j=1;j<=i;j++) { printf("*"); } printf("\n"); } for( i=max_stars-1;i>=1;i--)  
 {  
   for( j=1;j<=i;j++)  
   {  
     printf("*");  
   }  
   printf("\n");  
 }    
     
    return 0;  
}

Output

Enter the width of diamond: 7
*
**
***
****
*****
******
*******
******
*****
****
***
**
*

Solid Full Diamond Pattern in C

width: 7

Preview

      *
     ***
    *****
   *******
    *****
     ***
      *

Program

#include<stdio.h>  
int main(void) {  
  int width, space, stars, i, j, k;  
  printf("Enter the width of diamonds: ");  
  scanf("%d",&width);  
  space=width-1;  
   stars=1;  
  for( i=1;i<=width;i++)  
  {  
    for( j=1;j<=space;j++)  
    {  
      printf(" ");  
    }  
    for( k=1;k<=stars;k++) { printf("*"); } if(space>i)  
    {  
      space=space-1;  
      stars=stars+2;  
    }  
    if(space<i)  
    {  
      space=space+1;  
      stars=stars-2;  
    }  
    printf("\n");  
  }  
  return 0;}

Output

Enter the width of diamonds: 7
      *
     ***
    *****
   *******
    *****
     ***
      *

Conclusion

Those were some of the most popular pattern programs in C. Let us know which is your favorite.