Advertisement
PifyZ

BootMonkey

Aug 18th, 2012
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Manipulation de fichiers
  2.     # File.write(fichier, texte)          - écrit à la suite du fichier
  3.     # File.rewrite(fichier, texte)        - réécrit tout le fichier
  4.     # File.writeline(fichier, texte)      - écrit dans une nouvelle ligne du fichier (à la fin)
  5.     # File.writefirstline(fichier, texte) - écrit dans une nouvelle ligne du fichier (au début)
  6.     # File.open(fichier, mode)            - permet d'ouvrir le fichier avec un mode
  7.     # File.read(fichier)                  - permet de lire le fichier
  8.     # File.readline(fichier, ligne)       - permet de lire une ligne spécifique du fichier
  9.     # File.close(fichier)                 - permet de fermer le fichier
  10.  
  11. # Manipulation des textes
  12.     # String.lower(texte)  -
  13.     # String.upper(texte)  -
  14.     # String.length(texte) -
  15.  
  16. # Manipulation de la console
  17.     # Console.clean.          - Efface tout le contenu (ce qui est écrit) de la console
  18.     # Console.print   "Texte" - Affiche un texte sur la ligne courante
  19.     # Console.println "Texte" - Affiche un texte sur une nouvelle ligne
  20.  
  21. # Manipulation des int et des float
  22.     # Math.round 12.5  -
  23.     # Math.ceil 12.5   -
  24.     # Math.floor 12.5  -
  25.     # Math.random 12.5 -
  26.  
  27. # Manipulation des tableaux
  28.     # Array.in(element, array) - Retourne true si l'element se trouve dans l'array
  29.     # Array.empty(array)       -
  30.     # Array.size(array)        -
  31.  
  32. # Définition des variables globales
  33.     # *Non obligatoire signifie qu'il est possible de créer la fonction dans un script BM
  34.     #   mais c'est mieux si nous on créer la fonction plutôt que de déléguer ça aux développeurs
  35.  
  36.     opcodes = [
  37.         # fonction             entre  adresse
  38.         ["nop",                 '\0', "\x00\x00"], #
  39.         ["#",                   '\0', "\x00\x01"], #
  40.         ["if",                  '(',  "\x00\x02"], #
  41.         ["elseif",              '(',  "\x00\x03"], #
  42.         ["else",                '\0', "\x00\x04"], #
  43.         ["end",                 '\0', "\x00\x05"], #
  44.         ["continue",            '\0', "\x00\x06"], #
  45.         ["break",               '\0', "\x00\x07"], #
  46.  
  47.         ["Program.exit",        '\0', "\x01\x00"], #
  48.  
  49.         ["Console.clean",       '\0', "\x02\x01"], #
  50.         ["Console.print",       ' ',  "\x02\x01"], #
  51.         ["Console.println",     ' ',  "\x02\x02"], #
  52.         ["Console.sleep",       ' ',  "\x02\x03"], #
  53.  
  54.         ["String.lower",        '(',  "\x03\x00"], #
  55.         ["String.upper",        '(',  "\x03\x01"], #
  56.         ["String.length",       '(',  "\x03\x02"], #
  57.  
  58.         ["Math.floor",          '(',  "\x04\x00"], #
  59.         ["Math.round",          '(',  "\x04\x01"], #
  60.         ["Math.ceil",           '(',  "\x04\x02"], #
  61.         ["Math.random",         '(',  "\x04\x03"], #
  62.  
  63.         ["Array.in",            '(',  "\x05\x00"], # Non obligatoire
  64.         ["Array.empty",         '(',  "\x05\x01"], # Non obligatoire
  65.         ["Array.size",          '(',  "\x05\x02"], # Non obligatoire
  66.  
  67.         ["File.open",           '(',  "\x06\x00"], #
  68.         ["File.write",          '(',  "\x06\x01"], #
  69.         ["File.writeLine",      '(',  "\x06\x02"], #
  70.         ["File.writeFirstLine", '(',  "\x06\x03"], #
  71.         ["File.rewrite",        '(',  "\x06\x04"], #
  72.         ["File.isEmpty",        '(',  "\x06\x05"], #
  73.         ["File.read",           '(',  "\x06\x06"], #
  74.         ["File.readLine",       '(',  "\x06\x07"], #
  75.         ["File.close",          '(',  "\x06\x08"], #
  76.         ["File.countLine",      '(',  "\x06\x09"]  #
  77.     ]
  78.  
  79.     nbrWarnings = 0
  80.     nbrErrors   = 0
  81.  
  82. # Fonction de compilation
  83.     compile (File Src, File Dst)
  84.         Data = [][]                 # contient le fichier source [ligne][colonne]
  85.         nbrLignes = File.countLine(Src) # nombre de lignes du fichier
  86.  
  87.         print "Compilation de \"" . Src . "\" -> \"" . Dst . "\"...\n"
  88.  
  89.         if File.open(Src, "r") == null # Si le fichier source est inaccessible en lecture on affiche une erreur
  90.             exit "Le fichier source \"" . Src . "\" n'a pu être ouvert en lecture."
  91.         end
  92.  
  93.         for i = 0 to nbrLignes
  94.             if File.readline(Src, Data[i]) != 1
  95.                 exit "Le fichier source \"" . Src . "\" n'a pu être lu correctement."
  96.             end
  97.  
  98.             File.close(fpSrc)
  99.         end
  100.  
  101.         if File.isEmpty(Src)
  102.             exit "Le fichier source \"" . Src . "\" est vide.\n"
  103.         end
  104.  
  105.         if File.open(Dst, "wb") == null # Si le fichier de destination n'a pas pu être ouvert en écriture on affiche une erreur
  106.             exit "Le fichier de destination \"" . Dst . "\" n'a pu être ouvert en écriture."
  107.         end
  108.  
  109.         File.write(Dst, "BM01")
  110.  
  111.         for y = 0 to nbrLignes
  112.             if Data[y][0] == '\0'
  113.                 continue
  114.             end
  115.  
  116.             for x = 0 to Array.size(opcodes)
  117.                 if Array.in(Data[y][x], opcodes)
  118.                     File.write(Dst, [j].code)
  119.                     k = 0
  120.  
  121.                     # ---------------------------- #
  122.                     # début partie en modification #
  123.                     # ---------------------------- #
  124.                     if [j].nextCar != '\0'
  125.                         if [j].nextCar == ' '
  126.                             for (k=strlen (opcodes [j].str) ; Data [y][k]==' ' && k < strlen (Data [y]) ; k++)
  127.                             end
  128.                         else
  129.                             for (k=strlen (opcodes [j].str) ; (Data [y][k]!=opcodes [j].nextCar || Data [y][k]==' ') && k < strlen (Data [y]) ; k++)
  130.                             end
  131.                         end
  132.  
  133.                         if k >= strlen (Data[y])
  134.                             exit "Instruction invalide dans le fichier " . Src . ":" . (y + 1) . "."
  135.                             break
  136.                         end
  137.                     end
  138.                     # -------------------------- #
  139.                     # fin partie en modification #
  140.                     # -------------------------- #
  141.                 else.
  142.                     exit "Instruction inconnue : \"" . Data[y] . "\" dans le fichier " . Src . ":" . (y + 1) . "."
  143.                 end
  144.             end
  145.         end
  146.  
  147.         File.close(Dst)
  148.         print "Compilation terminée (" . nbrErrors . " erreur(s) et " . nbrWarnings . " warning(s))"
  149.  
  150.         if (nbrErrors > 0)
  151.             return false
  152.         end
  153.  
  154.         return true
  155.     end
  156.  
  157.  
  158.  
  159.  
  160. Syntaxe d’un objet BootMonkey
  161. (Fichier binaire exécutable)
  162.  
  163. Signature (sur 4 octets) : “BM01”. Sans cette signature, l’exécutable .rbm NE pourra PAS être exécuté !
  164. Puis :
  165.  
  166. Pour chaque instruction (non conditionnelle):
  167.  
  168.         code de l’instruction (2 octets).
  169.         adresse de l’instruction suivante à partir du début du fichier (4 octets).
  170.         nombre de paramètres (sur 1 octet)
  171.             Pour chaque paramètre :
  172.  
  173.     - Son type (1 octets)
  174.  
  175.         - Le premier demi-octet : Type de variable (1=constante immédiate/0=adresse d’une variable).
  176.  
  177.         - Le deuxième demi-octet : Taille de la variable (1 ou 2 ou 4 / 4 obligatoire pour l’adresse d’une variable).
  178.  
  179.     - Son contenu (1 ou 2 ou 4 octets)
  180.  
  181.         En fonction du type.
  182.  
  183.  
  184.    
  185.  
  186.  
  187. // PISTES
  188.    
  189.  
  190.                 switch (opcodes [j].nextCar)
  191.                 {
  192.                     case ' ':
  193.                     {
  194.                         // ArgsSize est la taille de l'argument passé en paramètre.
  195.                         uint32_t ArgsSize = strlen (Data [i]) - k ;
  196.                         // ArgsSize + 1 pour prendre en compte le '\0' de fin de chaîne.
  197.                         uint8_t *Var = malloc (ArgsSize + 1) ;
  198.                         memcpy (Var, &Data [i][k], ArgsSize + 1) ;
  199.                        
  200.                         // ArgsSize - 1 car ArgsSize est un tableau, donc pour utiliser le dernier paramètre
  201.                         if (Var [0] == '\"' && Var [ArgsSize - 1] == '\"')
  202.                         {
  203.                             // addr est l'adresse de l'instruction suivante.
  204.                             uint32_t addr = ftell (fpDst) + 4 + (ArgsSize - 2) + 1 ;
  205.                             uint32_t fill = 0 ;
  206.                             fwrite (&addr, 1, 4, fpDst) ;
  207.                             for (uint32_t k=1 ; k < ArgsSize-1 ; k++)
  208.                             {
  209.                                 if (Var [k] == '\\' && k+1 < ArgsSize-1)
  210.                                 {
  211.                                     switch (Var [++k])
  212.                                     {
  213.                                         case '\\':
  214.                                             Var [k] = '\\' ;
  215.                                             break ;
  216.                                         case '\"':
  217.                                             Var [k] = '\"' ;
  218.                                             break ;
  219.                                         case '\'':
  220.                                             Var [k] = '\'' ;
  221.                                             break ;
  222.                                         case 'a':
  223.                                             Var [k] = '\a' ;
  224.                                             break ;
  225.                                         case 'b':
  226.                                             Var [k] = '\b' ;
  227.                                             break ;
  228.                                         case 'e':
  229.                                             Var [k] = '\e' ;
  230.                                             break ;
  231.                                         case 'f':
  232.                                             Var [k] = '\f' ;
  233.                                             break ;
  234.                                         case 'n':
  235.                                             Var [k] = '\n' ;
  236.                                             break ;
  237.                                         case 'r':
  238.                                             Var [k] = '\r' ;
  239.                                             break ;
  240.                                         case 't':
  241.                                             Var [k] = '\t' ;
  242.                                             break ;
  243.                                         case 'v':
  244.                                             Var [k] = '\v' ;
  245.                                             break ;
  246.                                         default:
  247.                                             warning ("Séquence d'échappement invalide \"\\%c\" dans le fichier %s:%d, utilisation du caractère sans échappement.", Var [k], Src, i+1) ;
  248.                                             break ;
  249.                                     }
  250.                                     fill++ ;
  251.                                 }
  252.                                    
  253.                                 fprintf (fpDst, "%c", Var [k]) ;
  254.                             }
  255.                             fwrite ("\0", 1, 1, fpDst) ;
  256.                             while (fill-- > 0)
  257.                                 fwrite ("\0", 1, 1, fpDst) ;
  258.                         }
  259.                         else if (isdigit (Var [0]))
  260.                         {
  261.                             uint32_t addr = ftell (fpDst) + 4 + ArgsSize + 1 ;
  262.                             fwrite (&addr, 1, 4, fpDst) ;
  263.                             fprintf (fpDst, "%d", atoi (&Var [0])) ;
  264.                             fwrite ("\0", 1, 1, fpDst) ;
  265.                         }
  266.                         else
  267.                             dieOnError ("Déclaration de constante immédiate illégale dans le fichier %s:%d.", Src, i+1) ;
  268.                         free (Var) ;
  269.                         break ;
  270.                     }
  271.                 }
  272.                 break ;
  273.             }
  274.         }
  275.         if (j >= NbrOpCodes)
  276.             dieOnError ("Instruction inconnue : \"%s\" dans le fichier %s:%d.", Data [i], Src, i+1) ;
  277.     }
  278.     fclose (fpDst) ;
  279.     fprintf (stdout, "Compilation terminée (%d erreur", nbrErrors) ;
  280.     if (nbrErrors > 1)
  281.         fprintf (stdout, "s") ;
  282.     fprintf (stdout, " et %d warning", nbrWarnings) ;
  283.     if (nbrWarnings > 1)
  284.         fprintf (stdout, "s") ;
  285.     fprintf (stdout, ").\n") ;
  286.     if (nbrErrors > 0)
  287.         return EXIT_FAILURE ;
  288.     return EXIT_SUCCESS ;
  289. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement