• Aucun résultat trouvé

[PDF] Outils de base pour la programmation avec le langage Forth | Cours informatique

N/A
N/A
Protected

Academic year: 2021

Partager "[PDF] Outils de base pour la programmation avec le langage Forth | Cours informatique"

Copied!
25
0
0

Texte intégral

(1)

Logique, math´ematiques,informatique

Eric Abouaf

15 juin 2005

Etude d’un interpr´

eteur Forth

Ann´ee Scolaire 2004-2005

esum´

e

Ce document est le rapport d’un mini-projet r´

ealis´

e pour un cours

d’approfondissement. Il s’agit de l’impl´

ementation d’un interpr´

eteur

pour un langage proche du Forth. Le programme est ´

ecrit en C et

les sources sont disponibles `

a la fin de ce document. Une petite

in-troduction au langage Forth sera dispens´

ee afin de comprendre la

probl´

ematique de l’interpreteur.

(2)

Table des mati`

eres

1

Introduction

3

1.1

Un mot pour commencer . . . .

3

1.2

Objectif . . . .

3

1.3

Choix du forth

. . . .

3

1.4

Port´

ee . . . .

4

1.5

Organisation du document . . . .

4

2

Introduction au langage Forth

5

2.1

Introduction . . . .

5

2.2

La Pile de donn´

ees . . . .

5

2.3

Notions de mot et de dictionnaire . . . .

6

2.4

Les variables . . . .

6

3

efinition du Micro-forth

7

3.1

Simplifications . . . .

7

3.2

El´

ements repris du forth . . . .

7

4

Impl´

ementation d’un syst`

eme Micro-forth

8

4.1

Choix dans l’impl´

ementation . . . .

8

4.2

El´

ements d’un interpr´

eteur . . . .

8

4.2.1

Structure du dictionnaire . . . .

8

4.2.2

La pile de donn´

ees . . . .

9

4.2.3

La pile de retour . . . .

10

4.2.4

Le buffer d’entr´

ee (input buffer) . . . .

10

4.3

Structure de l’interpr´

eteur . . . .

10

4.3.1

Mots imm´

ediats . . . .

10

4.3.2

Registre IP (instruction pointer) . . . .

11

4.3.3

Fonctionnement interne

. . . .

11

5

Conclusion

12

A Bibliographie

13

(3)

1

Introduction

1.1

Un mot pour commencer

Ce document a ´

et´

e r´

ealis´

e pour le cours d’approfondissement ”Logique,

math´

ematiques, informatique” dispens´

e `

a l’Ecole Centrale Paris par Mr.

Pas-cal Laurent en mai-juin 2005.

Vous pouvez l’utiliser ou le distribuer comme vous le souhaitez, mais merci

de conserver l’int´

egralit´

e du document afin qu’il garde son sens. Ce document

n’ayant pas ´

et´

e relu par une personne plus comp´

etente, je ne garantis pas la

eracit´

e de l’ensemble du document.

L’adresse originale de ce travail est : http ://www.neyric.com/comp/forth/

Vous pouvez me contacter pour toute remarque ou question `

a propos de ce

document `

a l’adresse suivante : eric.abouaf@student.ecp.fr

Le langage implant´

e est en grande partie bas´

e sur la d´

efinition du langage

Forth de l’American National Standard for Information Systems datant du

24 Mars 1994. [1] Particuli`

erement les sections 1 `

a 6, (Les sections 7 `

a 17

efinissent des word sets suppl´

ementaires non pris en compte dans micro

forth.) mˆ

eme si le jeu de mots est bien plus limit´

e (pour l’instant !).

1.2

Objectif

Ce document a pour objectif de se familiariser avec la r´

ealisation d’un

interpr´

eteur pour un langage informatique afin de comprendre les concepts

de bases d’un compilateur.

1.3

Choix du forth

J’ai choisit le langage forth pour plusieurs raisons :

– interpr´

eteur tr`

es petit (dictionnaire des core words tr`

es succin),

– portabilit´

e du langage (tr`

es pr`

es du langage machine et pourtant

por-table sur n’importe quelle ”machine virtuelle” forth),

(4)

1.4

Port´

ee

Ce document d´

efinit l’impl´

ementation d’un syst`

eme forth minimaliste

ne r´

epondant pas au format d´

efini par l’ANS. Sa vocation est purement

´

educative bien que la plupart des ´

el´

ements pr´

esent´

es peuvent servir de base

`

a la cr´

eation d’une impl´

ementation compl`

ete du langage forth.

Inclusions :

– ce document d´

ecrit le langage ”Micro-forth”,

– ce document d´

ecrit l’impl´

ementation d’un syst`

eme Micro-forth capable

de d´

ecrire le langage Micro-forth. Les deux noms seront confondus par

la suite.

– ce document s’int´

eresse particuli`

erement au coeur du syst`

eme forth et

au mode d’execution.

Exclusions :

– ce document ne vise pas `

a impl´

ementer le langage forth tel que d´

efinit

par l’ANS. Pour plus d’informations, sur le langage forth, je vous dirige

vers le site de l’ANS [1],

– pour toutes les exclusions du langage forth dans Micro-forth, je vous

invite `

a vous rendre partie 3.1 pour une lire la simplification du langage.

1.5

Organisation du document

Ce document va pr´

esenter le cheminement pour parvenir `

a l’impl´

ementation

d’un syst`

eme forth simplifi´

ee. Le but est de montrer quels ´

el´

ements du

lan-gage permettent d’expliquer les choix r´

ealis´

es lors de l’impl´

ementation.

(5)

2

Introduction au langage Forth

Si vous ˆ

etes d´

ej`

a familiaris´

e avec le forth, vous pouvez sauter cette partie.

2.1

Introduction

Le Forth est un langage avec une syntaxe assez d´

eroutante mais tr`

es

efficace. C’est un langage fonctionnel qui se base sur une pile de donn´

ee pour

passer les arguments aux fonctions. Ainsi, les fonctions sont repr´

esent´

es par

des simples mots, tout comme les variables, les constantes ou les op´

erateurs

de structures.

2.2

La Pile de donn´

ees

La pile de donn´

ees est une pile LIFO (Last Input First Output) qui stocke

les param`

etres d’appel d’un mot. Exemple :

2 3 + .

Les nombres 2 puis 3 sont empil´

es puis le mot ’+’ enl`

eve ces deux nombres

de la pile de donn´

ees et place le r´

esultat de l’op´

eration au sommet de la pile.

Le plus effectue l’addition puis le ’.’ affiche le r´

esultat. On utilise g´

en´

eralement

une notation bien pratique pour d´

ecrire l’action d’un mot sur la pile :

Mot ( before -- after )

Pour notre exemple pr´

ec´

edent :

+ ( a b -- a+b )

Il existe beaucoup de mots de manipulations de la pile. Citons parmi eux :

– DUP : duplique le sommet de la pile

– DROP : enl`

eve l’´

el´

ement au sommet de la pile

– OVER : duplique l’avant-dernier ´

el´

ement de la pile

– etc...

(6)

2.3

Notions de mot et de dictionnaire

L’ensemble des mots forth forme un dictionnaire. Il existe deux types

de mots :

– les mots de base du forth (appell´

es core-words)

– les mots d´

efinis par l’utilisateur

Pour d´

efinir un nouveau mot, on utilise la syntaxe suivante :

: nouveau_mot definition ;

Voici quelques exemples de d´

efinitions :

: carre dup * ; ( a -- a^2)

( Calcul le carre d’un nombre )

: cube dup carre * ; ( a -- a^3)

( Calcul le cube d’un nombre )

Certains mots de base peuvent ´

egalement ˆ

etre d´

efinis `

a l’aide d’autres

mots (swap ´

echange les deux nombres au sommet de la pile, rot effectue une

rotation entre les trois premiers ´

el´

ements) :

: over swap dup rot rot ;

2.4

Les variables

Les variables sont ´

egalement des mots. Lors de leur execution, ces mot

mettent sur la pile l’adresse de l’espace m´

emoire r´

eserv´

e pour cette variable.

Deux mots deviennent alors fondamentaux :

@ "at" ( addr -- value )

Ajoute sur la pile le contenu de addr.

! "store" ( value addr -- )

Ecrit value `

a l’adresse addr.

Voici un petit exemple pour illustrer qui illustre la cr´

eation, l’affectation

et la lecture d’une variable :

variable test

5 test !

test @ .

(7)

3

efinition du Micro-forth

3.1

Simplifications

Le but du micro-forth n’est pas de concevoir un nouveau langage r´

evolutionnaire

ni d’´

etudier ses optimisations. L’impl´

ementation souffira donc de nombreuses

pertes de vitesse par rapport au langage forth dans un souci de temps. Voici

une liste exhaustive de toute les simplifications :

– liste des core-words tr`

es simplifi´

ee,

– calculs sur 32 bits uniquement (plus facile pour l’adressage),

– mots du core d´

efini en forth (perte de performance originellement gagn´

e

en jouant sur un jeu d’instructions plus ´

elev´

e, exemple : 1+ correspond

normalement `

a ”inc” alors que 1 + effectue deux instructions pour le

processeur),

– nombre non-sign´

es uniquement,

– interpr´

eteur case-sensitive,

– base 10 pour l’affichage de toutes les valeurs.

3.2

El´

ements repris du forth

La plupart des ´

el´

ements fondamentaux du forth sont repris, en

l’occu-rence :

– la syntaxe,

– les mots de manipulations de pile,

– la pile de retour (cf. 4.2.2),

– le buffer d’entr´

ee,

– la structure du dictionnaire.

Tous ces ´

el´

ements sont accessibles par l’utilisateur et forment ´

egalement

le ”coeur” du syst`

eme forth, `

a l’aide d’un algorithme relativement simple

ecrit dans la prochaine partie.

(8)

4

Impl´

ementation d’un syst`

eme Micro-forth

4.1

Choix dans l’impl´

ementation

Voici `

a nouveau quelques simplifications, cette fois-ci dans

l’environne-ment forth :

– aucune variable d’environnement forth,

– aucun ´

el´

ement de stockage (plus tard, rajouter la lecture de fichier).

La sortie standard sera toujours l’´

ecran, et l’entr´

ee standard sera le clavier.

4.2

El´

ements d’un interpr´

eteur

Nous allons d´

etailler dans cette partie toutes les sous-fonctions d’un

in-terpr´

eteur forth. Ensuite, nous ´

etudierons le fonctionnement conjugu´

e de

toutes ces sous-parties.

4.2.1

Structure du dictionnaire

Le dictionnaire contient les d´

efinitions de l’ensemble des mots du

lan-gage. C’est une zone m´

emoire r´

eserv´

ee lors de l’initialisation du syst`

eme. Le

dictionnaire a la structure suivante :

last_def

|

-| Word1 -| Word2 -| Word3 -| Word 4 -| ...

-^

^

^

dp0

fence

dp

Le dictionnaire contient 4 pointeurs essentiels `

a l’´

execution ou `

a la

com-pilation de nouveaux mots :

– dp0 : pointeur vers le d´

ebut du dictionnaire,

– dp : pointeur vers la premi`

ere cellule libre du dictionnaire,

– fence : non utilis´

e par Micro-forth (cf. [2] pour plus d’informations),

– last def : adresse du dernier mot d´

efinit.

(9)

Chaque mot a alors la structure suivante :

---<-PFA = Parameter Field Address

| Flags |

name_length

|

---|

Word Name

|

---|

PFA Previous Word

|

---<-CFA = Code Field Address

|

Code Word

|

---|

|

|

Data

|

|

|

---– flags : indique si le mot est de type IMMEDIATE ou non (cf. 4.3),

– name lengh : longueur du nom du mot,

– word name : chaˆıne de charact`

eres repr´

esentant le mot (null-terminated),

– pfa previous word : adresse du champ de param`

etre de la d´

efinition

pr´

ec´

edente (sert au parcours du dictionnaire lors de la recherche d’un

mot),

– code word : indique le mot qui servira `

a traduire data (le mot peut ˆ

etre

un mot du core, une definition, une variable ou une constante),

– data : contient la d´

efinition du mot ou la valeur d’une variable.

Plus pr´

ecisement, dans le cas d’une d´

efinition, le champ data comporte

la liste des cfa des mots qui le composent.

Pour reprendre notre exemple pr´

ec´

edent, le champ data de ”carre” contient

le cfa de dup suivit du cfa de *.

4.2.2

La pile de donn´

ees

La pile de donn´

ees est l’´

el´

ement le plus simple du forth. Nous avons

ej`

a vu son fonctionnement (cf. 2.2). Son impl´

ementation consiste `

a allouer

l’espace n´

ecessaire. Deux poiteurs sont n´

ecessaires pour manipuler cette pile :

– sp0 : pointeur vers le d´

ebut de la pile de donn´

ees,

– sp : poiteur vers le prochain emplacement libre sur la pile.

Le nombre d’´

el´

ements sur la pile peut alors ˆ

etre calcul´

e par (sp-sp0)/4 (on

divise par 4 car tous les ´

el´

ements de la pile font 32 bits).

(10)

4.2.3

La pile de retour

La pile de retour est un ´

el´

ement essentiel du coeur de forth. Elle contient

les adresses de retour lors de l’execution de mot. L’utilisteur peut y acc´

eder

par l’interm´

ediaire des mots ¿R et R¿ qui transferent le sommet entre la pile

de donn´

ees et la pile de retour. Cependant, si le syst`

eme trouve une valeur

qui n’est pas une adresse de retour au sommet de la pile, l’interpr´

eteur risque

de planter. Leur utilisation requiert donc de nombreuses pr´

ecautions :

– un programme ne doit pas acc´

eder aux valeurs de la pile de retour par

R¿ s’il n’a pas plac´

e au pr´

ealable une valeur par ¿R,

– un programme ne doit pas acc´

eder aux valeurs de la pile de retour

plac´

ees avant une boucle depuis l’interieur de cette boucle,

– toutes les valeurs stock´

es sur la pile de retour dans une boucle doivent

ˆ

etre ot´

ees avant la fin de la boucle,

– toutes les valeurs plac´

ees par ¿R doivent ˆ

etre retir´

ees avant la fin de

l’execution de l’input buffer.

4.2.4

Le buffer d’entr´

ee (input buffer)

Le buffer d’entr´

ee est un espace servant de stockage `

a la chaˆıne de

cha-ract`

eres entr´

ee par l’utilisateur. Cette chaˆıne sera analys´

ee, d´

ecoup´

ee en mots

qui seront execut´

es. Une variable ¿IN permet de savoir la position du parser

lors de l’interpr´

etation.

4.3

Structure de l’interpr´

eteur

4.3.1

Mots imm´

ediats

Les mots imm´

ediats sont un peu particuliers et servent lors de la

compila-tion de nouveaux mots. Ils modifient le flux de traitement du buffer d’entr´

ee.

Exemple : le mot ” :” est un mot imm´

ediat et execut´

e `

a la compilation. Ce

mot va chercher le prochain mot dans l’input buffer et cr´

ee une entˆ

ete dans

le dictionnaire. Il passe ´

egalement le mode de l’interpr´

eteur de ex´

ecution

`

a compilation du nouveau mot. Un mot imm´

ediat situ´

e `

a l’interieur d’une

efinition ne sera pas compil´

e dans cette d´

efinition. Ce sont de v´

eritables

”agents de contrˆ

ole” de la compilation.

(11)

4.3.2

Registre IP (instruction pointer)

Le registre IP contient l’adresse du prochain mot `

a ex´

ecuter. Dans le cas

de notre exemple, le syst`

eme effectuera la tˆ

ache suivante : : carre dup * ; 1.

Place le cfa de carre sur la pile de retour.

2. IP prend la valeur du premier ´

el´

ement sur la pile de retour.

3. Ajout de IP+4 sur la pile de retour.

4. Execution de [IP] (ici dup).

5. D´

epile un ´

el´

ement de la pile de retour dans IP.

6. Execution de [IP] (*).

7. Plus rien sur la pile de retour, donc on rend la main.

4.3.3

Fonctionnement interne

I) R´

ecup`

ere le prochain mot du buffer d’entr´

ee

II) Chercher le mot dans le dictionnaire

1. Si il est trouv´

e

i) Si le mode est COMPILATION:

- Execute le mot s’il est marqu´

e IMMEDIATE

- Sinon, ajouter son cfa `

a la suite de la

efinition du dictionnaire

ii) Si le mode est INTERPRETATION:

- Execute le mot

2. S’il n’est pas trouv´

e

i) Si c’est un nombre

- Ajouter `

a la pile de donn´

ees en INTERPRETATION

- Ajouter `

a la d´

efinition, pr´

ec´

ed´

e du mot (VALUE)

en mode COMPILATION

(12)

5

Conclusion

Grˆ

ace `

a une structure ing´

enieuse, le forth est un langage n´

ecessitant tr`

es

peu de ressources. Il est de plus extrement rapide puisqu’une fois compil´

e,

l’ex´

ecution ne fait qu’une s´

erie de ”jump” de plus que le code assembleur

lui-mˆ

eme. Finalement, une fois familiaris´

e avec la structure interne d’un

in-terpr´

eteur forth, on se rend compte que celui-ci fonctionne comme un

en-semble de r`

egles de Markov pour du code executable. En effet, lors de

l’execution d’un mot, on ne fait que remplacer ce mot par sa d´

efinition

jus-qu’`

a tomber sur une succession de mots de base directement executables.

L’interpr´

eteur pr´

esent´

e en annexe n’est pas encore compl`

etement fonctionnel

puisque le vocabulaire de base est tr`

es limit´

e. Cependant, beaucoup de mot

peuvent se d´

efinir `

a l’aide de la pile de retour, comme le do ... loop qui sert

`

a faire les boucles :

: do

compile swap

compile >r

compile >r

here ; immediate

: loop

compile r>

compile 1+

compile r>

compile 2dup

compile >r

compile >r

compile <

compile 0=

compile 0branch

here - ,

compile r>

compile r>

(13)

Annexes

A

Bibliographie

[1] http ://www.taygeta.com/forth/dpans.html

[2] http ://forth.free.fr/livres/guide/guide.htm

B

Code Source de Microforth Interpreter

Voici le code source de l’interpreteur.

Il peut ˆ

etre t´

el´

echarg´

e sous forme informatique `

a l’adresse suivante :

http ://www.neyric.com/comp/forth/microforth.tar.gz

: : : : : : : : : : : : : : main . c : : : : : : : : : : : : : : /∗ main . c M i c r o f o r t h i n t e r p r e t e r By E r i c A b o u a f n e y r i c @ v i a . e c p . f r J u n e 1 0 , 2 0 0 5 T h i s f i l e c o n t a i n s t h e main i n i t i a l i s a t i o n s and t h e i n f i n i t e l o o p . ∗/ #i n c l u d e < s t d i o . h> // p r i n t f #i n c l u d e < s t d l i b . h> // e x i t #i n c l u d e ” main . h ” #i n c l u d e ” d i c t i o n n a r y . h ” #i n c l u d e ” s t a c k s . h ” #i n c l u d e ” i n p u t b u f f e r . h ” #i n c l u d e ” p a r s e r . h ” // i n i t ( ) // // F u n c t i o n : P r i n t s i n f o s // A l l o c a t e s s p a c e f o r s t a c k s and d i c t i o n n a r y // A r g u m e n t s : None // R e t u r n : N o t h i n g // void i n i t ( ) { // P r i n t s i n f o s p r i n t f ( ” M i c r o f o r t h i n t e r p r e t e r \n ” ) ; p r i n t f ( ”By E r i c Abouaf \n ” ) ; p r i n t f ( ” n e y r i c @ v i a . e c p . f r \n ” ) ; p r i n t f ( ” June , 2 0 0 5 \ n\n ” ) ; // A l l o c a t e s s p a c e f o r i n p u t b u f f e r , d i c t i o n n a r y , s t a c k s i n i t i n p u t b u f f e r ( ) ; i n i t d i c t i o n n a r y ( ) ; i n i t s t a c k s ( ) ; } // f r e e m e m ( ) // // F u n c t i o n : F r e e s t h e a l l o c a t e d memory // A r g u m e n t s : None // R e t u r n : N o t h i n g // void f r e e m e m ( )

(14)

{ // F r e e a l l o c a t e d memory f o r d i c t i o n n a r y , i n p u t b u f f e r , s t a c k s f r e e i n p u t b u f f e r ( ) ; f r e e d i c t i o n n a r y ( ) ; f r e e s t a c k s ( ) ; } // main ( ) // // F u n c t i o n : E n t r y p o i n t o f t h e a p p l i c a t i o n // P a r a m e t e r s : None // R e t u r n : 0 ( a l w a y s ) // i n t main ( void ) { // A l l o c a t e s memory i n i t ( ) ; // I n f i n i t e l o o p f o r ( ; ; ) { // P r i n t p r o m p t p r i n t f ( ” OK\n ” ) ; // F i l l s i n p u t b u f f e r f i l l i n p u t b u f f e r ( ) ; // C a l l t h e p a r s e r p a r s e r ( ) ; } // N e v e r c a l l e d , f o r c o m p i l a t i o n return 0 ; } : : : : : : : : : : : : : : main . h : : : : : : : : : : : : : : void f r e e m e m ( ) ; : : : : : : : : : : : : : : d i c t i o n n a r y . c : : : : : : : : : : : : : : /∗ d i c t i o n n a r y . c M i c r o f o r t h i n t e r p r e t e r By E r i c A b o u a f n e y r i c @ v i a . e c p . f r J u n e 1 0 , 2 0 0 5 T h i s f i l e c o n t a i n s t h e main d i c t i o n n a r y v a r i a b l e s a n s a l l o c a t e s p a c e f o r t h e d i c t i o n n a r y . The s t r u c t u r e o f t h e d i c t i o n n a r y i s t h e f o l l o w i n g : l a s t d e f | −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− − − | Word1 | Word2 | Word3 | Word 4 | . . . −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− − − ˆ ˆ ˆ d p 0 f e n c e dp d p 0 : s t a r t o f t h e d i c t i o n n a r y dp : f i r s t c e l l a v a i l a b l e a t t h e e n d o f t h e d i c t i o n n a r y f e n c e : b e f o r e f e n c e , t h e i n t e r p r e t e r c a n n o t FORGET l a s t d e f : A d r e s s o f t h e l a s t d e f i n i t i o n The s t r u c t u r e o f a w o r d w i t h i n t h e d i c t i o n n a r y i s t h e f o l l o w i n g : PFA −−−−−−−−−−−−−−−−−−−−−−−−− | F l a g s | n a m e l e n g t h | −−−−−−−−−−−−−−−−−−−−−−−−− | Word Name | −−−−−−−−−−−−−−−−−−−−−−−−− | P r e v i o u s Word | P o i n t e r t o t h e PFA o f t h e p r e v i o u s w o r d CFA −−−−−−−−−−−−−−−−−−−−−−−−−

| Code Word | EXEC WORD | COLON WORD −−−−−−−−−−−−−−−−−−−−−−−−−

(15)

| | | D a t a | | | −−−−−−−−−−−−−−−−−−−−−−−−− ∗/ #i n c l u d e ” d i c t i o n n a r y . h ” #i n c l u d e ” c o r e . h ” #d e f i n e DICO SIZE 8 0 0 0 #d e f i n e EXEC WORD 0 #d e f i n e COLON WORD 1 #d e f i n e IMMEDIATE WORD 32 void ∗ dp0 ; void ∗ dp ; void ∗ f e n c e ; void ∗ l a s t d e f ; // i n i t d i c t i o n n a r y ( ) // // F u n c t i o n : A l l o c a t e s memory f o r t h e d i c t i o n n a r y // and i n i t i a t e d i c t i o n n a r y p o i n t e r s // A r g u m e n t s : None // R e t u r n s : N o t h i n g // void i n i t d i c t i o n n a r y ( ) { // A l l o c a t e s memory // +1 => no d e f i n i t i o n s t a r t i n g b y 0 dp0 = ( void ∗ ) m a l l o c ( DICO SIZE ) + 1 ; // S e t d i c o p o i n t e r s dp = dp0 ; f e n c e = dp0 ; // F i r s t d e f i n i t i o n h a s no p r e v i o u s w o r d l a s t d e f = 0 ; c o r e d e f i n i t i o n s ( ) ; } // c o r e d e f i n i t i o n s ( ) // // F u n c t i o n : C r e a t e s e n t r i e s i n t h e d i c t i o n n a r y // A r g u m e n t s : None // R e t u r n s : N o t h i n g // void c o r e d e f i n i t i o n s ( ) { a d d c o r e w o r d ( ” . ” , &dot , 0 ) ; a d d c o r e w o r d ( ” . s ” , &d o t s , 0 ) ; a d d c o r e w o r d ( ”+” , &p l u s , 0 ) ; a d d c o r e w o r d ( ” w o r d s ” , &words , 0 ) ; a d d c o r e w o r d ( ” q u i t ” , &q u i t , 0 ) ;

a d d c o r e w o r d ( ” : ” , &c o l o n , IMMEDIATE WORD ) ; a d d c o r e w o r d ( ” ; ” , &s e m i c o l o n , IMMEDIATE WORD ) ; a d d c o r e w o r d ( ”dp@” , &dpat , 0 ) ; a d d c o r e w o r d ( ” dup ” , &dup , 0 ) ; a d d c o r e w o r d ( ” ∗ ” , &mult , 0 ) ; } // f r e e d i c t i o n n a r y ( ) // // F u n c t i o n : F r e e s t h e memory a l l o c a t e d f o r t h e d i c t i o n n a r y // A r g u m e n t s : None // R e t u r n s : N o t h i n g // void f r e e d i c t i o n n a r y ( ) { // f r e e s t h e memory o f t h e d i c t i o n n a r y f r e e ( dp0 ) ; } // a d d c o r e w o r d ( ) // // F u n c t i o n : C r e a t e a new e n t r y i n t h e d i c t i o n n a r y // A r g u m e n t s : // − word : s t r i n g o f t h e w o r d

(16)

// − f u n c t i o n : a d r e s s o f t h e C f u n c t i o n // − f l a g s : IMMEDIATE o r NULL // R e t u r n s : N o t h i n g

//

void a d d c o r e w o r d ( const char ∗ word , void ∗ f u n c t i o n , unsigned char f l a g s ) {

void ∗ temp dp = dp ; unsigned char temp ;

// Ge t t h e s i z e o f t h e w o r d ( b e t w e e n 1 . . 3 1 )

unsigned char l e n g t h = ( unsigned char ) s t r l e n ( word ) ; unsigned char l e n g t h f l a g s = l e n g t h | f l a g s ;

// W r i t e t h e f i r s t b y t e ( f l a g s + l e n g t h )

memcpy ( dp , &l e n g t h f l a g s , s i z e o f ( unsigned char ) ) ; dp += s i z e o f ( unsigned char ) ;

// W r i t e t h e name o f t h e w o r d

// a d d s t h e z e r o a t t h e e n d f o r s t r c m p memcpy ( dp , ( void ∗ ) word , l e n g t h + 1 ) ; dp += s i z e o f ( char ) ∗ ( l e n g t h + 1 ) ; // W r i t e t h e p f a o f t h e p r e v i o u s w o r d memcpy ( dp , &l a s t d e f , s i z e o f ( void ∗ ) ) ; dp += s i z e o f ( void ∗ ) ;

// W r i t e t h e Code Word , w h i c h i s i n t h i s c a s e o n l y EXEC WORD temp = EXEC WORD;

memcpy ( dp , &temp , s i z e o f ( unsigned char ) ) ; dp += s i z e o f ( unsigned char ) ;

// W r i t e t h e PFA ( A d d r e s s o f t h e e x e c u t i o n f u n c t i o n ) memcpy ( dp , &f u n c t i o n , s i z e o f ( void ∗ ) ) ;

dp += s i z e o f ( void ∗ ) ; // S e t t h e l a s t d e f v a r i a b l e l a s t d e f = temp dp ; } : : : : : : : : : : : : : : d i c t i o n n a r y . h : : : : : : : : : : : : : : // C o n t a i n s d e f i n i t i o n s f o r d i c t i o n n a r y . c void i n i t d i c t i o n n a r y ( ) ; void c o r e d e f i n i t i o n s ( ) ; void f r e e d i c t i o n n a r y ( ) ;

void a d d c o r e w o r d ( const char ∗ word , void ∗ f u n c t i o n , unsigned char f l a g s ) ; : : : : : : : : : : : : : : i n p u t b u f f e r . c : : : : : : : : : : : : : : /∗ i n p u t b u f f e r . c M i c r o f o r t h i n t e r p r e t e r By E r i c A b o u a f n e y r i c @ v i a . e c p . f r J u n e 1 0 , 2 0 0 5 T h i s f i l e c o n t a i n s t h e i n p u t b u f f e r f u n c t i o n s : i n i t , f r e e , and f i l l ∗/ #i n c l u d e ” i n p u t b u f f e r . h ” #d e f i n e INPUTBUFFER SIZE 2 5 6 // I n p u t b u f f e r p o i n t e r char ∗ i n p u t b u f f e r ; // i n i t i n p u t b u f f e r // // F u n c t i o n : A l l o c a t e memory f o r t h e i n p u t b u f f e r // A r g u m e n t s : None // R e t u r n : N o t h i n g // void i n i t i n p u t b u f f e r ( ) { // A l l o c a t e s s p a c e f o r i n p u t b u f f e r

(17)

i f ( i n p u t b u f f e r == 0 ) { p r i n t f ( ” i n i t i n p u t b u f f e r : U n a b l e t o a l l o c a t e s p a c e f o r i n p u t b u f f e r \n ” ) ; } } // f r e e i n p u t b u f f e r // // F u n c t i o n : F r e e memory a l l o c a t e d f o r t h e i n p u t b u f f e r // A r g u m e n t s : None // R e t u r n : N o t h i n g // void f r e e i n p u t b u f f e r ( ) { // f r e e s i n p u t b u f f e r f r e e ( ( void ∗ ) i n p u t b u f f e r ) ; } // f i l l i n p u t b u f f e r // // F u n c t i o n : F i l l s t h e i n p u t b u f f e r w i t h d a t a f r o m s t d i n // and p r e v e n t b u f f e r o v e r f l o w . ( b e t t e r t h a n g e t s ) // A r g u m e n t s : None // R e t u r n : N o t h i n g // void f i l l i n p u t b u f f e r ( ) { // F i l l s i n p u t b u f f e r char c = 0 ; unsigned char i = 0 ; while ( c != ’ \n ’ ) { // Ge t c h a r f r o m s t d i n c = g e t c h a r ( ) ; // P r e v e n t b u f f e r o v e r f l o w i f ( i == INPUTBUFFER SIZE−1) c = ’ \n ’ ; // Add t h e l e t t e r t o t h e b u f f e r i n p u t b u f f e r [ i ++] = c ; } i n p u t b u f f e r [ i −1] = 0 ; // i −1 c a u s e we r e m o v e t h e ’ \ n ’ } : : : : : : : : : : : : : : i n p u t b u f f e r . h : : : : : : : : : : : : : : // c o n t a i n s d e f i n i t i o n s f o r i n p u t b u f f e r . c void i n i t i n p u t b u f f e r ( ) ; void f r e e i n p u t b u f f e r ( ) ; void f i l l i n p u t b u f f e r ( ) ; : : : : : : : : : : : : : : p a r s e r . c : : : : : : : : : : : : : : /∗ p a r s e r . c M i c r o f o r t h i n t e r p r e t e r By E r i c A b o u a f n e y r i c @ v i a . e c p . f r J u n e 1 0 , 2 0 0 5 T h i s f i l e p a r s e t h e i n p u t b u f f e r and e x e c u t e t h e f o l l o w i n g : I ) P a r s e n e x t w o r d i n i n p u t b u f f e r I I ) L o o k u p t h e w o r d i n t h e d i c t i o n n a r y 1 . I f f o u n d i ) i f c o m p i l i n g : − E x e c u t e i f t h e w o r d i s m a r k e d IMMEDIATE − E l s e a d d w o r d a t t h e e n d o f t h e d i c t i o n n a r y i i ) i f i n t e r p r e t i n g : − E x e c u t e t h e w o r d 2 . I f n o t f o u n d i ) Try t o c o n v e r t i t t o a number − a d d t o s t a c k i f i n t e r p r e t i n g − a d d t o d i c t i o n n a r y w i t h (VALUE) b e f o r e i n t h e d i c t i o n n a r y i f c o m p i l i n g . i i ) P r i n t an e r r o r m e s s a g e ”Word unknown ”

(18)

∗/ #i n c l u d e ” p a r s e r . h ” #d e f i n e MODE COMPILATION 1 #d e f i n e MODE INTERPRET 0 extern char ∗ i n p u t b u f f e r ; extern void ∗ l a s t d e f ; extern void ∗ dp0 ; extern void ∗ dp ; extern void ∗ s p ; extern void ∗ r p ; extern void ∗ r p 0 ; char ∗ i n ;

unsigned char mode = MODE INTERPRET ; // GetNextWord ( ) // // F u n c t i o n : G e t s n e x t w o r d i n i n p u t b u f f e r // A r g u m e n t s : n e x t w o r d => r e s u l t b u f f e r // R e t u r n s : N o t h i n g //

void GetNextWord ( char ∗ n e x t w o r d ) { i n t i = 0 ; // Remove b l a n k s o r t a b s b e f o r e t h e w o r d while ( i n [ 0 ] == ’ ’ | | i n [ 0 ] == ’ \ t ’ ) i n += s i z e o f ( char ) ; // S t o r e t h e w o r d

while ( i n [ 0 ] != ’ ’ && i n [ 0 ] != ’ \ t ’ && i n [ 0 ] != 0 ) { n e x t w o r d [ i ++] = i n [ 0 ] ; i n += s i z e o f ( char ) ; } n e x t w o r d [ i ++] = 0 ; } // t i c k ( ) // // F u n c t i o n : f i n d a w o r d g i v e n i t s name i n t h e d i c t i o n n a r y // A r g u m e n t s : w o r d : s t r i n g o f t h e w o r d // R e t u r n s : p o i n t e r c o n t a i n i n g t h e p f a t o t h e w o r d //

void ∗ t i c k ( unsigned char ∗ word ) { // Take t h e l a s t d e f i n i t i o n void ∗ d e f i n i t i o n = l a s t d e f ; void ∗ p f a = 0 ; unsigned char b o o l e a n = 0 ; // W h i l e we d i d n ’ t f i n d t h e w o r d and no more d e f i n i t i o n while ( b o o l e a n == 0 && d e f i n i t i o n != 0 ) {

void ∗ n a m e p t r = d e f i n i t i o n +s i z e o f ( unsigned char ) ; // Compare t h e name

i f ( s t r c m p ( word , ( unsigned char ∗ ) n a m e p t r ) == 0 ) {

p f a = d e f i n i t i o n ; b o o l e a n = 1 ; }

e l s e // I f d i f f e r e n t , g o t o p r e v i o u s d e f i n i t i o n

memcpy ( &d e f i n i t i o n , n a m e p t r+ s t r l e n ( ( unsigned char ∗ ) n a m e p t r ) + 1 , s i z e o f ( void ∗ ) ) ; } return ( void ∗ ) p f a ; } // p f a 2 c f a ( ) // // F u n c t i o n : c o n v e r t a p f a t o a c f a // A r g u m e n t s : p f a o f t h e w o r d // R e t u r n s : p o i n t e r c o n t a i n i n g t h e c f a o f t h e w o r d // void ∗ p f a 2 c f a ( void ∗ p f a ) {

(19)

void ∗ c f a ; unsigned char l e n g t h ; i f ( p f a == 0 ) return 0 ; // S k i p l e n g t h b y t e c f a = p f a + s i z e o f ( unsigned char ) ; // S k i p name

memcpy(& l e n g t h , p f a , s i z e o f ( unsigned char ) ) ; l e n g t h = l e n g t h & 3 1 ; c f a += ( l e n g t h +1)∗ s i z e o f ( char ) ; // S k i p s p r e v i o u s p f a c f a += s i z e o f ( void ∗ ) ; return c f a ; } // i s n u m e r i c ( ) // // F u n c t i o n : T e s t i f a s t r i n g i s n u m e r i c a l // A r g u m e n t s : s t r i n g // R e t u r n s : 0 i f n u m e r i c a l , e l s e 1 . //

char i s n u m e r i c ( unsigned char ∗ s t r ) {

unsigned char ∗ temp = s t r ; while ( temp [ 0 ] != 0 ) { i f ( temp [ 0 ] < ’ 0 ’ | | temp [ 0 ] > ’ 9 ’ ) return 1 ; temp++; } return 0 ; } // p a r s e r ( ) // // F u n c t i o n : S e e t o p o f t h e f i l e // A r g u m e n t s : None // R e t u r n : N o t h i n g // void p a r s e r ( ) { // To s t o r e t h e n e x t w o r d char n e x t w o r d [ 3 2 ] ; void ∗ c f a ; i n t l e n g t h = s t r l e n ( i n p u t b u f f e r ) ; // Makes i n t h e b e g g i n i n g o f i n p u t b u f f e r i n = i n p u t b u f f e r ; // C o n t i n u e s u n t i l t h e i n p u t b u f f e r g e t s e m p t y while ( i n != i n p u t b u f f e r+l e n g t h ∗ s i z e o f ( char ) ) { GetNextWord ( n e x t w o r d ) ; // I f w o r d i s n o t e m p t y . . . i f ( n e x t w o r d [ 0 ] != 0 ) { // T i c k f i n d t h e p f a o f t h e w o r d unsigned char f i r s t b y t e = 0 ; void ∗ t e m p p f a = t i c k ( n e x t w o r d ) ; c f a = p f a 2 c f a ( t e m p p f a ) ; i f ( c f a != 0 ) {

memcpy ( &f i r s t b y t e , t e m p p f a , s i z e o f ( unsigned char ) ) ; // & 32 => F i l t e r f o r t h e 3 r d b i t d o r e a l w o r d ( c f a , f i r s t b y t e & 3 2 ) ; } // E l s e c f a == 0 e l s e { // Try t o c o n v e r t t o a n u m e r i c a l v a l u e i f ( i s n u m e r i c ( n e x t w o r d ) == 0 )

(20)

{

long number = a t o i (& n e x t w o r d ) ; i f ( mode == 0 ) // INTERPRETATION {

// Add t h e number on s t a c k memcpy ( sp ,& number , s i z e o f ( long ) ) ; s p += s i z e o f ( long ) ; } e l s e { // Add t h e CFA o f v a l u e void ∗ v a l u e = ( void ∗ ) 1 ;

memcpy ( dp ,& v a l u e , s i z e o f ( void ∗ ) ) ; dp += s i z e o f ( void ∗ ) ;

// Add t h e v a l u e

memcpy ( dp ,& number , s i z e o f ( long ) ) ; dp += s i z e o f ( long ) ; } } e l s e // Word unknown p r i n t f ( ”%s : U n d e f i n e d word \n ” , n e x t w o r d ) ; } // e l s e c f a == 0 } // I f w o r d n o t e m p t y } // w h i l e i n . . . } // d o r e a l w o r d ( ) // // F u n c t i o n : S e e t o p o f t h e f i l e // A r g u m e n t s : c f a o f t h e w o r d t o e x e c u t e o r c o m p i l e // f l a g s ( i m m e d i a t e w o r d o r n o t ) // R e t u r n : N o t h i n g //

void d o r e a l w o r d ( void ∗ c f a , unsigned char f l a g s ) { i f ( mode == 1 ) // COMPILATION { // IMMEDIATE WORD i f ( f l a g s == 3 2 ) i n t e r p r e t ( c f a ) ; e l s e { // We j u s t a d d t h e c f a a t t h e e n d o f t h e d i c t i o n n a r y memcpy ( dp , &c f a , s i z e o f ( void ∗ ) ) ;

dp += s i z e o f ( void ∗ ) ; } } e l s e // INTERPRETEATION i n t e r p r e t ( c f a ) ; } // i n t e r p r e t ( ) // // F u n c t i o n : E x e c u t e a w o r d g i v e n i t s c f a // A r g u m e n t s : c f a // R e t u r n : N o t h i n g // void i n t e r p r e t ( void ∗ c f a ) { unsigned char t y p e ; void ( ∗ f p ) ( ) ;

void ∗ c f a d a t a = c f a + s i z e o f ( unsigned char ) ; memcpy(& t y p e , c f a , s i z e o f ( unsigned char ) ) ;

i f ( t y p e == 0 ) // EXEC WORD {

// R e t r i e v e e x e c a d d r e s s

memcpy ( &f p , c f a d a t a , s i z e o f ( void ∗ ) ) ; // E x e c u t e a d d r e s s f p ( ) ; } e l s e i f ( t y p e == 1 ) // COLON WORD { // Add t h e c f a on t o p o f t h e r e t u r n s t a c k memcpy ( rp , &c f a d a t a , s i z e o f ( void ∗ ) ) ; r p += s i z e o f ( void ∗ ) ;

(21)

// E x e c u t e t h e s t a c k e x e c u t e ( ) ; } e l s e p r i n t f ( ” C o r r u p t e d memory i n d i c t i o n n a r y . \ n ” ) ; } // e x e c u t e ( ) // // F u n c t i o n : E x e c u t e t h e r e t u r n s t a c k ( i f f o r t h −d e f i n e d w o r d ) // A r g u m e n t s : None // R e t u r n : N o t h i n g // void e x e c u t e ( ) { void ∗ c f a ; void ∗ i p ; long temp ; while ( r p != r p 0 ) { // U n s t a c k an e l e m e n t r p −= s i z e o f ( void ∗ ) ;

memcpy ( rp , &c f a , s i z e o f ( void ∗ ) ) ; i p = c f a ; // p r i n t f (”% d ” , c f a ) ; memcpy(&temp , i p , s i z e o f ( long ) ) ; while ( temp != 0 ) { i f ( temp == 1 ) // 1 i s t h e CFA i n d i c a t i n g a v a l u e { i p += s i z e o f ( long ∗ ) ; // Add t h e v a l u e on t h e s t a c k memcpy ( sp , i p , s i z e o f ( long ) ) ; s p += s i z e o f ( long ) ; } e l s e { void ∗ n e w c f a ;

memcpy ( &n e w c f a , i p , s i z e o f ( void ∗ ) ) ; i n t e r p r e t ( n e w c f a ) ; } // Go t o n e x t i n s t r u c t i o n i p += s i z e o f ( long ∗ ) ; memcpy(&temp , i p , s i z e o f ( long ) ) ; } } } : : : : : : : : : : : : : : p a r s e r . h : : : : : : : : : : : : : : // D e f i n i t i o n s f o r p a r s e r . c

void GetNextWord ( char ∗ n e x t w o r d ) ; void p a r s e r ( ) ;

void d o r e a l w o r d ( void ∗ c f a , unsigned char f l a g s ) ; void i n t e r p r e t ( void ∗ c f a ) ; void e x e c u t e ( ) ; : : : : : : : : : : : : : : s t a c k s . c : : : : : : : : : : : : : : /∗ s t a c k s . c M i c r o f o r t h i n t e r p r e t e r By E r i c A b o u a f n e y r i c @ v i a . e c p . f r J u n e 1 0 , 2 0 0 5 C o n t a i n s t h e i n i t and f r e e f u n c t i o n s f o r d a t a and r e t u r n s t a c k s .

(22)

∗/ #i n c l u d e ” s t a c k s . h ” #d e f i n e DATASTACK SIZE 3 0 0 0 #d e f i n e RETURNSTACK SIZE 3 0 0 0 // P o i n t e r s f o r t h e r e t u r n s t a c k void ∗ r p 0 ; void ∗ r p ; // P o i n t e r s f o r t h e d a t a s t a c k void ∗ s p 0 ; void ∗ s p ; // i n i t s t a c k s ( ) // // F u n c t i o n : A l l o c a t e s p a c e f o r d a t a and r e t u r n s t a c k s // A r g u m e n t s : None // R e t u r n : N o t h i n g // void i n i t s t a c k s ( ) { // A l l o c a t e s s p a c e f o r d a t a s t a c k s p 0 = ( void ∗ ) m a l l o c (DATASTACK SIZE ) ; i f ( s p 0 == 0 ) { p r i n t f ( ” i n i t s t a c k s : U n a b l e t o a l l o c a t e s p a c e f o r d a t a s t a c k \n ” ) ; } s p = s p 0 ; // A l l o c a t e s s p a c e f o r r e t u r n s t a c k r p 0 = ( void ∗ ) m a l l o c (RETURNSTACK SIZE ) ; i f ( r p 0 == 0 ) { p r i n t f ( ” i n i t s t a c k s : U n a b l e t o a l l o c a t e s p a c e f o r r e t u r n s t a c k \n ” ) ; } r p = r p 0 ; } // f r e e s t a c k s ( ) // // F u n c t i o n : F r e e memory a l l o c a t e d f o r t h e s t a c k s // A r g u m e n t s : None // R e t u r n : N o t h i n g // void f r e e s t a c k s ( ) { // F r e e s t a c k s f r e e ( ( void ∗ ) r p 0 ) ; f r e e ( ( void ∗ ) s p 0 ) ; } : : : : : : : : : : : : : : s t a c k s . h : : : : : : : : : : : : : : // d e f i n i t i o n s f o r s t a c k s . c void i n i t s t a c k s ( ) ; void f r e e s t a c k s ( ) ; : : : : : : : : : : : : : : c o r e . c : : : : : : : : : : : : : : /∗ c o r e . c M i c r o f o r t h i n t e r p r e t e r By E r i c A b o u a f n e y r i c @ v i a . e c p . f r J u n e 1 1 , 2 0 0 5 T h i s f i l e c o n t a i n s some c o r e w o r d d e f i n i t i o n s . A l l t h e f u n c t i o n s a r e meant t o b e a d d e d t o t h e d i c t i o n n a r y t h r o u g h a d d c o r e w o r d ( ) ∗/

(23)

#i n c l u d e ” c o r e . h ” #i n c l u d e ” p a r s e r . h ” #i n c l u d e ” main . h ” extern void ∗ s p ; extern void ∗ dp ; extern void ∗ s p 0 ; extern void ∗ l a s t d e f ; extern unsigned char mode ; // d u p void dup ( ) { i f ( s p == s p 0 ) p r i n t f ( ” dup : e r r o r , empty s t a c k \n ” ) ; e l s e {

memcpy ( sp , sp−s i z e o f ( long ) , s i z e o f ( long ) ) ; s p += s i z e o f ( long ) ; } } // DP@ void d p a t ( ) {

memcpy ( sp , &dp , s i z e o f ( void ∗ ) ) ; s p += s i z e o f ( void ∗ ) ; } // : ( i m m e d i a t e w o r d ) void c o l o n ( ) { char n e x t w o r d [ 3 2 ] ; unsigned char l e n g t h ; unsigned char temp ; void ∗ temp dp = dp ; // S w i t c h t o c o m p i l a t i o n mode mode = 1 ; // GetNextWord i n i n p u t b u f f e r GetNextWord ( n e x t w o r d ) ; l e n g t h = ( unsigned char ) s t r l e n ( n e x t w o r d ) ; // w r i t e w o r d h e a d e r

memcpy ( dp , &l e n g t h , s i z e o f ( unsigned char ) ) ; dp += s i z e o f ( unsigned char ) ;

// w r i t e t h e name

memcpy ( dp , ( void ∗ ) n e x t w o r d , l e n g t h + 1 ) ; dp += s i z e o f ( char ) ∗ ( l e n g t h + 1 ) ;

// W r i t e t h e p f a o f t h e p r e v i o u s w o r d memcpy ( dp , &l a s t d e f , s i z e o f ( void ∗ ) ) ; dp += s i z e o f ( void ∗ ) ;

// W r i t e i n f o a b o u t a c o l o n w o r d temp = 1 ;

memcpy ( dp , &temp , s i z e o f ( unsigned char ) ) ; dp += s i z e o f ( unsigned char ) ; // U p d a t e l a s t d e f l a s t d e f = temp dp ; } // ; ( i m m e d i a t e w o r d ) void s e m i c o l o n ( ) { void ∗ temp = 0 ; // S w i t c h t o i n t e r p r e t a t i o n mode mode = 0 ; // W r i t e t h e e n d o f t h e w o r d ( 0 ) memcpy ( dp , &temp , s i z e o f ( void ∗ ) ) ; dp += s i z e o f ( void ∗ ) ;

} // q u i t void q u i t ( )

(24)

{ p r i n t f ( ” \ nGoodbye ! \ n\n ” ) ; f r e e m e m ( ) ; e x i t ( 0 ) ; } // . void d o t ( ) { i f ( s p == s p 0 ) p r i n t f ( ” . : e r r o r , empty s t a c k \n ” ) ; e l s e { long temp ; s p −= s i z e o f ( long ) ; memcpy(&temp , sp , s i z e o f ( long ) ) ; p r i n t f ( ”%d ” , temp ) ; } } // + void p l u s ( ) { i f ( s p <= s p 0+s i z e o f ( long ) ) p r i n t f ( ” +: e r r o r , empty s t a c k \n ” ) ; e l s e { long x1 , x2 ; s p −= s i z e o f ( long ) ; memcpy(&x1 , sp , s i z e o f ( long ) ) ; s p −= s i z e o f ( long ) ; memcpy(&x2 , sp , s i z e o f ( long ) ) ; x1 += x2 ;

memcpy ( sp , &x1 , s i z e o f ( long ) ) ; s p += s i z e o f ( long ) ; } } // ∗ void mult ( ) { i f ( s p <= s p 0+s i z e o f ( long ) ) p r i n t f ( ” +: e r r o r , empty s t a c k \n ” ) ; e l s e { long x1 , x2 ; s p −= s i z e o f ( long ) ; memcpy(&x1 , sp , s i z e o f ( long ) ) ; s p −= s i z e o f ( long ) ; memcpy(&x2 , sp , s i z e o f ( long ) ) ; x1 = x1 ∗ x2 ;

memcpy ( sp , &x1 , s i z e o f ( long ) ) ; s p += s i z e o f ( long ) ; } } // . s void d o t s ( ) { void ∗ temp = s p 0 ; p r i n t f ( ”<%d> ” , ( sp−s p 0 ) / s i z e o f ( long ) ) ; while ( temp != s p ) { long numero ;

memcpy(&numero , temp , s i z e o f ( long ) ) ; p r i n t f ( ”%d ” , numero ) ; temp += s i z e o f ( long ) ; } } // w o r d s void w o r d s ( ) { void ∗ d e f i n i t i o n = l a s t d e f ; // W h i l e we d i d n ’ t f i n d no more d e f i n i t i o n while ( d e f i n i t i o n != 0 ) {

(25)

void ∗ n a m e p t r = d e f i n i t i o n +s i z e o f ( unsigned char ) ; p r i n t f ( ”%s ” , ( unsigned char ∗ ) n a m e p t r ) ;

// P r e v i o u s d e f i n i t i o n a d d r e s s i s a t n a m e p t r+ l e n g t h o f ( name )

memcpy ( &d e f i n i t i o n , n a m e p t r+ s t r l e n ( ( unsigned char ∗ ) n a m e p t r ) + 1 , s i z e o f ( void ∗ ) ) ; } p r i n t f ( ” \n ” ) ; } : : : : : : : : : : : : : : c o r e . h : : : : : : : : : : : : : : // C o n t a i n s d e c l a r a t i o n s o f c o r e . c void dup ( ) ; void mult ( ) ; void d p a t ( ) ; void c o l o n ( ) ; void s e m i c o l o n ( ) ; void q u i t ( ) ; void d o t ( ) ; void d o t s ( ) ; void p l u s ( ) ; void w o r d s ( ) ; : : : : : : : : : : : : : : M a k e f i l e : : : : : : : : : : : : : : m i c r o f o r t h : main . c d i c t i o n n a r y . c i n p u t b u f f e r . c s t a c k s . c p a r s e r . c c o r e . c g c c −o main . o −c main . c

g c c −o d i c t i o n n a r y . o −c d i c t i o n n a r y . c g c c −o c o r e . o −c c o r e . c g c c −o p a r s e r . o −c p a r s e r . c g c c −o i n p u t b u f f e r . o −c i n p u t b u f f e r . c g c c −o s t a c k s . o −c s t a c k s . c g c c −o m i c r o f o r t h main . o d i c t i o n n a r y . o i n p u t b u f f e r . o s t a c k s . o p a r s e r . o c o r e . o c l e a n : rm − r f ∗ . o rm m i c r o f o r t h

Références

Documents relatifs

Indeed the non-verbal signals sequences contained in these segments will be distributed for different types of attitude variations, and therefore will not be very frequent before

Dans tous les cas, Segeta n'est pas ici représentée dans son temple, comme sur les monnaies de Salonine et comme d'autres divinités, comme Mercure, sur d'autres séries de jetons

Specifically, given a series of observations x 1:T , which can be noisy, partially and irregularly sam- pled of a dynamical system, DAODEN supposes that the generation process of x

Pour comprendre les évolutions récentes et les conflits au sein des compagnies classiques, il est nécessaire de saisir que ce n’est pas seulement le concept un peu abstrait de «

Destacou-se a importância do balanço hídrico para a economia de água e em que áreas pode ser utilizado, propôs-se um método computacional que permita ao usuário obter

Jean-Luc Godard, Une histoire seule (1b), in Histoire(s) du cinéma, 1998.. tout le projet politique et poétique de Godard et Gorin. En écho aux échecs de Vertov et

L’archive ouverte pluridisciplinaire HAL, est destinée au dépôt et à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des

Observações sobre a ocorrência da vespa de Uganda Prorops nasuta Waterston em lavouras da Zona da Mata, infestadas pela broca do café Hypothenemus hampei (Ferrari, 1867).. In: