Je suis relativement nouveau à C ++. J'ai traversé toutes les choses de base et réussi à construire 2-3 interprètes simples pour mes langages de programmation. P> La première chose qui m'a donné et me donne toujours mal à la tête: Mise en œuvre du système de type de ma langue en C ++ forte> p> Pensez à cela: Ruby, Python, PHP et Co. ont beaucoup de types intégrés qui sont évidemment mis en œuvre dans C.
Alors, ce que j'ai essayé d'abord était de permettre de donner une valeur dans ma langue trois types possibles: int, string et nil. P> Je suis venu avec ceci: p> enum ValueType
{
Int, String, Nil
};
extern string stringTable[255];
class Value
{
public:
ValueType type;
int index;
};
5 Réponses :
En ce qui concerne la vitesse, vous dites: p>
C'était extrêmement lent de passer cette classe autour de l'allocateur de chaîne devait être appelé tout le temps. p> blockQuote>
Vous savez que vous devriez passer des objets en référence à la grande majorité du temps? Votre solution a l'air viable pour un interprète simple. P>
Ce n'était pas si facile la plupart du temps. J'ai dû faire plusieurs copies autant de fonctions modifier temporairement les valeurs.
@sub bien cela semble douteux. Je ne vois pas pourquoi vous changeriez jamais une valeur, une fois qu'il a été créé, à moins que l'utilisateur ne l'assigne.
Une solution évidente consiste à définir une hiérarchie de type: et ainsi de suite. À titre d'exemple complet, écrivez-nous un interprète pour une langue minuscule. La langue permet de déclarer des variables comme ceci: p> qui créera un objet Voici le code complet de l'interpréteur: p> Un échantillon d'interaction avec l'interprète: p> int code>, attribuez-lui la valeur
10 code> et Stockez-le dans la table d'une variable sous le nom
A code>. Les opérations peuvent être invoquées sur des variables. Par exemple, l'opération d'addition sur deux valeurs INT ressemble à: p>
Puis-je les stocker tous dans un seul tableau? Ou sont-ils des types complètement différents comme chaîne vs int? Je suis relativement nouveau à cela.
@Vijay: Pourriez-vous s'il vous plaît expliquer comment et où stocker les instances des classes?
Ceci est une solution commune dans de nombreux systèmes. Il doit être combiné à une allocation dynamique C'est l'évolution directe de la solution C que j'ai fournie, où vous ajoutez la hiérarchie et remplacez le style C avec une distribution dynamique. Les informations de type réelles sont généralement stockées dans la classe de base (sous forme d'énorme) ou obtenues avec l'opérateur typeid ()
@sub Le moyen le plus C ++ est d'utiliser std :: Carte en tant que table de symboles. Je modifierai ma réponse avec un exemple plus complet.
C ++ est une langue fortement dactylographiée. Je peux voir que vous venez d'une langue non typée et que vous pensez toujours dans ces termes. p>
Si vous vraiment em> besoin de stocker plusieurs types dans une variable, jetez un coup d'œil à boost :: n'importe quel . p>
Toutefois, si vous mettez en œuvre un interprète, vous devez utiliser l'héritage et les classes qui représentent un type spécifique. P>
Ce n'est pas mon problème. Vous ne m'avez pas dit comment i> et où i> stocker les instances de ces classes.
J'ai évoqué, car la réponse est bonne: utiliser Boost :: Tout. Je ne vois pas comment ce n'est pas votre problème.
+1, d'accord. Boost :: Tout est une solution à la question écrite, même si ce n'est pas une réponse (complète) à la question de la tête de Sub.
Il y a quelques choses différentes que vous pouvez faire ici. Différentes solutions ont augmenté dans le temps et la plupart d'entre elles ont besoin d'une allocation dynamique de la donnée réelle (Boost :: Variant peut éviter d'utiliser une mémoire allouée dynamiquement pour les petits objets --Thanks @msalters).
APPROCHE PURE C: P >
Informations sur le type de magasin et un pointeur vide sur la mémoire qui doit être interprété en fonction des informations de type (généralement une énumération): p> in c ++, vous pouvez améliorer cela Approche en utilisant des classes pour simplifier l'utilisation, mais plus important encore, vous pouvez utiliser des solutions plus complexes et utiliser des bibliothèques existantes telles que Boost :: Tout boost :: Variante offrant différentes solutions au même problème. P> Boost :: Tout boost :: Variante Stockez les valeurs de la mémoire allouée dynamiquement, généralement via un pointeur à une classe virtuelle dans une hiérarchie et avec des opérateurs qui réinterpréter (Down Count) sur les types de béton. P> P> P> P> >
Je ne pense pas que ça boost :: variante (ou même boost :: n'importe quel) nécessite une allocation dynamique i>. Ils ont des astuces spéciales pour éviter que possible. À peu près parler, même s'ils ont un Void * code> pour les gros objets sur le tas, ce pointeur peut faire partie d'une union dont les autres membres sont utilisés pour contenir de petits types de données.
@Msalters: Droite. Je n'avais pas examiné la mise en œuvre de la variante et utilise un tampon qui est réinterprété en fonction du type particulier utilisé, comme vous l'avez expliqué. Boostez-vous, d'autre part, est beaucoup plus simple et utilise une mémoire allouée de manière dynamique inconditionnellement.
Selon la solution de Vijay, la mise en œuvre sera la suivante: Le bit manquant de son code est de savoir comment extraire ces valeurs ... Voici ma version (en fait j'ai appris cela de l'ogre et modifié C'est à mon goût). p> Utilisation est quelque chose comme: p> OK, maintenant pour voir si un élément particulier est une chaîne: p> Le code de la catégorie de n'importe quelle classe est indiqué ci-dessous. N'hésitez pas à l'utiliser mais vous aimez :). J'espère que cela vous aide! P> dans le fichier d'en-tête ... Dites an.h p> maintenant dans le fichier CPP ... tout.cpp p>
Oublié de mentionner. Speed-sage, c'est effectivement un pointeur à l'instance CLAS d'espace réservé, qui stocke le pointeur sur la valeur transmise. Pas trop de surcharge je suppose. Et c'est le type de type et n'a pas besoin de bibliothèques complexes comme Boost.
"Int, string, nil", qu'en est-il du flotteur?
Je supporte pleinement l'idée d'un langage de programmation sans
float code>! Sinon, la première question sub_language sur ce que vous serez "hé, pourquoi 0,1 + 0,2 0,2 == 0.3 dans sub_language? C'est cassé!".
@SUB: Si c'est vous, vous descendez certaines des réponses, vous devez le reconsidérer. Il existe des réponses valides qui ont été évitées sans raison, dont certaines pourraient être que vous n'avez pas compris la réponse dans toute leur mesure. Si cela n'a pas été vous, à qui l'a fait: s'il vous plaît, expliquez ce que vous considérez comme mal des réponses. C'est le seul moyen d'améliorer réellement le système.