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