summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-10-24 00:56:47 +0200
committerAraq <rumpf_a@web.de>2011-10-24 00:56:47 +0200
commit9fb97e24bf05fa980bcc781dd4b32fd3efed48a0 (patch)
tree19739c18f3085766e4c5afab56b1b56b8c9bf574
parenta702524ae456d8272480d460a3c42705be91ea24 (diff)
downloadNim-9fb97e24bf05fa980bcc781dd4b32fd3efed48a0.tar.gz
compilation cache: multi methods now work
-rwxr-xr-xcompiler/ast.nim29
-rwxr-xr-xcompiler/cgmeth.nim22
-rwxr-xr-xcompiler/main.nim1
-rwxr-xr-xcompiler/rodwrite.nim5
-rwxr-xr-xtodo.txt10
5 files changed, 41 insertions, 26 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 01b70980d..9b2f210a3 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -13,9 +13,9 @@ import
   msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists, 
   intsets, idgen
 
-const 
-  ImportTablePos* = 0
-  ModuleTablePos* = 1
+const
+  ImportTablePos* = 0         # imported symbols are at level 0
+  ModuleTablePos* = 1         # module's top level symbols are at level 1
 
 type 
   TCallingConvention* = enum 
@@ -173,20 +173,20 @@ type
     nkStmtListType,       # a statement list ending in a type; for macros
     nkBlockType,          # a statement block ending in a type; for macros
                           # types as syntactic trees:
-    nkTypeOfExpr,
-    nkObjectTy,
-    nkTupleTy,
+    nkTypeOfExpr,         # type(1+2)
+    nkObjectTy,           # object body
+    nkTupleTy,            # tuple body
     nkRecList,            # list of object parts
     nkRecCase,            # case section of object
     nkRecWhen,            # when section of object
-    nkRefTy,
-    nkPtrTy,
-    nkVarTy,
+    nkRefTy,              # ``ref T``
+    nkPtrTy,              # ``ptr T``
+    nkVarTy,              # ``var T``
     nkConstTy,            # ``const T``
     nkMutableTy,          # ``mutable T``
     nkDistinctTy,         # distinct type
-    nkProcTy,
-    nkEnumTy,
+    nkProcTy,             # proc type
+    nkEnumTy,             # enum body
     nkEnumFieldDef,       # `ident = expr` in an enumeration
     nkReturnToken         # token used for interpretation
   TNodeKinds* = set[TNodeKind]
@@ -235,7 +235,8 @@ type
   TSymFlags* = set[TSymFlag]
 
 const
-  sfFakeConst* = sfDeadCodeElim # const cannot be put into a data section
+  sfFakeConst* = sfDeadCodeElim  # const cannot be put into a data section
+  sfDispatcher* = sfDeadCodeElim # copied method symbol is the dispatcher 
 
 type
   TTypeKind* = enum  # order is important!
@@ -246,7 +247,7 @@ type
     tyGenericInvokation, # ``T[a, b]`` for types to invoke
     tyGenericBody,       # ``T[a, b, body]`` last parameter is the body
     tyGenericInst,       # ``T[a, b, realInstance]`` instantiated generic type
-    tyGenericParam,      # ``a`` in the example
+    tyGenericParam,      # ``a`` in the above patterns
     tyDistinct,
     tyEnum,
     tyOrdinal,           # misnamed: should become 'tyConstraint'
@@ -575,7 +576,7 @@ const
   pragmasPos* = 3
   codePos* = 4
   resultPos* = 5
-  dispatcherPos* = 6
+  dispatcherPos* = 6 # caution: if method has no 'result' it can be position 5!
 
 # creator procs:
 proc NewSym*(symKind: TSymKind, Name: PIdent, owner: PSym): PSym
diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim
index 3c90f3343..e2c3c009c 100755
--- a/compiler/cgmeth.nim
+++ b/compiler/cgmeth.nim
@@ -34,9 +34,11 @@ proc genConv(n: PNode, d: PType, downcast: bool): PNode =
   
 proc methodCall*(n: PNode): PNode = 
   result = n
+  # replace ordinary method by dispatcher method: 
   var disp = lastSon(result.sons[0].sym.ast).sym
   result.sons[0].sym = disp
-  for i in countup(1, sonsLen(result) - 1): 
+  # change the arguments to up/downcasts to fit the dispatcher's parameters:
+  for i in countup(1, sonsLen(result)-1):
     result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true)
 
 # save for incremental compilation:
@@ -67,24 +69,36 @@ proc sameMethodBucket(a, b: PSym): bool =
       return 
   result = true
 
+proc attachDispatcher(s: PSym, dispatcher: PNode) =
+  var L = s.ast.len-1
+  var x = s.ast.sons[L]
+  if x.kind == nkSym and sfDispatcher in x.sym.flags:
+    # we've added a dispatcher already, so overwrite it
+    s.ast.sons[L] = dispatcher
+  else:
+    s.ast.add(dispatcher)
+
 proc methodDef*(s: PSym, fromCache: bool) =
   var L = len(gMethods)
   for i in countup(0, L - 1): 
     if sameMethodBucket(gMethods[i][0], s): 
-      add(gMethods[i], s)     # store a symbol to the dispatcher:
-      addSon(s.ast, lastSon(gMethods[i][0].ast))
+      add(gMethods[i], s)
+      attachDispatcher(s, lastSon(gMethods[i][0].ast))
       return 
   add(gMethods, @[s])
   # create a new dispatcher:
   if not fromCache:
     var disp = copySym(s)
+    incl(disp.flags, sfDispatcher)
+    excl(disp.flags, sfExported)
     disp.typ = copyType(disp.typ, disp.typ.owner, false)
+    # we can't inline the dispatcher itself (for now):
     if disp.typ.callConv == ccInline: disp.typ.callConv = ccDefault
     disp.ast = copyTree(s.ast)
     disp.ast.sons[codePos] = ast.emptyNode
     if s.typ.sons[0] != nil: 
       disp.ast.sons[resultPos].sym = copySym(s.ast.sons[resultPos].sym)
-    addSon(s.ast, newSymNode(disp))
+    attachDispatcher(s, newSymNode(disp))
 
 proc relevantCol(methods: TSymSeq, col: int): bool = 
   # returns true iff the position is relevant
diff --git a/compiler/main.nim b/compiler/main.nim
index f8c6860fd..7a0d016ce 100755
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -103,6 +103,7 @@ proc CommandGenDepend(filename: string) =
 proc CommandCheck(filename: string) = 
   msgs.gErrorMax = high(int)  # do not stop after first error
   semanticPasses()            # use an empty backend for semantic checking only
+  registerPass(rodwrite.rodwritePass())
   compileProject(filename)
 
 proc CommandCompileToC(filename: string) = 
diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim
index 0aa7b3b57..626d0382c 100755
--- a/compiler/rodwrite.nim
+++ b/compiler/rodwrite.nim
@@ -322,7 +322,7 @@ proc addToIndex(w: var TIndex, key, val: int) =
   w.lastIdxVal = val
   IiTablePut(w.tab, key, val)
 
-var debugWritten: TIntSet
+#var debugWritten = initIntSet()
 
 proc symStack(w: PRodWriter) =
   var i = 0
@@ -351,7 +351,7 @@ proc symStack(w: PRodWriter) =
         if s.kind == skConverter: 
           if w.converters.len != 0: add(w.converters, ' ')
           encodeVInt(s.id, w.converters)
-        elif s.kind == skMethod:
+        elif s.kind == skMethod and sfDispatcher notin s.flags:
           if w.methods.len != 0: add(w.methods, ' ')
           encodeVInt(s.id, w.methods)
       elif IiTableGet(w.imports.tab, s.id) == invalidKey: 
@@ -569,4 +569,3 @@ proc rodwritePass(): TPass =
     result.close = myClose
     result.process = process
 
-debugWritten = initIntSet()
diff --git a/todo.txt b/todo.txt
index 05f6c2f1f..e7959a930 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,16 +1,16 @@
 Version 0.8.14
 ==============
 
-- optimize unused constants away (affected by HLO)
+- optimize unused constants away (affected by HLO); get rid of nfAllConst
 - 'let x = y'
 - fix actors.nim
 - make threadvar efficient again on linux after testing
-- test the sort implementation again
 - document & test splicing; don't forget to test negative indexes
 - implement lib/pure/memfiles properly
 - eval context is per module; this way modularity is kept; global id generation
   macro can still be done once macros support basic IO (store current id in
   some file)
+- methods for JS backend (very easy to do!)
 
 
 incremental compilation
@@ -18,7 +18,6 @@ incremental compilation
 
 - adapt thread var implementation to care about the new merge operation
 - write test cases: needs test script support
-  - fix method generation
   - test thread var
   - test DLL interfacing!
   - stress test with whole compiler
@@ -26,13 +25,14 @@ incremental compilation
 - automate tests:
   - test basic recompilation scheme
   - test type converters
-  - test G, A, B example from the documentation
-  - test init sections
+  - test G, A, B example from the documentation; test init sections
+  - test method generation
 
 
 version 0.9.0
 =============
 
+- test the sort implementation again
 - const ptr/ref
 - unsigned ints and bignums
 - implement the high level optimizer
49'>549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925