Advertisement
PifyZ

BootMonkey

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