Mercurial > projects > ldc
comparison dmd/interpret.c @ 1621:fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Both DMD revisions are for fixing bugzilla 2029 (Typesafe variadic
functions don't work in CTFE).
The DMD r314 commit message is:
bugzilla 2029 (Typesafe variadic functions don't work in CTFE
The DMD r315 commit message is:
bugzilla 2029 - try again
---
dmd/constfold.c | 11 ++++-
dmd/declaration.c | 21 +++++++++-
dmd/declaration.h | 10 ++++-
dmd/expression.c | 1 +
dmd/interpret.c | 111 +++++++++++++++++++++++++++++++++++++++++++++--------
dmd/mars.h | 2 +-
dmd/mtype.c | 2 +-
7 files changed, 135 insertions(+), 23 deletions(-)
author | Leandro Lucarella <llucax@gmail.com> |
---|---|
date | Wed, 06 Jan 2010 15:18:22 -0300 |
parents | 0333945a915e |
children | e83f0778c260 |
comparison
equal
deleted
inserted
replaced
1620:0333945a915e | 1621:fb2e6707ad17 |
---|---|
46 | 46 |
47 Expression *interpret_aaLen(InterState *istate, Expressions *arguments); | 47 Expression *interpret_aaLen(InterState *istate, Expressions *arguments); |
48 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments); | 48 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments); |
49 Expression *interpret_aaValues(InterState *istate, Expressions *arguments); | 49 Expression *interpret_aaValues(InterState *istate, Expressions *arguments); |
50 | 50 |
51 Expression *interpret_length(InterState *istate, Expression *earg); | |
52 Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd); | |
53 Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd); | |
54 | |
51 /************************************* | 55 /************************************* |
52 * Attempt to interpret a function given the arguments. | 56 * Attempt to interpret a function given the arguments. |
53 * Input: | 57 * Input: |
54 * istate state for calling function (NULL if none) | 58 * istate state for calling function (NULL if none) |
55 * arguments function arguments | 59 * arguments function arguments |
64 printf("\n********\nFuncDeclaration::interpret(istate = %p) %s\n", istate, toChars()); | 68 printf("\n********\nFuncDeclaration::interpret(istate = %p) %s\n", istate, toChars()); |
65 printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun); | 69 printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun); |
66 #endif | 70 #endif |
67 if (global.errors) | 71 if (global.errors) |
68 return NULL; | 72 return NULL; |
73 | |
74 #if DMDV1 | |
69 if (ident == Id::aaLen) | 75 if (ident == Id::aaLen) |
70 return interpret_aaLen(istate, arguments); | 76 return interpret_aaLen(istate, arguments); |
71 else if (ident == Id::aaKeys) | 77 else if (ident == Id::aaKeys) |
72 return interpret_aaKeys(istate, arguments); | 78 return interpret_aaKeys(istate, arguments); |
73 else if (ident == Id::aaValues) | 79 else if (ident == Id::aaValues) |
74 return interpret_aaValues(istate, arguments); | 80 return interpret_aaValues(istate, arguments); |
81 #endif | |
82 #if DMDV2 | |
83 if (thisarg && | |
84 (!arguments || arguments->dim == 0)) | |
85 { | |
86 if (ident == Id::length) | |
87 return interpret_length(istate, thisarg); | |
88 else if (ident == Id::keys) | |
89 return interpret_keys(istate, thisarg, this); | |
90 else if (ident == Id::values) | |
91 return interpret_values(istate, thisarg, this); | |
92 } | |
93 #endif | |
75 | 94 |
76 if (cantInterpret || semanticRun == 3) | 95 if (cantInterpret || semanticRun == 3) |
77 return NULL; | 96 return NULL; |
78 | 97 |
79 if (!fbody) | 98 if (!fbody) |
92 | 111 |
93 Type *tb = type->toBasetype(); | 112 Type *tb = type->toBasetype(); |
94 assert(tb->ty == Tfunction); | 113 assert(tb->ty == Tfunction); |
95 TypeFunction *tf = (TypeFunction *)tb; | 114 TypeFunction *tf = (TypeFunction *)tb; |
96 Type *tret = tf->next->toBasetype(); | 115 Type *tret = tf->next->toBasetype(); |
97 if (tf->varargs) | 116 if (tf->varargs && arguments && parameters && arguments->dim != parameters->dim) |
98 { cantInterpret = 1; | 117 { cantInterpret = 1; |
99 error("Variadic functions are not yet implemented in CTFE"); | 118 error("C-style variadic functions are not yet implemented in CTFE"); |
100 return NULL; | 119 return NULL; |
101 } | 120 } |
102 | 121 |
103 // Ensure there are no lazy parameters | 122 // Ensure there are no lazy parameters |
104 if (tf->parameters) | 123 if (tf->parameters) |
1002 if (e && !e->type) | 1021 if (e && !e->type) |
1003 e->type = v->type; | 1022 e->type = v->type; |
1004 } | 1023 } |
1005 else | 1024 else |
1006 { e = v->value; | 1025 { e = v->value; |
1007 if (v->isDataseg()) | 1026 if (!v->isCTFE()) |
1008 { error(loc, "static variable %s cannot be read at compile time", v->toChars()); | 1027 { error(loc, "static variable %s cannot be read at compile time", v->toChars()); |
1009 e = EXP_CANT_INTERPRET; | 1028 e = EXP_CANT_INTERPRET; |
1010 } | 1029 } |
1011 else if (!e) | 1030 else if (!e) |
1012 error(loc, "variable %s is used before initialization", v->toChars()); | 1031 error(loc, "variable %s is used before initialization", v->toChars()); |
1134 { Expression *e = (Expression *)elements->data[i]; | 1153 { Expression *e = (Expression *)elements->data[i]; |
1135 Expression *ex; | 1154 Expression *ex; |
1136 | 1155 |
1137 ex = e->interpret(istate); | 1156 ex = e->interpret(istate); |
1138 if (ex == EXP_CANT_INTERPRET) | 1157 if (ex == EXP_CANT_INTERPRET) |
1139 { delete expsx; | 1158 goto Lerror; |
1140 return EXP_CANT_INTERPRET; | |
1141 } | |
1142 | 1159 |
1143 /* If any changes, do Copy On Write | 1160 /* If any changes, do Copy On Write |
1144 */ | 1161 */ |
1145 if (ex != e) | 1162 if (ex != e) |
1146 { | 1163 { |
1158 } | 1175 } |
1159 if (elements && expsx) | 1176 if (elements && expsx) |
1160 { | 1177 { |
1161 expandTuples(expsx); | 1178 expandTuples(expsx); |
1162 if (expsx->dim != elements->dim) | 1179 if (expsx->dim != elements->dim) |
1163 { delete expsx; | 1180 goto Lerror; |
1164 return EXP_CANT_INTERPRET; | |
1165 } | |
1166 ArrayLiteralExp *ae = new ArrayLiteralExp(loc, expsx); | 1181 ArrayLiteralExp *ae = new ArrayLiteralExp(loc, expsx); |
1167 ae->type = type; | 1182 ae->type = type; |
1168 return ae; | 1183 return ae; |
1169 } | 1184 } |
1170 return this; | 1185 return this; |
1186 | |
1187 Lerror: | |
1188 if (expsx) | |
1189 delete expsx; | |
1190 error("cannot interpret array literal"); | |
1191 return EXP_CANT_INTERPRET; | |
1171 } | 1192 } |
1172 | 1193 |
1173 Expression *AssocArrayLiteralExp::interpret(InterState *istate) | 1194 Expression *AssocArrayLiteralExp::interpret(InterState *istate) |
1174 { Expressions *keysx = keys; | 1195 { Expressions *keysx = keys; |
1175 Expressions *valuesx = values; | 1196 Expressions *valuesx = values; |
1592 if (e1->op == TOKvar) | 1613 if (e1->op == TOKvar) |
1593 { | 1614 { |
1594 VarExp *ve = (VarExp *)e1; | 1615 VarExp *ve = (VarExp *)e1; |
1595 VarDeclaration *v = ve->var->isVarDeclaration(); | 1616 VarDeclaration *v = ve->var->isVarDeclaration(); |
1596 assert(v); | 1617 assert(v); |
1597 if (v && v->isDataseg()) | 1618 if (v && !v->isCTFE()) |
1598 { // Can't modify global or static data | 1619 { // Can't modify global or static data |
1599 error("%s cannot be modified at compile time", v->toChars()); | 1620 error("%s cannot be modified at compile time", v->toChars()); |
1600 return EXP_CANT_INTERPRET; | 1621 return EXP_CANT_INTERPRET; |
1601 } | 1622 } |
1602 if (v && !v->isDataseg()) | 1623 if (v && v->isCTFE()) |
1603 { | 1624 { |
1604 Expression *ev = v->value; | 1625 Expression *ev = v->value; |
1605 if (fp && !ev) | 1626 if (fp && !ev) |
1606 { error("variable %s is used before initialization", v->toChars()); | 1627 { error("variable %s is used before initialization", v->toChars()); |
1607 return e; | 1628 return e; |
1633 * v.var = e2 | 1654 * v.var = e2 |
1634 */ | 1655 */ |
1635 else if (e1->op == TOKdotvar && aggregate->op == TOKvar) | 1656 else if (e1->op == TOKdotvar && aggregate->op == TOKvar) |
1636 { VarDeclaration *v = ((VarExp *)aggregate)->var->isVarDeclaration(); | 1657 { VarDeclaration *v = ((VarExp *)aggregate)->var->isVarDeclaration(); |
1637 | 1658 |
1638 if (v->isDataseg()) | 1659 if (!v->isCTFE()) |
1639 { // Can't modify global or static data | 1660 { // Can't modify global or static data |
1640 error("%s cannot be modified at compile time", v->toChars()); | 1661 error("%s cannot be modified at compile time", v->toChars()); |
1641 return EXP_CANT_INTERPRET; | 1662 return EXP_CANT_INTERPRET; |
1642 } else { | 1663 } else { |
1643 // Chase down rebinding of out and ref | 1664 // Chase down rebinding of out and ref |
1705 */ | 1726 */ |
1706 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) | 1727 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) |
1707 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1; | 1728 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1; |
1708 VarDeclaration *v = soe->var->isVarDeclaration(); | 1729 VarDeclaration *v = soe->var->isVarDeclaration(); |
1709 | 1730 |
1710 if (v->isDataseg()) | 1731 if (!v->isCTFE()) |
1711 { | 1732 { |
1712 error("%s cannot be modified at compile time", v->toChars()); | 1733 error("%s cannot be modified at compile time", v->toChars()); |
1713 return EXP_CANT_INTERPRET; | 1734 return EXP_CANT_INTERPRET; |
1714 } | 1735 } |
1715 if (fp && !v->value) | 1736 if (fp && !v->value) |
1751 */ | 1772 */ |
1752 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar) | 1773 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar) |
1753 { IndexExp *ie = (IndexExp *)e1; | 1774 { IndexExp *ie = (IndexExp *)e1; |
1754 VarExp *ve = (VarExp *)ie->e1; | 1775 VarExp *ve = (VarExp *)ie->e1; |
1755 VarDeclaration *v = ve->var->isVarDeclaration(); | 1776 VarDeclaration *v = ve->var->isVarDeclaration(); |
1756 if (!v || v->isDataseg()) | 1777 if (!v || !v->isCTFE()) |
1757 { | 1778 { |
1758 error("%s cannot be modified at compile time", v ? v->toChars(): "void"); | 1779 error("%s cannot be modified at compile time", v ? v->toChars(): "void"); |
1759 return EXP_CANT_INTERPRET; | 1780 return EXP_CANT_INTERPRET; |
1760 } | 1781 } |
1761 if (v->value && v->value->op == TOKvar) | 1782 if (v->value && v->value->op == TOKvar) |
1914 ((IndexExp *)aggregate)->e1->op == TOKvar) | 1935 ((IndexExp *)aggregate)->e1->op == TOKvar) |
1915 { | 1936 { |
1916 IndexExp * ie = (IndexExp *)aggregate; | 1937 IndexExp * ie = (IndexExp *)aggregate; |
1917 VarExp *ve = (VarExp *)(ie->e1); | 1938 VarExp *ve = (VarExp *)(ie->e1); |
1918 VarDeclaration *v = ve->var->isVarDeclaration(); | 1939 VarDeclaration *v = ve->var->isVarDeclaration(); |
1919 if (!v || v->isDataseg()) | 1940 if (!v || !v->isCTFE()) |
1920 { | 1941 { |
1921 error("%s cannot be modified at compile time", v ? v->toChars(): "void"); | 1942 error("%s cannot be modified at compile time", v ? v->toChars(): "void"); |
1922 return EXP_CANT_INTERPRET; | 1943 return EXP_CANT_INTERPRET; |
1923 } | 1944 } |
1924 Type *t = ve->type->toBasetype(); | 1945 Type *t = ve->type->toBasetype(); |
2006 else if (e1->op == TOKslice && ((SliceExp *)e1)->e1->op==TOKvar) | 2027 else if (e1->op == TOKslice && ((SliceExp *)e1)->e1->op==TOKvar) |
2007 { | 2028 { |
2008 SliceExp * sexp = (SliceExp *)e1; | 2029 SliceExp * sexp = (SliceExp *)e1; |
2009 VarExp *ve = (VarExp *)(sexp->e1); | 2030 VarExp *ve = (VarExp *)(sexp->e1); |
2010 VarDeclaration *v = ve->var->isVarDeclaration(); | 2031 VarDeclaration *v = ve->var->isVarDeclaration(); |
2011 if (!v || v->isDataseg()) | 2032 if (!v || !v->isCTFE()) |
2012 { | 2033 { |
2013 error("%s cannot be modified at compile time", v->toChars()); | 2034 error("%s cannot be modified at compile time", v->toChars()); |
2014 return EXP_CANT_INTERPRET; | 2035 return EXP_CANT_INTERPRET; |
2015 } | 2036 } |
2016 // Chase down rebinding of out and ref | 2037 // Chase down rebinding of out and ref |
2634 return e; | 2655 return e; |
2635 } | 2656 } |
2636 | 2657 |
2637 /******************************* Special Functions ***************************/ | 2658 /******************************* Special Functions ***************************/ |
2638 | 2659 |
2660 #if DMDV1 | |
2661 | |
2639 Expression *interpret_aaLen(InterState *istate, Expressions *arguments) | 2662 Expression *interpret_aaLen(InterState *istate, Expressions *arguments) |
2640 { | 2663 { |
2641 if (!arguments || arguments->dim != 1) | 2664 if (!arguments || arguments->dim != 1) |
2642 return NULL; | 2665 return NULL; |
2643 Expression *earg = (Expression *)arguments->data[0]; | 2666 Expression *earg = (Expression *)arguments->data[0]; |
2688 e->type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments->dim : 0)); | 2711 e->type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments->dim : 0)); |
2689 //printf("result is %s\n", e->toChars()); | 2712 //printf("result is %s\n", e->toChars()); |
2690 return e; | 2713 return e; |
2691 } | 2714 } |
2692 | 2715 |
2716 #endif | |
2717 | |
2718 #if DMDV2 | |
2719 | |
2720 Expression *interpret_length(InterState *istate, Expression *earg) | |
2721 { | |
2722 //printf("interpret_length()\n"); | |
2723 earg = earg->interpret(istate); | |
2724 if (earg == EXP_CANT_INTERPRET) | |
2725 return NULL; | |
2726 if (earg->op != TOKassocarrayliteral) | |
2727 return NULL; | |
2728 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; | |
2729 Expression *e = new IntegerExp(aae->loc, aae->keys->dim, Type::tsize_t); | |
2730 return e; | |
2731 } | |
2732 | |
2733 Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd) | |
2734 { | |
2735 #if LOG | |
2736 printf("interpret_keys()\n"); | |
2737 #endif | |
2738 earg = earg->interpret(istate); | |
2739 if (earg == EXP_CANT_INTERPRET) | |
2740 return NULL; | |
2741 if (earg->op != TOKassocarrayliteral) | |
2742 return NULL; | |
2743 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; | |
2744 Expression *e = new ArrayLiteralExp(aae->loc, aae->keys); | |
2745 assert(fd->type->ty == Tfunction); | |
2746 assert(fd->type->nextOf()->ty == Tarray); | |
2747 Type *elemType = ((TypeFunction *)fd->type)->nextOf()->nextOf(); | |
2748 e->type = new TypeSArray(elemType, new IntegerExp(aae->keys->dim)); | |
2749 return e; | |
2750 } | |
2751 | |
2752 Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd) | |
2753 { | |
2754 //printf("interpret_values()\n"); | |
2755 earg = earg->interpret(istate); | |
2756 if (earg == EXP_CANT_INTERPRET) | |
2757 return NULL; | |
2758 if (earg->op != TOKassocarrayliteral) | |
2759 return NULL; | |
2760 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; | |
2761 Expression *e = new ArrayLiteralExp(aae->loc, aae->values); | |
2762 assert(fd->type->ty == Tfunction); | |
2763 assert(fd->type->nextOf()->ty == Tarray); | |
2764 Type *elemType = ((TypeFunction *)fd->type)->nextOf()->nextOf(); | |
2765 e->type = new TypeSArray(elemType, new IntegerExp(aae->values->dim)); | |
2766 //printf("result is %s\n", e->toChars()); | |
2767 return e; | |
2768 } | |
2769 | |
2770 #endif | |
2771 |