import inspect
import itertools

from cached_property import cached_property


class Variable:
    """
    Base class for all variables.

    """
    def __init__(self):
        pass

    @cached_property
    def _bsca(self):
        frame = inspect.currentframe().f_back.f_back
        return frame.f_locals.get('self', '')

    @cached_property
    def var_name(self):
        frame = inspect.currentframe().f_back.f_back
        all_vars = itertools.chain(frame.f_globals.items(),
                                   frame.f_locals.items())
        for k, var in all_vars:
            if isinstance(var, self.__class__):
                if hash(self) == hash(var):
                    return k
        return ''


class IntegerVariable(Variable):
    pass


class DeferredExpression:

    def __init__(self, code):
        self.code = code

@@ -156,24 +156,34 @@
 _init__(self
+, val=None
 ):%0A        p
@@ -185,26 +185,126 @@
     
-pass%0A%0A    @cached_
+self._declared = False%0A        if val is not None:%0A            self.__set__(self, DeferredExpression(str(val)))%0A%0A    @
 prop
@@ -321,12 +321,20 @@
 ef _
-bsca
+holder_frame
 (sel
@@ -381,32 +381,39 @@
 ().f_back.f_back
+.f_back
 %0A        return 
@@ -405,23 +405,33 @@
         
-return 
+while isinstance(
 frame.f_
@@ -452,16 +452,82 @@
 lf', '')
+, Variable):%0A            frame = frame.f_back%0A        return frame
 %0A%0A    @c
@@ -553,16 +553,13 @@
 def 
-var_name
+_bsca
 (sel
@@ -574,52 +574,104 @@
     
-frame = inspect.current
+return self._holder_
 frame
-()
 .f_
-back.f_back
+locals.get('self', '')%0A%0A    @cached_property%0A    def var_name(self):
 %0A   
@@ -702,16 +702,29 @@
 s.chain(
+self._holder_
 frame.f_
@@ -771,24 +771,37 @@
             
+self._holder_
 frame.f_loca
@@ -984,16 +984,493 @@
 urn ''%0A%0A
+    def _declare_once(self):%0A        if not self._declared:%0A            code = %22%25s %25s;%5Cn%22 %25 (self.var_type, self.var_name)%0A            self._bsca._func_body += code%0A            self._declared = True%0A%0A    def __get__(self, obj, objtype):%0A        self._declare_once()%0A        return DeferredExpression(self.var_name)%0A%0A    def __set__(self, obj, value):%0A        self._declare_once()%0A        code = %22%25s = %25s;%5Cn%22 %25 (self.var_name, value.code)%0A        self._bsca._func_body += code%0A%0A
 %0Aclass I
@@ -1503,12 +1503,33 @@
     
-pass
+var_type = %22unsigned int%22
 %0A%0A%0Ac

Declare variable on first use (#20)