Créez des definitions FORTH en utilisant JavaScript

publication: 17 mars 2023 / mis à jour 20 mars 2023

Read this page in english

 


Le mariage Javascript Forth

eFORTH web fonctionne dans tous les navigateurs web, sur tous les systèmes Windows, Linux, MacOS, Android... Comment est-ce possible?

Le secret de cette extraordinaire polyvalence est très simple: un mariage réussi entre Javascript et FORTH.

La plupart des primitives du langage FORTH sont écrites dans un pseudo-assembleur ou en FORTH. Nous allons voir comment agrandir le vocabulaire web en définissant le mot ellipse:

web definitions 
 
\ draw ellipse in graphic mode 
JSWORD: ellipse { x y rx ry angle div  } 
  context.ctx.ellipse(x, y, rx, ry, Math.PI * 2 * angle / div, 0, 2 * Math.PI); 
~ 
forth definitions 

Ici, le mot ellipse est défini après le mot de création JSWORD:. Le délimiteur de fin de définition est marqué par le caractère ~. Voyons en détail la structure de définition de notre mot ellipse.

Structure d'une définition de mot avec JSWORD:

Commençons par analyser la première ligne de cette définition de ellipse:

JSWORD: ellipse { x y rx ry angle div  }
  context.ctx.ellipse(x, y, rx, ry, Math.PI * 2 * angle / div, 0, 2 * Math.PI);
~

La ligne suivante contient le code Javascript:

JSWORD: ellipse { x y rx ry angle div  }
  context.ctx.ellipse(x, y, rx, ry, Math.PI * 2 * angle / div, 0, 2 * Math.PI);
~

Le code Javascript peut être écrit sur plusieurs lignes:

web definitions 
JSWORD: time@ { -- h m s } 
    let date = new Date(); 
    var hh = date.getHours(); 
    var mm = date.getMinutes(); 
    var ss = date.getSeconds(); 
    return [hh, mm, ss]; 
~ 
 
JSWORD: date@ { -- y m d } 
    let date = new Date(); 
    var yy = date.getFullYear(); 
    var mm = date.getMonth()+1; 
    var dd = date.getUTCDate(); 
    return [yy, mm, dd]; 
~ 
forth definitions 

Nous allons voir en détail comment s'effectue le passage des paramètres.

Passage des paramètres entre eFORTH et JavaScript

Le passage de paramètres exploite les variables locales. Ces variables sont définies entre le mot { et le caractère }. Reprenons l'exemple de la définition du mot ellipse:

JSWORD: ellipse { x y rx ry angle div  } 
  context.ctx.ellipse(x, y, rx, ry, Math.PI * 2 * angle / div, 0, 2 * Math.PI); 
~ 

Ici nous passons cinq paramètres. Ces paramètres sont ceux utilisés ensuite dans une définition en langage FORTH:

web gr 
600 300 window 
$ff0000 color! 
100 100 75 30 0 360 ellipse  fill 
0 color!  stroke 

Il y a quatre cas de passage de paramètres à un mot défini par JSWORD:.

Appel à une fonction JavaSCript sans passage de paramètre. Les accolades sont vides:

JSWORD: beginPath { } 
  context.ctx.beginPath();
~

Appel à une fonction JavaScript avec passage de paramètres en entrée seulement:

JSWORD: lineTo { x y }
  context.ctx.lineTo(x, y);
~

Appel à une fonction JavaScript avec récupération de paramètres en sortie seulement:

JSWORD: viewport@ { -- w h }
  return [context.width, context.height]; 
~

Et enfin, passage de paramètres en entrée et en sortie:

JSWORD: web-type-raw { a n -- yld }
  if (globalObj.write) { 
    var text = GetString(a, n); 
    write(text); 
    return 0; 
  } else { 
    var newline = false; 
    for (var i = 0; i < n; ++i) { 
      var ch = u8[a + i]; 
      if (ch == 10) { newline = true; } 
      context.Emit(ch); 
    } 
    if (newline) { 
      context.Update(); 
    } 
    return newline ? -1 : 0; 
  } 
~

Dans ce dernier cas, on sépare les paramètres d'entrée et de sortie avec --. En temps normal, dans une définition eFORTH classique, ces caractères et ceux qui suivent sont ignorés. Pour JSWORD:, le passage des paramètres doit impérativement respecter une des quatre formes énumérées ci-avant.

Pour les paramètres de sortie, il n'est pas nécessaire d'utiliser des variables JavaScript. Reprenons le code de time@:

web definitions 
JSWORD: time@ { -- h m s } 
    let date = new Date(); 
    var hh = date.getHours(); 
    var mm = date.getMinutes(); 
    var ss = date.getSeconds(); 
    return [hh, mm, ss]; 
~ 
forth definitions 

Ce code peut être réécrit comme suit:

web definitions 
JSWORD: time@ { -- h m s } 
    let date = new Date(); 
    return [date.getHours(), date.getMinutes(), date.getSeconds()]; 
~ 
forth definitions 

La fonction JavaScript return() doit simplement énumérer les valeurs à passer à eFORTH. Les -- doivent être suivis d'autant de paramètres que ceux renvoyés par return().

En conclusion, il est facile d'étendre eFORTH en rajoutant des fonctions de tout type: file, HTTP, etc...

Bonne programmation.


Legal: site web personnel sans commerce / personal site without seling